楊 平 黃 巍(中國電子科技集團第三十研究所,四川,成都,610041)
?
基于DWG DirectX的電子產品圖樣結構關系輕量化構建方法研究
楊平 黃巍
(中國電子科技集團第三十研究所,四川,成都,610041)
摘要:為便于樣機研發階段顯示產品圖樣結構關系,準確統計產品零部件信息,提高對圖樣裝配欄與明細欄信息的審核效率,利用VC 2008平臺與DWGdirectX開發工具實現了在非AutoCAD環境下的圖樣信息提取。利用嵌套循環比對算法深度遍歷圖樣信息集合,并構建圖樣之間的裝配映射關系。利用MFC控件直觀顯示圖樣結構關系與BOM表信息,自動統計與核對產品零部件數量,實現缺漏圖樣提醒。在檢入PDM系統前,有效降低了圖樣BOM信息的錯誤發生率,并最終生成符合企業標準的產品清單。
關鍵詞:圖樣結構樹 DWGdirectX動態鏈接庫 信息提取 遞歸算法
電子產品的圖檔文件依據構成要素可分為結構零部件圖表、印制板板卡圖表和機內外通信互聯線纜圖表等,其圖樣關系構成較為復雜,如大型網絡交換機與新型互聯網控制器等。其設備表現出功能更加密集化、融合度更高的特點[1],同時對處于樣機研制階段中圖樣模型的完整性與正確性提出了更高的要求。要滿足產品完整性與正確性,就需要構建清晰的產品結構樹關系。目前商用產品數據管理系統(PDM)采用自頂向下方式構建產品結構樹關系,而在產品樣機研制階段往往缺乏設備頂層裝配圖表,因此商用PDM系統很難全面、清晰地反映出樣機階段產品的結構樹關系。
電子通信產品的BOM信息是產品的核心組織,其中的產品結構樹與零部件數量信息是檢驗產品完整性的重要信息。這些信息來源于產品的每一張設計圖樣。如何高效的讀取產品BOM信息,檢驗產品零部件圖樣的正確性與齊套性,不僅是設計者同時也是產品信息管理者所關心的問題。目前Autodesk公司的DWG格式文件是國內外應用最為廣泛的產品設計信息存儲文件[2]。批量讀取DWG格式圖樣信息方法較為多樣,例如,仇巍基于ObjectARX利用單元化信息匹配的方式提取圖樣信息[3],董玉德等利用明細表坐標比對方式識別圖樣明細欄信息并提取[4],此兩種方法都無法完全擺脫AutoCAD環境,因此存在耗用計算機資源較多,提取速度慢的問題。黃維豐和李橋梁等利用ODT技術實現了對DWG格式圖樣直接讀取[5],但只能提取2004版本之前的圖樣文件。本文基于Open Design Alliance開發的DWGDirectX的ActiveX控件[6],脫離AutoCAD環境,直接讀取DWG文件,提取所需圖樣BOM信息,采用自底向上的方式構建圖樣結構樹與零部件統計信息,實現對圖樣BOM信息的集中統計、檢查、核對與缺漏提醒。
1.1 DWG圖樣格式分析
DWG文件主要由表段(TABLE)、實體段(ENTITY)、塊段(BLOCK)和文件頭(HEADER)等組合而成,文件以二進制方式書寫,用于存儲AutoCAD圖形文件。
其中DWG文件的版本號與各段中的起始地址、圖形因子以及DWG整參數等記錄于DWG的頭文件中。因AutoCAD版本的差異,帶來DWG文件會有些許細微差別。
圖塊由多個不同類型的實體組成,同時每個圖塊對應屬于自己的索引用于區別不同的圖塊,這些索引組成了包含塊名、塊長度、標志字和結束標志的塊表。
實體段用于記錄AutoCAD中稱之為實體的圖元數據。這些圖元是指直線、點、圓、弧、文字、多義線、軌跡線和插入塊等。塊段用于記錄組成DWG文件每個塊的顏色、線型和插入基點等實體信息。由每個塊所對應的實體表組成。表段在DWG文件中存儲在實體段之后,實際上它是由塊表、層表、字型表、線型表、視圖表順序組成的。層表由描述每個圖層的表記錄依次組成,表記錄包括以下內容:層狀態標志、層名、層顏色、層線型。
文件中一些重要索引信息的副本被存放于應急頭部之中。
1.2 基于DWGDirectX讀取原理
DWGDirectX通過API函數提供對DWG或DXF文件的內容的讀寫通道。DWGDirectX提供的接口中含有許多類型的對象,這些對象是以一種層次化的方式來組織的。DWGDirectX描述的DWG文件對象模型結構圖如圖1所示。

圖1 DWG文件結構圖
讀取圖樣的核心機制在于將Autodesk公司加密的二進制圖樣文件轉化為數據自定義的模型文件,DWGDirectX組織數據的方式與ObjectARX非常相似,包括線型(LineType)、形文件(shapeFile)、圖塊(Bloek)、圖層(Layer)、視口(ViewPort)、標注樣式(Dimstyle)、視圖(View)、注冊應用程序(RegApp)和用戶坐標系(ues)等9個容器表,以及Modelspace(模型空間)和PaperSPace(圖樣空間)兩種基本類型的塊表。
OdaHostApp類表示整個應用程序,OdaHostApp的對象中定義了相關面向對象的接口,用于處理應用程序。利用其Application屬性來操作主應用程序。AcadApplication類的對象負責控制整個應用程序的各個屬性和應用程序層面的方法。所有應用程序層面的一些工作都是由它完成的,而且各個其他對象也是通過AcadApplication來與操作系統等外界的環境進行交互。但AcadApplication類的對象只能通過OdaHostApp對象的Application屬性獲得。
AcadDocument對象的Documents屬性返回一個AcadDocument對象集合,其中每個AcadDocument對象都代表一張圖樣。每張圖樣都有自己對應的模型空間,所以對應在內存中就會有一個AcadModelSpace集合。在DWG格式的圖樣文件中的點、線、文字、圓和圓弧等元素,都是以對應的實體形式存儲在模型空間或圖樣空間中。每個實體都有一個索引,在模型空間中通過該索引我們可以找到該實體。
因工程圖樣格式相對固定,因此可利用圖樣中的“塊”特性,預先定制不同圖幅中標題欄與明細欄的屬性名稱與屬性值。在圖樣提取過程中,重點對圖樣中的“塊”屬性值進行比對與提取,從而實現對圖樣標題欄與明細欄信息提取。
1.3 提取過程與實現代碼
在進行軟件開發之前需要先引入動態鏈接庫的接口文件,即要復制DWGDirectX軟件包中的DWGDireetX. tlb、OdaToolkit.h和OdaX.h等文件到所編程序的目錄中,再將其頭文件引入至程序中,代碼如下:
#inelude”OdaToolkit.h” ;
#imPort’’DWGdirectX.tlb’’;
這樣就完成了引入工作,同時還要定義一些操作DWG文件實例的變量:
IOdaHostAPP*m_iHost;
IAcadAPPlication*m_iAPPlieation;
IAeadDoeument *m_iCurrentDoc;
因以上所引用變量需要遵從COM規范,所以在引用時需要增加計數,同時在完成引用之后需要釋放變量,利用Release()函數完成釋放。
另外在程序開頭需要引入接口變量,利用COM中的智能指針實現對變量的引入:
CComPtr
C C o m Q I P t rPNeWEnum;
C C o m Q I P t rPEnt;
CComQIPtr
CComQIPtr
在圖樣信息提取之前,先對圖樣進行模板預定義,將標題欄和明細欄定義為屬性塊,利用DWGdirectX動態鏈接庫,找到圖樣中相應的塊名,依據屬性標簽中的名稱進行比對,便可有針對性的提取明細欄、裝配欄和標題欄中的數據,如圖號、名稱和數量等。相關實現代碼如下:
void LoadDwg(CString FileName,int flag)
{
CoInitialize(NULL);
HRESULT hr;
IClassFactory *pCF; //處理整個類的對象
CoGetClassObject(__uuidof(OdaHostApp),CLSCTX_INPROC_SERVER,NULL,IID_IClassFactory,(void **)&pCF);//找到接口
hr=pCF->CreateInstance(NULL,IID_ IOdaHostApp,(void **)&m_iHost);
//創建新的非初始化接口對象
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); //獲得程序應用
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);//打開單個圖樣并,獲取
if (S_OK == hr)
{
hr = m_pCurrentDoc->get_Database(&pDb);//獲取圖樣數據信息
if (S_OK == hr)
{
if(flag==0) //比對塊名稱
ReadTitle(pDb); //讀標題欄
if(flag==1) //比對塊名稱
ReadMxb(pDb); //讀明細欄
pDb->Release();
}
}
pDocuments->Release();
}
m_iApplication->Quit();
m_iApplication->Release();
m_iApplication = NULL; //釋放程序
UnBindSink();
m_iHost->Release();
m_iHost = NULL; //釋放句柄CoUninitialize();
}
2.1 圖樣數據結構模型
將提取到的圖樣明細信息存入到一個名為ProduceData的嵌套結構體數組中,該數組中每一個元素代表一張圖樣的信息,該圖樣的名稱和圖號信息記入標題欄結構,它的各個子部件的名稱、圖號和裝入數量等信息記入嵌套的明細欄結構數組中。該結構數組在文檔類中定義,它完整記錄了組成產品的所有零部件的信息,作為構建圖樣結構樹與零部件信息統計的基礎數據,其數據結構定義如下。
struct ProduceData
{
CString filename; //文件名
CString head-flag; //頭標示參數
CString tail; //尾部索引參數
struct Title // 標題欄結構體
{
CString name; //名稱
CString code; //圖號
}Title_info;
struct List //明細欄結構體
{
CString name; //名稱
CString code; //圖號
CString number; //裝入數量
}List_info[];
}DWG_info[];
2.2 圖樣之間關聯特點與關系構建
反映設備齊套性的設計文件主要由零件、部件、整件、關重件、外購件和輔助表格文件等組成。文件之間利用引用于裝配形成映射關系,具有網狀模型的特征。依據有無引用關系,整機圖樣又可分為零件圖與裝配圖。其中零件圖中只存在標題欄,用于記錄零件圖號、數量和名稱等信息,零件圖中無裝配關系信息,所以不能向下構建子節點,是產品結構樹的終端節點。裝配圖中即包含標題欄也包含裝配欄,其中裝配欄中記錄了子節點的圖號、名稱及數量信息,可依次向下構建結構樹子節點。
建立裝配圖樣與零件圖樣之間的裝配映射關系是構建結構樹的關鍵。由于圖樣信息欄中圖號的唯一性,因此可利用圖號構建圖樣文件之間映射關系。由于無法預先判定頂層總裝圖圖號,即不能實現自頂向下構建圖樣結構關系。因此僅將圖樣集合區分為“裝配圖”與“零件圖”兩級,利用結構體數組ProduceData中的code記錄圖號,head-flag作為裝配關系判斷,tail作為子集圖樣的索引,采用自底向上的方式構建圖樣之間的網狀關系。方法如下:
(1)將所讀的圖樣信息寫入結構體數組DWG_info[]中,且讀入的每一張圖樣對應結構體數組DWG_info[i]中唯一的序號i,如圖樣為裝配圖,則明細欄中的圖號也對應此數組DWG_info[i].List_info[k]中唯一的序號K。
(2)開始嵌套循環對比圖樣集合DWG_info[]中的code圖號信息,如果DWG_info[i].code值與DWG_info[j]. List_info[k].code值相同,則利用尾部變量tail記錄被裝入圖樣的索引號,即將DWG_info[j].List_info[k].tail值記錄為i,并將被裝入圖樣的頭標示變量值記錄為“done”表示此圖樣與其他圖樣存在裝配關系。
(3)嵌套循環完成后圖樣之間的映射關系便記錄在結構體數組中的tail變量中。在構建結構樹時先判斷ProduceData中的head-flag值是否為空,如果為空則說明本張圖樣不會裝入其他圖樣中,可作為結構樹的根節點,利用tail索引值可直接找到子節點的圖樣序號并讀取其中信息,而對于tail值為null的裝配圖樣,則說明圖樣集合中缺少對應此裝配圖號的零件圖樣,可進行圖樣缺漏提醒。
2.3 建立圖樣信息結構樹
由于所檢入圖樣可能存在多個總裝圖,即存在多個根節點,因此首先在基礎數據中找到無裝配關系的ProduceData結構體數組。由上一節中對無裝配關系的ProduceData的head-flag參數標記為null,因此只需循環比較便可找到根節點結構體ProduceData編號。根據之前所建立的圖樣裝配映射關系,在找到根節點后便可依照深度優先策略,即先子后兄的方式從根節點開始建立結構樹視圖關系,步驟如下:
(1)插入結構樹根節點。
(2)如果當前節點有子節點(含裝配關系),用子節點變量替換,循環調用“構建結構樹”遞歸函數,轉步驟(1)。
(3)若該節點無子節點(無裝配關系),返回。
具體代碼如下:
ConstructTree(code,item)
{
FatherItem=Insert(code,item); //插入節點
If(HaveChild(code)) //存在子節點情況
{
For(i=0;i { ConstructTree(childnode[i],FatherItem) ; //替換變量遞歸循環 } } Return; } 以構建圖樣信息結構樹與圖樣BOM信息統計顯示為目的,利用以上所介紹算法,實現批量讀取DWG格式圖樣文件信息,并同步構建圖樣間關系。利用樹控件構建產品結構,統計圖樣數量,并利用list控件顯示圖樣信息,實現圖樣結構樹缺損信息提醒,最終將統計信息以excel格式導出,生成產品零部件統計清單。圖樣結構樹與產品零部件信息統計工具軟件如圖2與圖3所示。 本文重點介紹了基于DWGDirectX庫技術的圖樣信息提取方法,實現了對圖樣標題欄與明細欄內容的快速讀取,并以此為基礎數據,提出了構建圖樣之間裝配映射關系的方法。 針對樣機研制階段圖樣的管理要求,以快速采集圖樣信息,構建圖樣結構樹與零部件數量統計為目標,利用DWGDirectX庫與VC++工具編制應用程序,讀取圖樣信息,并采用自底向上的方式構建圖樣結構樹與輸出符合企業標準的零部件統計清單,實現了樣機階段圖樣信息的集中可視化管理與圖樣BOM信息高效糾錯核對。 圖2 圖樣結構樹構建 圖3 圖樣結構樹軟件應用 參考文獻: [1] 董愛先,王學軍. 第5代移動技術及發展趨勢[J].通信技術,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] 仇巍,刑建國. 基于ObjectARX提取AutoCAD中任意格式表格信息[J].青島大學學報,2013,02(06): 49-52. [4] 董玉德,劉孫. 面向工程圖樣離線式表格信息提取與識別方法研究[J].工程圖學學報,2009,01:17-25 [5] 黃維豐,李橋梁,吳洪濤.基于OpenDWG Toolkit 訪問AutoCAD DWG圖形文件[J].現代計算機,2003,01:69-72. [6] Open Design Specifi cation for .dwg fi les Version 5.2 楊平(1968—),男,高級工程師,主要研究方向為軍用電子裝備結構設計。 黃巍(1982—),男,工程師,主要研究方向為軍用電子裝備結構設計。 收稿日期:2016年5月6日3 實例應用
4 結論

