获取NX装配结构信息

最近在做一个项目,需要获取NX装配结构信息,这里把代码分享给大家,希望对各位有帮助,注意以下几点:

1)代码获取了PART的属性、表达式等,因此一些细节可能需要您根据实际情况修改。

2)读写XML用的pugixml,需要您包含到工程中,接口使用的是宽字符模式,所以在pugiconfig.hpp需要打开宽字符开关。

 题外话,本人用过的解析XML的库有微软MSXML、markup、tinyxml、pugixml等,其中pugixml是最好用的,强烈推荐给大家,下载地址:pugixml

3)代码功能是传入一个装配part,生成一个包含装配信息的xml。

4)代码采用ug open c实现,如果您需要在C#、Java等其他工程中调用,可将其包装成独立的exe,采用后台方式调用。

5)如果您不需要生成XML,可不生成,直接使用其内存对象即可。

6)该代码只是抛砖引玉,仅供参考。

VS后台传参如下:

由于装配结构嵌套可能非常多,生成的xml结构大致如下:

代码如下:

  1 // GenarateAssemblyInfo.cpp : 定义控制台应用程序的入口点。
  2 //
  3 
  4 #include "stdafx.h"
  5 #include "pugiconfig.hpp"
  6 #include "pugixml.hpp"
  7 #include <windows.h>
  8 #include <stdlib.h>
  9 #include <uf_attr.h>
 10 #include <uf_modl.h>
 11 #include <uf.h>
 12 #include <uf_part.h>
 13 #include <uf_assem.h>
 14 #include <uf_ui_ugopen.h>
 15 #include <map>
 16 #include <vector>
 17 #include <NXSigningResource.cpp>
 18 using namespace std;
 19 
 20 #ifndef SAFE_DELETE 
 21 #define SAFE_DELETE(p) do{ if(p){delete(p);(p)=NULL;} }while(0)
 22 #endif
 23 typedef    struct _tagAssemblyInfo
 24 {
 25     _tagAssemblyInfo()
 26     {
 27         
 28     }
 29 
 30     virtual ~_tagAssemblyInfo()
 31     {
 32         for (vector<_tagAssemblyInfo*>::iterator iter = children.begin(); iter != children.end(); ++iter)
 33         {
 34             SAFE_DELETE (*iter);
 35         }
 36     }
 37 
 38     string path;//原型路径
 39     map<string,map<string, string>> attr;  //组,键值对
 40     vector<_tagAssemblyInfo*> children;//子件
 41 }AssemblyInfo;
 42 
 43 
 44 string TCHAR2char( const TCHAR* STR)
 45 {
 46     string strchar;
 47     if (!*STR)
 48     {
 49         return strchar;
 50     }
 51     
 52     //返回字符串的长度
 53     int size = WideCharToMultiByte(CP_ACP, 0, STR, -1, NULL, 0, NULL, FALSE);
 54 
 55     //申请一个多字节的字符串变量
 56     char* str = new char[sizeof(char) * size];
 57 
 58     //将STR转成str
 59     WideCharToMultiByte(CP_ACP, 0, STR, -1, str, size, NULL, FALSE);
 60     strchar = str;
 61     delete (str);
 62 
 63     return strchar;
 64 }
 65 
 66 TCHAR* char2TCAHR(const char* str)
 67 {
 68     int size = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
 69 
 70     TCHAR* retStr = new TCHAR[size * sizeof(TCHAR)];
 71 
 72     MultiByteToWideChar(CP_ACP, 0, str, -1, retStr, size);
 73 
 74     return retStr;
 75 }
 76 
 77 void ReadExpression(AssemblyInfo* info,tag_t obj)
 78 {
 79     if ((NULL == info) || (NULL_TAG == obj))
 80     {
 81         return ;
 82     }
 83     
 84     int number_of_exps = 0;
 85     tag_t *exps = NULL;
 86     UF_MODL_ask_exps_of_part(obj,&number_of_exps,&exps);
 87     char *name = "Exp";
 88     for (int i = 0; i < number_of_exps; ++i)
 89     {
 90         tag_t expTag = *(exps + i);
 91         char* expStr = NULL;
 92         UF_MODL_ask_exp_tag_string(expTag, &expStr);
 93         char* leftStr = NULL;
 94         char* rightStr = NULL;
 95         UF_MODL_dissect_exp_string(expStr, &leftStr, &rightStr,&expTag );
 96         info->attr[name].insert(make_pair(leftStr,rightStr));
 97         UF_free(expStr);
 98         UF_free(leftStr);
 99         UF_free(rightStr);
100     }
101 
102     UF_free(exps);
103 }
104 
105 
106 void ReadAttribute(AssemblyInfo* info,tag_t obj)
107 {
108     if ((NULL == info) || (NULL_TAG == obj))
109     {
110         return ;
111     }
112     
113     char* category[] = {"ParameterExpression","ParameterMapping", "FxPartThumbnail"}; //组名称
114 
115     for (int i = 0; i < _countof(category); ++i)
116     {
117         int num_attributes = 0;
118         logical has_attribute = false;
119         
120         UF_ATTR_info_t attr_info = {0};
121         UF_ATTR_init_user_attribute_info(&attr_info);
122 
123         UF_ATTR_iterator_t query;
124         UF_ATTR_init_user_attribute_iterator(&query);
125         query.category = category[i];
126         query.check_category = true;
127         query.type = UF_ATTR_string;
128         
129         UF_ATTR_get_user_attribute(obj,&query,&attr_info,&has_attribute);
130         while (has_attribute)
131         {
132             info->attr[query.category].insert(make_pair(attr_info.title,attr_info.string_value));
133             UF_ATTR_free_user_attribute_info_strings(&attr_info);
134             UF_ATTR_get_next_user_attribute(obj,&query,&attr_info,&has_attribute);
135         }
136     }
137 }
138 
139 void GetAssembly(AssemblyInfo* info,tag_t occ)
140 {
141     if ((NULL == info) || (NULL_TAG == occ))
142     {
143         return ;
144     }
145     tag_t prototype = UF_ASSEM_ask_prototype_of_occ(occ);
146     UF_PART_set_display_part(prototype);
147 
148     //根据obj获取路径及属性
149     char part_fspec [MAX_FSPEC_SIZE+1] = {0};
150     UF_PART_ask_part_name(prototype,part_fspec);
151     info->path = part_fspec;
152 
153     //根据obj获取属性
154     ReadAttribute(info, prototype);
155 
156     //根据obj获取表达式
157     ReadExpression(info, prototype);
158 
159     //遍历子节点
160     tag_t *child_part_occs = NULL;
161 
162     int number = UF_ASSEM_ask_part_occ_children(occ, &child_part_occs);
163     for (int i = 0; i < number; ++i)
164     {
165         AssemblyInfo* childInfo = new AssemblyInfo();
166         info->children.push_back(childInfo);
167         GetAssembly(childInfo, *(child_part_occs + i));
168     }
169 
170     UF_free(child_part_occs);
171 }
172 
173 void WriteNode(AssemblyInfo* info, pugi::xml_node parent)
174 {
175     if ((NULL == info) || (NULL == parent))
176     {
177         return ;
178     }
179     _TCHAR* tmpStr = NULL;
180     pugi::xml_node assembly = parent.append_child(_T("assembly"));
181     tmpStr = char2TCAHR(info->path.c_str());
182     assembly.append_attribute(_T("name")).set_value(tmpStr);
183     SAFE_DELETE(tmpStr);
184     pugi::xml_node attrs = assembly.append_child(_T("attrs"));
185 
186     //属性
187     for (map<string,map<string, string>>::iterator iter = info->attr.begin(); iter != info->attr.end(); ++iter)
188     {
189         pugi::xml_node category = attrs.append_child(_T("category"));
190         tmpStr = char2TCAHR(iter->first.c_str());
191         category.append_attribute(_T("name")).set_value(tmpStr);
192         SAFE_DELETE(tmpStr);
193         map<string, string>& attrsMap = iter->second;
194         for (map<string, string>::iterator iterAttr = attrsMap.begin(); iterAttr != attrsMap.end(); ++iterAttr)
195         {
196             pugi::xml_node attr = category.append_child(_T("attr"));
197             tmpStr = char2TCAHR(iterAttr->first.c_str());
198             attr.append_attribute(_T("name")).set_value(tmpStr);
199             SAFE_DELETE(tmpStr);
200             tmpStr = char2TCAHR(iterAttr->second.c_str());
201             attr.append_attribute(_T("value")).set_value(tmpStr);
202             SAFE_DELETE(tmpStr);
203         }
204     }
205 
206     //子节点
207     pugi::xml_node children = assembly.append_child(_T("children"));
208     for (int i = 0; i < info->children.size(); ++i)
209     {
210         WriteNode(info->children[i], children);
211     }
212 }
213 
214 void WriteXml(AssemblyInfo* info,_TCHAR* xmlFile)
215 {
216     if ((NULL == info) || (NULL == xmlFile))
217     {
218         return ;
219     }
220 
221     pugi::xml_document doc;
222     pugi::xml_node decNode = doc.append_child(pugi::node_declaration);
223     pugi::xml_attribute vAttr = decNode.append_attribute(_T("version"));
224     vAttr.set_value(_T("1.0"));
225     pugi::xml_attribute encAttr = decNode.append_attribute(_T("encoding"));
226     encAttr.set_value(_T("utf-8"));
227 
228     pugi::xml_node root = doc.append_child(_T("root"));
229     WriteNode(info,root);
230 
231     doc.save_file(xmlFile, _T("	"), pugi::format_indent, pugi::encoding_utf8);
232 }
233 
234 int _tmain(int argc, _TCHAR* argv[])
235 {
236     if (argc < 3)
237     {
238         return 0;
239     }
240 
241     if (UF_initialize() != 0) 
242     {
243         return 0; 
244     }
245 
246     const _TCHAR* prtPath  = argv[1];
247     TCHAR* xmlFile = argv[2];    
248     tag_t tag = NULL_TAG;
249     UF_PART_load_status_t status;
250     UF_PART_open(TCHAR2char(prtPath).c_str(),&tag,&status);
251     if (status.failed)
252     {
253         return 0;
254     }
255 
256     tag_t occ = UF_ASSEM_ask_root_part_occ(tag);
257     AssemblyInfo* info = new AssemblyInfo();
258     if (NULL == info)
259     {
260         return 0;
261     }
262 
263     GetAssembly(info, occ);
264     WriteXml(info,xmlFile);
265 
266     UF_terminate();
267     delete info;
268     return 0;
269 }
作者:快雪
本文版权归作者所有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/kuaixue/p/12728151.html