• 获取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 }
    作者:快雪
    本文版权归作者所有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    iOS-夜间模式(换肤设置)
    iOS-自定义起始时间选择器视图
    [SpriteKit] 系统框架中Cocos2d-x制作小游戏ZombieConga
    [SceneKit] 不会 Unity3D 的另一种选择
    Android WiFi开发
    Java 工具类 —— 定时器(Timer/TimerTask)
    java 语法 —— 数组
    IDEA 的使用(快捷键、括号对齐的方式)
    cmd 高级用法
    MySQL 基本信息的查询(初始化配置信息 my.ini)
  • 原文地址:https://www.cnblogs.com/kuaixue/p/12728151.html
Copyright © 2020-2023  润新知