楊 平 黃 ?。ㄖ袊?guó)電子科技集團(tuán)第三十研究所,四川,成都,610041)
?
基于DWG DirectX的電子產(chǎn)品圖樣結(jié)構(gòu)關(guān)系輕量化構(gòu)建方法研究
楊平 黃巍
(中國(guó)電子科技集團(tuán)第三十研究所,四川,成都,610041)
摘要:為便于樣機(jī)研發(fā)階段顯示產(chǎn)品圖樣結(jié)構(gòu)關(guān)系,準(zhǔn)確統(tǒng)計(jì)產(chǎn)品零部件信息,提高對(duì)圖樣裝配欄與明細(xì)欄信息的審核效率,利用VC 2008平臺(tái)與DWGdirectX開發(fā)工具實(shí)現(xiàn)了在非AutoCAD環(huán)境下的圖樣信息提取。利用嵌套循環(huán)比對(duì)算法深度遍歷圖樣信息集合,并構(gòu)建圖樣之間的裝配映射關(guān)系。利用MFC控件直觀顯示圖樣結(jié)構(gòu)關(guān)系與BOM表信息,自動(dòng)統(tǒng)計(jì)與核對(duì)產(chǎn)品零部件數(shù)量,實(shí)現(xiàn)缺漏圖樣提醒。在檢入PDM系統(tǒng)前,有效降低了圖樣BOM信息的錯(cuò)誤發(fā)生率,并最終生成符合企業(yè)標(biāo)準(zhǔn)的產(chǎn)品清單。
關(guān)鍵詞:圖樣結(jié)構(gòu)樹 DWGdirectX動(dòng)態(tài)鏈接庫 信息提取 遞歸算法
電子產(chǎn)品的圖檔文件依據(jù)構(gòu)成要素可分為結(jié)構(gòu)零部件圖表、印制板板卡圖表和機(jī)內(nèi)外通信互聯(lián)線纜圖表等,其圖樣關(guān)系構(gòu)成較為復(fù)雜,如大型網(wǎng)絡(luò)交換機(jī)與新型互聯(lián)網(wǎng)控制器等。其設(shè)備表現(xiàn)出功能更加密集化、融合度更高的特點(diǎn)[1],同時(shí)對(duì)處于樣機(jī)研制階段中圖樣模型的完整性與正確性提出了更高的要求。要滿足產(chǎn)品完整性與正確性,就需要構(gòu)建清晰的產(chǎn)品結(jié)構(gòu)樹關(guān)系。目前商用產(chǎn)品數(shù)據(jù)管理系統(tǒng)(PDM)采用自頂向下方式構(gòu)建產(chǎn)品結(jié)構(gòu)樹關(guān)系,而在產(chǎn)品樣機(jī)研制階段往往缺乏設(shè)備頂層裝配圖表,因此商用PDM系統(tǒng)很難全面、清晰地反映出樣機(jī)階段產(chǎn)品的結(jié)構(gòu)樹關(guān)系。
電子通信產(chǎn)品的BOM信息是產(chǎn)品的核心組織,其中的產(chǎn)品結(jié)構(gòu)樹與零部件數(shù)量信息是檢驗(yàn)產(chǎn)品完整性的重要信息。這些信息來源于產(chǎn)品的每一張?jiān)O(shè)計(jì)圖樣。如何高效的讀取產(chǎn)品BOM信息,檢驗(yàn)產(chǎn)品零部件圖樣的正確性與齊套性,不僅是設(shè)計(jì)者同時(shí)也是產(chǎn)品信息管理者所關(guān)心的問題。目前Autodesk公司的DWG格式文件是國(guó)內(nèi)外應(yīng)用最為廣泛的產(chǎn)品設(shè)計(jì)信息存儲(chǔ)文件[2]。批量讀取DWG格式圖樣信息方法較為多樣,例如,仇巍基于ObjectARX利用單元化信息匹配的方式提取圖樣信息[3],董玉德等利用明細(xì)表坐標(biāo)比對(duì)方式識(shí)別圖樣明細(xì)欄信息并提取[4],此兩種方法都無法完全擺脫AutoCAD環(huán)境,因此存在耗用計(jì)算機(jī)資源較多,提取速度慢的問題。黃維豐和李橋梁等利用ODT技術(shù)實(shí)現(xiàn)了對(duì)DWG格式圖樣直接讀?。?],但只能提取2004版本之前的圖樣文件。本文基于Open Design Alliance開發(fā)的DWGDirectX的ActiveX控件[6],脫離AutoCAD環(huán)境,直接讀取DWG文件,提取所需圖樣BOM信息,采用自底向上的方式構(gòu)建圖樣結(jié)構(gòu)樹與零部件統(tǒng)計(jì)信息,實(shí)現(xiàn)對(duì)圖樣BOM信息的集中統(tǒng)計(jì)、檢查、核對(duì)與缺漏提醒。
1.1 DWG圖樣格式分析
DWG文件主要由表段(TABLE)、實(shí)體段(ENTITY)、塊段(BLOCK)和文件頭(HEADER)等組合而成,文件以二進(jìn)制方式書寫,用于存儲(chǔ)AutoCAD圖形文件。
其中DWG文件的版本號(hào)與各段中的起始地址、圖形因子以及DWG整參數(shù)等記錄于DWG的頭文件中。因AutoCAD版本的差異,帶來DWG文件會(huì)有些許細(xì)微差別。
圖塊由多個(gè)不同類型的實(shí)體組成,同時(shí)每個(gè)圖塊對(duì)應(yīng)屬于自己的索引用于區(qū)別不同的圖塊,這些索引組成了包含塊名、塊長(zhǎng)度、標(biāo)志字和結(jié)束標(biāo)志的塊表。
實(shí)體段用于記錄AutoCAD中稱之為實(shí)體的圖元數(shù)據(jù)。這些圖元是指直線、點(diǎn)、圓、弧、文字、多義線、軌跡線和插入塊等。塊段用于記錄組成DWG文件每個(gè)塊的顏色、線型和插入基點(diǎn)等實(shí)體信息。由每個(gè)塊所對(duì)應(yīng)的實(shí)體表組成。表段在DWG文件中存儲(chǔ)在實(shí)體段之后,實(shí)際上它是由塊表、層表、字型表、線型表、視圖表順序組成的。層表由描述每個(gè)圖層的表記錄依次組成,表記錄包括以下內(nèi)容:層狀態(tài)標(biāo)志、層名、層顏色、層線型。
文件中一些重要索引信息的副本被存放于應(yīng)急頭部之中。
1.2 基于DWGDirectX讀取原理
DWGDirectX通過API函數(shù)提供對(duì)DWG或DXF文件的內(nèi)容的讀寫通道。DWGDirectX提供的接口中含有許多類型的對(duì)象,這些對(duì)象是以一種層次化的方式來組織的。DWGDirectX描述的DWG文件對(duì)象模型結(jié)構(gòu)圖如圖1所示。
圖1 DWG文件結(jié)構(gòu)圖
讀取圖樣的核心機(jī)制在于將Autodesk公司加密的二進(jìn)制圖樣文件轉(zhuǎn)化為數(shù)據(jù)自定義的模型文件,DWGDirectX組織數(shù)據(jù)的方式與ObjectARX非常相似,包括線型(LineType)、形文件(shapeFile)、圖塊(Bloek)、圖層(Layer)、視口(ViewPort)、標(biāo)注樣式(Dimstyle)、視圖(View)、注冊(cè)應(yīng)用程序(RegApp)和用戶坐標(biāo)系(ues)等9個(gè)容器表,以及Modelspace(模型空間)和PaperSPace(圖樣空間)兩種基本類型的塊表。
OdaHostApp類表示整個(gè)應(yīng)用程序,OdaHostApp的對(duì)象中定義了相關(guān)面向?qū)ο蟮慕涌?,用于處理?yīng)用程序。利用其Application屬性來操作主應(yīng)用程序。AcadApplication類的對(duì)象負(fù)責(zé)控制整個(gè)應(yīng)用程序的各個(gè)屬性和應(yīng)用程序?qū)用娴姆椒āK袘?yīng)用程序?qū)用娴囊恍┕ぷ鞫际怯伤瓿傻?,而且各個(gè)其他對(duì)象也是通過AcadApplication來與操作系統(tǒng)等外界的環(huán)境進(jìn)行交互。但AcadApplication類的對(duì)象只能通過OdaHostApp對(duì)象的Application屬性獲得。
AcadDocument對(duì)象的Documents屬性返回一個(gè)AcadDocument對(duì)象集合,其中每個(gè)AcadDocument對(duì)象都代表一張圖樣。每張圖樣都有自己對(duì)應(yīng)的模型空間,所以對(duì)應(yīng)在內(nèi)存中就會(huì)有一個(gè)AcadModelSpace集合。在DWG格式的圖樣文件中的點(diǎn)、線、文字、圓和圓弧等元素,都是以對(duì)應(yīng)的實(shí)體形式存儲(chǔ)在模型空間或圖樣空間中。每個(gè)實(shí)體都有一個(gè)索引,在模型空間中通過該索引我們可以找到該實(shí)體。
因工程圖樣格式相對(duì)固定,因此可利用圖樣中的“塊”特性,預(yù)先定制不同圖幅中標(biāo)題欄與明細(xì)欄的屬性名稱與屬性值。在圖樣提取過程中,重點(diǎn)對(duì)圖樣中的“塊”屬性值進(jìn)行比對(duì)與提取,從而實(shí)現(xiàn)對(duì)圖樣標(biāo)題欄與明細(xì)欄信息提取。
1.3 提取過程與實(shí)現(xiàn)代碼
在進(jìn)行軟件開發(fā)之前需要先引入動(dòng)態(tài)鏈接庫的接口文件,即要復(fù)制DWGDirectX軟件包中的DWGDireetX. tlb、OdaToolkit.h和OdaX.h等文件到所編程序的目錄中,再將其頭文件引入至程序中,代碼如下:
#inelude”O(jiān)daToolkit.h” ;
#imPort’’DWGdirectX.tlb’’;
這樣就完成了引入工作,同時(shí)還要定義一些操作DWG文件實(shí)例的變量:
IOdaHostAPP*m_iHost;
IAcadAPPlication*m_iAPPlieation;
IAeadDoeument *m_iCurrentDoc;
因以上所引用變量需要遵從COM規(guī)范,所以在引用時(shí)需要增加計(jì)數(shù),同時(shí)在完成引用之后需要釋放變量,利用Release()函數(shù)完成釋放。
另外在程序開頭需要引入接口變量,利用COM中的智能指針實(shí)現(xiàn)對(duì)變量的引入:
CComPtr
C C o m Q I P t rPNeWEnum;
C C o m Q I P t rPEnt;
CComQIPtr
CComQIPtr
在圖樣信息提取之前,先對(duì)圖樣進(jìn)行模板預(yù)定義,將標(biāo)題欄和明細(xì)欄定義為屬性塊,利用DWGdirectX動(dòng)態(tài)鏈接庫,找到圖樣中相應(yīng)的塊名,依據(jù)屬性標(biāo)簽中的名稱進(jìn)行比對(duì),便可有針對(duì)性的提取明細(xì)欄、裝配欄和標(biāo)題欄中的數(shù)據(jù),如圖號(hào)、名稱和數(shù)量等。相關(guān)實(shí)現(xiàn)代碼如下:
void LoadDwg(CString FileName,int flag)
{
CoInitialize(NULL);
HRESULT hr;
IClassFactory *pCF; //處理整個(gè)類的對(duì)象
CoGetClassObject(__uuidof(OdaHostApp),CLSCTX_INPROC_SERVER,NULL,IID_IClassFactory,(void **)&pCF);//找到接口
hr=pCF->CreateInstance(NULL,IID_ IOdaHostApp,(void **)&m_iHost);
//創(chuàng)建新的非初始化接口對(duì)象
if (CLASS_E_NOTLICENSED == hr)
{
IClassFactory2 *pFactory;
h r=p C F->Q u e r y I n t e r f a c e(I I D_ IClassFactory2,(void **)&pFactory);
if (S_OK == hr)
{
hr = pFactory->CreateInstanceLic(NULL,NULL,IID_IOdaHostApp,(BSTR)_bstr_t("some key"), (void **)&m_iHost);
pFactory->Release();
}
}
pCF->Release();
if (S_OK != hr)
return;
hr=m_iHost->get_Application(&m_ iApplication); //獲得程序應(yīng)用
if (S_OK != hr)
{
m_iHost->Release(); //程序初始化
m_iHost = NULL;
return ;
}
BindSink();
IAcadDocuments* pDocuments; //定義操作圖樣指針
IAcadDatabase* pDb;
_variant_t vPassword;
h r=m_i A p p l i c a t i o n->g e t_ Documents(&pDocuments); //獲得圖樣集合
if (S_OK == hr)
{
vPassword.vt = VT_ERROR;
h r=p D o c u m e n t s->O p e n(F i l e N a m e. AllocSysString(), _variant_t(true), vPassword, &m_ pCurrentDoc);//打開單個(gè)圖樣并,獲取
if (S_OK == hr)
{
hr = m_pCurrentDoc->get_Database(&pDb);//獲取圖樣數(shù)據(jù)信息
if (S_OK == hr)
{
if(flag==0) //比對(duì)塊名稱
ReadTitle(pDb); //讀標(biāo)題欄
if(flag==1) //比對(duì)塊名稱
ReadMxb(pDb); //讀明細(xì)欄
pDb->Release();
}
}
pDocuments->Release();
}
m_iApplication->Quit();
m_iApplication->Release();
m_iApplication = NULL; //釋放程序
UnBindSink();
m_iHost->Release();
m_iHost = NULL; //釋放句柄CoUninitialize();
}
2.1 圖樣數(shù)據(jù)結(jié)構(gòu)模型
將提取到的圖樣明細(xì)信息存入到一個(gè)名為ProduceData的嵌套結(jié)構(gòu)體數(shù)組中,該數(shù)組中每一個(gè)元素代表一張圖樣的信息,該圖樣的名稱和圖號(hào)信息記入標(biāo)題欄結(jié)構(gòu),它的各個(gè)子部件的名稱、圖號(hào)和裝入數(shù)量等信息記入嵌套的明細(xì)欄結(jié)構(gòu)數(shù)組中。該結(jié)構(gòu)數(shù)組在文檔類中定義,它完整記錄了組成產(chǎn)品的所有零部件的信息,作為構(gòu)建圖樣結(jié)構(gòu)樹與零部件信息統(tǒng)計(jì)的基礎(chǔ)數(shù)據(jù),其數(shù)據(jù)結(jié)構(gòu)定義如下。
struct ProduceData
{
CString filename; //文件名
CString head-flag; //頭標(biāo)示參數(shù)
CString tail; //尾部索引參數(shù)
struct Title // 標(biāo)題欄結(jié)構(gòu)體
{
CString name; //名稱
CString code; //圖號(hào)
}Title_info;
struct List //明細(xì)欄結(jié)構(gòu)體
{
CString name; //名稱
CString code; //圖號(hào)
CString number; //裝入數(shù)量
}List_info[];
}DWG_info[];
2.2 圖樣之間關(guān)聯(lián)特點(diǎn)與關(guān)系構(gòu)建
反映設(shè)備齊套性的設(shè)計(jì)文件主要由零件、部件、整件、關(guān)重件、外購件和輔助表格文件等組成。文件之間利用引用于裝配形成映射關(guān)系,具有網(wǎng)狀模型的特征。依據(jù)有無引用關(guān)系,整機(jī)圖樣又可分為零件圖與裝配圖。其中零件圖中只存在標(biāo)題欄,用于記錄零件圖號(hào)、數(shù)量和名稱等信息,零件圖中無裝配關(guān)系信息,所以不能向下構(gòu)建子節(jié)點(diǎn),是產(chǎn)品結(jié)構(gòu)樹的終端節(jié)點(diǎn)。裝配圖中即包含標(biāo)題欄也包含裝配欄,其中裝配欄中記錄了子節(jié)點(diǎn)的圖號(hào)、名稱及數(shù)量信息,可依次向下構(gòu)建結(jié)構(gòu)樹子節(jié)點(diǎn)。
建立裝配圖樣與零件圖樣之間的裝配映射關(guān)系是構(gòu)建結(jié)構(gòu)樹的關(guān)鍵。由于圖樣信息欄中圖號(hào)的唯一性,因此可利用圖號(hào)構(gòu)建圖樣文件之間映射關(guān)系。由于無法預(yù)先判定頂層總裝圖圖號(hào),即不能實(shí)現(xiàn)自頂向下構(gòu)建圖樣結(jié)構(gòu)關(guān)系。因此僅將圖樣集合區(qū)分為“裝配圖”與“零件圖”兩級(jí),利用結(jié)構(gòu)體數(shù)組ProduceData中的code記錄圖號(hào),head-flag作為裝配關(guān)系判斷,tail作為子集圖樣的索引,采用自底向上的方式構(gòu)建圖樣之間的網(wǎng)狀關(guān)系。方法如下:
(1)將所讀的圖樣信息寫入結(jié)構(gòu)體數(shù)組DWG_info[]中,且讀入的每一張圖樣對(duì)應(yīng)結(jié)構(gòu)體數(shù)組DWG_info[i]中唯一的序號(hào)i,如圖樣為裝配圖,則明細(xì)欄中的圖號(hào)也對(duì)應(yīng)此數(shù)組DWG_info[i].List_info[k]中唯一的序號(hào)K。
(2)開始嵌套循環(huán)對(duì)比圖樣集合DWG_info[]中的code圖號(hào)信息,如果DWG_info[i].code值與DWG_info[j]. List_info[k].code值相同,則利用尾部變量tail記錄被裝入圖樣的索引號(hào),即將DWG_info[j].List_info[k].tail值記錄為i,并將被裝入圖樣的頭標(biāo)示變量值記錄為“done”表示此圖樣與其他圖樣存在裝配關(guān)系。
(3)嵌套循環(huán)完成后圖樣之間的映射關(guān)系便記錄在結(jié)構(gòu)體數(shù)組中的tail變量中。在構(gòu)建結(jié)構(gòu)樹時(shí)先判斷ProduceData中的head-flag值是否為空,如果為空則說明本張圖樣不會(huì)裝入其他圖樣中,可作為結(jié)構(gòu)樹的根節(jié)點(diǎn),利用tail索引值可直接找到子節(jié)點(diǎn)的圖樣序號(hào)并讀取其中信息,而對(duì)于tail值為null的裝配圖樣,則說明圖樣集合中缺少對(duì)應(yīng)此裝配圖號(hào)的零件圖樣,可進(jìn)行圖樣缺漏提醒。
2.3 建立圖樣信息結(jié)構(gòu)樹
由于所檢入圖樣可能存在多個(gè)總裝圖,即存在多個(gè)根節(jié)點(diǎn),因此首先在基礎(chǔ)數(shù)據(jù)中找到無裝配關(guān)系的ProduceData結(jié)構(gòu)體數(shù)組。由上一節(jié)中對(duì)無裝配關(guān)系的ProduceData的head-flag參數(shù)標(biāo)記為null,因此只需循環(huán)比較便可找到根節(jié)點(diǎn)結(jié)構(gòu)體ProduceData編號(hào)。根據(jù)之前所建立的圖樣裝配映射關(guān)系,在找到根節(jié)點(diǎn)后便可依照深度優(yōu)先策略,即先子后兄的方式從根節(jié)點(diǎn)開始建立結(jié)構(gòu)樹視圖關(guān)系,步驟如下:
(1)插入結(jié)構(gòu)樹根節(jié)點(diǎn)。
(2)如果當(dāng)前節(jié)點(diǎn)有子節(jié)點(diǎn)(含裝配關(guān)系),用子節(jié)點(diǎn)變量替換,循環(huán)調(diào)用“構(gòu)建結(jié)構(gòu)樹”遞歸函數(shù),轉(zhuǎn)步驟(1)。
(3)若該節(jié)點(diǎn)無子節(jié)點(diǎn)(無裝配關(guān)系),返回。
具體代碼如下:
ConstructTree(code,item)
{
FatherItem=Insert(code,item); //插入節(jié)點(diǎn)
If(HaveChild(code)) //存在子節(jié)點(diǎn)情況
{
For(i=0;i { ConstructTree(childnode[i],F(xiàn)atherItem) ; //替換變量遞歸循環(huán) } } Return; } 以構(gòu)建圖樣信息結(jié)構(gòu)樹與圖樣BOM信息統(tǒng)計(jì)顯示為目的,利用以上所介紹算法,實(shí)現(xiàn)批量讀取DWG格式圖樣文件信息,并同步構(gòu)建圖樣間關(guān)系。利用樹控件構(gòu)建產(chǎn)品結(jié)構(gòu),統(tǒng)計(jì)圖樣數(shù)量,并利用list控件顯示圖樣信息,實(shí)現(xiàn)圖樣結(jié)構(gòu)樹缺損信息提醒,最終將統(tǒng)計(jì)信息以excel格式導(dǎo)出,生成產(chǎn)品零部件統(tǒng)計(jì)清單。圖樣結(jié)構(gòu)樹與產(chǎn)品零部件信息統(tǒng)計(jì)工具軟件如圖2與圖3所示。 本文重點(diǎn)介紹了基于DWGDirectX庫技術(shù)的圖樣信息提取方法,實(shí)現(xiàn)了對(duì)圖樣標(biāo)題欄與明細(xì)欄內(nèi)容的快速讀取,并以此為基礎(chǔ)數(shù)據(jù),提出了構(gòu)建圖樣之間裝配映射關(guān)系的方法。 針對(duì)樣機(jī)研制階段圖樣的管理要求,以快速采集圖樣信息,構(gòu)建圖樣結(jié)構(gòu)樹與零部件數(shù)量統(tǒng)計(jì)為目標(biāo),利用DWGDirectX庫與VC++工具編制應(yīng)用程序,讀取圖樣信息,并采用自底向上的方式構(gòu)建圖樣結(jié)構(gòu)樹與輸出符合企業(yè)標(biāo)準(zhǔn)的零部件統(tǒng)計(jì)清單,實(shí)現(xiàn)了樣機(jī)階段圖樣信息的集中可視化管理與圖樣BOM信息高效糾錯(cuò)核對(duì)。 圖2 圖樣結(jié)構(gòu)樹構(gòu)建 圖3 圖樣結(jié)構(gòu)樹軟件應(yīng)用 參考文獻(xiàn): [1] 董愛先,王學(xué)軍. 第5代移動(dòng)技術(shù)及發(fā)展趨勢(shì)[J].通信技術(shù),2014,47(03): 235-240. [2] Leong K K, Yu Kai Ming. Product data allocation or distributed product data management system [J].Computers in Industry,2002,(47):289-298 [3] 仇巍,刑建國(guó). 基于ObjectARX提取AutoCAD中任意格式表格信息[J].青島大學(xué)學(xué)報(bào),2013,02(06): 49-52. [4] 董玉德,劉孫. 面向工程圖樣離線式表格信息提取與識(shí)別方法研究[J].工程圖學(xué)學(xué)報(bào),2009,01:17-25 [5] 黃維豐,李橋梁,吳洪濤.基于OpenDWG Toolkit 訪問AutoCAD DWG圖形文件[J].現(xiàn)代計(jì)算機(jī),2003,01:69-72. [6] Open Design Specifi cation for .dwg fi les Version 5.2 楊平(1968—),男,高級(jí)工程師,主要研究方向?yàn)檐娪秒娮友b備結(jié)構(gòu)設(shè)計(jì)。 黃巍(1982—),男,工程師,主要研究方向?yàn)檐娪秒娮友b備結(jié)構(gòu)設(shè)計(jì)。 收稿日期:2016年5月6日3 實(shí)例應(yīng)用
4 結(jié)論