摘要: 鑒于AutoCAD在各個(gè)行業(yè)中的廣泛應(yīng)用,目前的技術(shù)只是停留在把AutoCAD圖檔元素信息以文件的形式保存起來(lái),然而隨著項(xiàng)目團(tuán)隊(duì)對(duì)AutoCAD文檔的交叉設(shè)計(jì),實(shí)現(xiàn)如何讓不同的設(shè)計(jì)數(shù)據(jù)共享起來(lái),是個(gè)非常重要的問(wèn)題。本文針對(duì)AutoCAD圖檔中的各種元素(如文本框、矩形框等)信息進(jìn)行讀取,并將其保存到其它形式的數(shù)據(jù)存儲(chǔ)介質(zhì) (如XML或MS SQL Server、Oracle等關(guān)系型數(shù)據(jù)庫(kù)) 中,方便對(duì)AutoCAD圖檔文件進(jìn)行更智能化的信息化管理。AutoCAD文件本身也是一種數(shù)據(jù)庫(kù),文件擴(kuò)展名為DWG,只是該數(shù)據(jù)生態(tài)鏈沒(méi)有和日常中經(jīng)常使用的XML或MS SQL Server、Oracle等關(guān)系型數(shù)據(jù)庫(kù)存儲(chǔ)介質(zhì)進(jìn)行交互傳遞。其實(shí)根據(jù)XML或MS SQL Server、Oracle保存的數(shù)據(jù),我們反過(guò)來(lái)可以修改AutoCAD文件中文本框、矩形框的相關(guān)信息參數(shù),這樣我們就可以和AutoCAD文件進(jìn)行數(shù)據(jù)交互了,讀和寫DWG文件中的元素信息。
關(guān)鍵詞: .NET;AutoCAD ;XML; 數(shù)據(jù)存儲(chǔ)
中圖分類號(hào):TP311 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2014)13-2911-03
1 概述
AutoCAD數(shù)據(jù)庫(kù)是按一定組織結(jié)構(gòu)的各相關(guān)數(shù)據(jù)的集合。它可以用來(lái)存儲(chǔ)組成AutoCAD圖的對(duì)象和實(shí)體。DWG圖是一個(gè)儲(chǔ)存在數(shù)據(jù)庫(kù)中的對(duì)象集合?;镜臄?shù)據(jù)庫(kù)對(duì)象是實(shí)體,符號(hào)表和詞典。圖1列出了組成AutoCAD數(shù)據(jù)庫(kù)的主要部件。
圖1
在AutoCAD中創(chuàng)建的對(duì)象被添加到數(shù)據(jù)庫(kù)對(duì)應(yīng)的容器對(duì)象中,實(shí)體被添加到塊表的記錄中,符號(hào)表記錄被添加到相應(yīng)的符號(hào)表中,所有其他的對(duì)象被添加到命名對(duì)象詞典中,或添加到其他對(duì)象擁有的對(duì)象(擁有其他對(duì)象的對(duì)象最終屬于命名對(duì)象詞典)中,或添加到擴(kuò)充詞典中。
本文開(kāi)發(fā)使用ObjectARX技術(shù),ObjectARX是針對(duì)AutoCAD平臺(tái)上的二次開(kāi)發(fā)而推出的一個(gè)開(kāi)發(fā)軟件包,它提供了以C++為基礎(chǔ)的面向?qū)ο蟮拈_(kāi)發(fā)環(huán)境及應(yīng)用程序接口,能真正快速的訪問(wèn)AutoCAD圖形數(shù)據(jù)庫(kù)。ObjectARX應(yīng)用程序是一個(gè)DLL(動(dòng)態(tài)鏈接庫(kù)),共享AutoCAD的地址空間,對(duì)AutoCAD進(jìn)行直接函數(shù)調(diào)用。
2 功能實(shí)現(xiàn)
具體功能可以通過(guò)以下兩個(gè)步驟加以實(shí)現(xiàn),具體步驟及代碼附加如下:
2.1加載DWG文件
使用Autodesk.AutoCAD.Windows.OpenFileDialog打開(kāi)DWG文件,使用acadApp.DocumentManager.Open打開(kāi)DWG文檔,這樣我們就可以把文件中的相關(guān)元素信息讀取并保存到XML文件中了,具體實(shí)現(xiàn)代碼如下:
private void btnUpload_Click(object sender, EventArgs e)
{ Autodesk.AutoCAD.Windows.OpenFileDialog dialog =
new Autodesk.AutoCAD.Windows.OpenFileDialog(
"選擇DWG文件" , null , "dwg;" , "DwgFile" , Autodesk.AutoCAD.Windows.OpenFileDialog.OpenFileDialogFlags.DoNotTransferRemoteFiles );
if (dialog.ShowDialog() == DialogResult.OK)
{acadApp.DocumentManager.Open(dialog.Filename, false);
//加載XML
XmlDocument DocXml = new XmlDocument();
//文件全路徑名
string spath = System.IO.Path.GetDirectoryName(dialog.Filename);
//去掉擴(kuò)展名的文件名,和DWG同名的XML文件
string sGetFileName = System.IO.Path.GetFileNameWithoutExtension(dialog.Filename);
string sPathFileName = spath + "\\" + sGetFileName + ".xml";
if (File.Exists(sPathFileName))
{ XmlDocument document = new XmlDocument();
document.Load(sPathFileName);
XmlElement element = document["CADDoc"];
if (element != null)
{ Document doc = acadApp.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
using (DocumentLock docLock = doc.LockDocument())
{for (int i = 0; i < element.ChildNodes.Count; i++)
{if (element.ChildNodes[i].Name == "Rectangle")
{ string sStatus =element.ChildNodes[i].ChildNodes[11].FirstChild.Value.ToString().Trim(); }}}
doc.SendStringToExecute("_qsave", true, false, false); }}}}}
2.2把DWG中各元素信息寫入XML文件中
首先把打開(kāi)的DWG文件用DocumentLock docLock = doc.LockDocument()進(jìn)行鎖定,使用XmlTextWriter xtw = new XmlTextWriter(sPathFileName, Encoding.UTF8)創(chuàng)建實(shí)例,然后從DWG文檔中讀取出來(lái)的信息寫入XML文件中。記錄圖紙的句柄、所屬圖層、所屬空間、對(duì)象類型、對(duì)象類別(關(guān)聯(lián)字段)、坐標(biāo)信息(x1y1z1,x2y2z2、長(zhǎng)度或周長(zhǎng)、方位角、面積等)、顏色、線型、線寬、線型比例、樣式、字體、文字、比例、寬度比例因子、傾斜角度、旋轉(zhuǎn)角度等信息。
Document doc = acadApp.DocumentManager.MdiActiveDocument;
//保存
using (DocumentLock docLock = doc.LockDocument())
{doc.SendStringToExecute("_qsave", true, false, false);}
string fileName = doc.Name.ToString().Trim();
// 取文檔信息
if (!File.Exists(fileName))
{throw new FileNotFoundException();}
else
{ //文件全路徑名
string spath = System.IO.Path.GetDirectoryName(fileName);
string sGetFileName = System.IO.Path.GetFileNameWithoutExtension(fileName);
string sDWFFileName = spath + sGetFileName + ".dwf";
if (IFCreateSWF.Checked == true)
{SimplePlot(sDWFFileName);}
docInfo = new DocumentInfo(fileName);
rectInfoList.Clear();
textInfoList.Clear();
GetAllEntityInfo(docInfo.Database);
XmlDocument DocXml = new XmlDocument();
string sPathFileName = spath + "\\" + sGetFileName + ".xml";
if (File.Exists(sPathFileName))
{File.Delete(sPathFileName);}
XmlTextWriter xtw = new XmlTextWriter(sPathFileName, Encoding.UTF8);
xtw.WriteStartDocument();
xtw.WriteStartElement("CADDoc");
xtw.WriteEndElement();
xtw.WriteEndDocument();
xtw.Close();
DocXml.Load(sPathFileName);
int icount = 0;
foreach (RectangleInfo item in rectInfoList)
{ icount++;
RectangleGroup group = new RectangleGroup(item);
XmlElement newRectangleInfo = DocXml.CreateElement("Rectangle");
XmlAttribute newID = DocXml.CreateAttribute("id");
newID.InnerText = icount.ToString();
newRectangleInfo.SetAttributeNode(newID);
//句柄
XmlElement newHandle = DocXml.CreateElement("Handle");
newHandle.InnerText = group.Handle.ToString().Trim();
newRectangleInfo.AppendChild(newHandle);
//圖層
XmlElement newLayer = DocXml.CreateElement("Layer");
newLayer.InnerText = group.Layer.ToString().Trim();
newRectangleInfo.AppendChild(newLayer);
DocXml.DocumentElement.AppendChild(newRectangleInfo); }
DocXml.Save(sPathFileName);
MessageBox.Show("成功生成圖檔信息!");}
3 結(jié)束語(yǔ)
通過(guò)上面的代碼可以實(shí)現(xiàn)從AutoCAD文件中讀取各元素相關(guān)信息,并保存到XML文件中,其實(shí)也可以把這些信息保存到關(guān)系型數(shù)據(jù)庫(kù)中,只需要把保存到XML文件的代碼修改成保存到數(shù)據(jù)庫(kù)中的代碼就行了,該文不在贅述。
其實(shí)反過(guò)來(lái),從XML中讀取相關(guān)數(shù)據(jù),也是可以加載到AutoCAD文件中,使AutoCAD文件中的元素信息依據(jù)XML中的數(shù)據(jù)進(jìn)行更新。因此只要我們通過(guò)信息管理軟件對(duì)XML或數(shù)據(jù)庫(kù)中的相關(guān)數(shù)據(jù)進(jìn)行更新,我們?cè)诩虞dXML文件時(shí),同樣也可以把AutoCAD文件對(duì)應(yīng)的相關(guān)元素信息進(jìn)行更新,從而可以保持AutoCAD文件里的數(shù)據(jù)共享,方便不同部門或不同區(qū)域的人員使用。
參考文獻(xiàn):
[1] Christian Nagel. C#高級(jí)編程[M].7版.清華大學(xué)出版社,2010.
[2] Andrew Troelsen. C#與.NET 4高級(jí)程序設(shè)計(jì)[M].5版.人民郵電出版社,2011.
[3] 周衛(wèi).AUTO CAD地圖制圖與系統(tǒng)開(kāi)發(fā)[M].科學(xué)出版社,2010.
[4] 林昌華,黃霞,楊巖.機(jī)械CAD開(kāi)發(fā)技術(shù)[M].國(guó)防工業(yè)出版社,2013.
{ string sStatus =element.ChildNodes[i].ChildNodes[11].FirstChild.Value.ToString().Trim(); }}}
doc.SendStringToExecute("_qsave", true, false, false); }}}}}
2.2把DWG中各元素信息寫入XML文件中
首先把打開(kāi)的DWG文件用DocumentLock docLock = doc.LockDocument()進(jìn)行鎖定,使用XmlTextWriter xtw = new XmlTextWriter(sPathFileName, Encoding.UTF8)創(chuàng)建實(shí)例,然后從DWG文檔中讀取出來(lái)的信息寫入XML文件中。記錄圖紙的句柄、所屬圖層、所屬空間、對(duì)象類型、對(duì)象類別(關(guān)聯(lián)字段)、坐標(biāo)信息(x1y1z1,x2y2z2、長(zhǎng)度或周長(zhǎng)、方位角、面積等)、顏色、線型、線寬、線型比例、樣式、字體、文字、比例、寬度比例因子、傾斜角度、旋轉(zhuǎn)角度等信息。
Document doc = acadApp.DocumentManager.MdiActiveDocument;
//保存
using (DocumentLock docLock = doc.LockDocument())
{doc.SendStringToExecute("_qsave", true, false, false);}
string fileName = doc.Name.ToString().Trim();
// 取文檔信息
if (!File.Exists(fileName))
{throw new FileNotFoundException();}
else
{ //文件全路徑名
string spath = System.IO.Path.GetDirectoryName(fileName);
string sGetFileName = System.IO.Path.GetFileNameWithoutExtension(fileName);
string sDWFFileName = spath + sGetFileName + ".dwf";
if (IFCreateSWF.Checked == true)
{SimplePlot(sDWFFileName);}
docInfo = new DocumentInfo(fileName);
rectInfoList.Clear();
textInfoList.Clear();
GetAllEntityInfo(docInfo.Database);
XmlDocument DocXml = new XmlDocument();
string sPathFileName = spath + "\\" + sGetFileName + ".xml";
if (File.Exists(sPathFileName))
{File.Delete(sPathFileName);}
XmlTextWriter xtw = new XmlTextWriter(sPathFileName, Encoding.UTF8);
xtw.WriteStartDocument();
xtw.WriteStartElement("CADDoc");
xtw.WriteEndElement();
xtw.WriteEndDocument();
xtw.Close();
DocXml.Load(sPathFileName);
int icount = 0;
foreach (RectangleInfo item in rectInfoList)
{ icount++;
RectangleGroup group = new RectangleGroup(item);
XmlElement newRectangleInfo = DocXml.CreateElement("Rectangle");
XmlAttribute newID = DocXml.CreateAttribute("id");
newID.InnerText = icount.ToString();
newRectangleInfo.SetAttributeNode(newID);
//句柄
XmlElement newHandle = DocXml.CreateElement("Handle");
newHandle.InnerText = group.Handle.ToString().Trim();
newRectangleInfo.AppendChild(newHandle);
//圖層
XmlElement newLayer = DocXml.CreateElement("Layer");
newLayer.InnerText = group.Layer.ToString().Trim();
newRectangleInfo.AppendChild(newLayer);
DocXml.DocumentElement.AppendChild(newRectangleInfo); }
DocXml.Save(sPathFileName);
MessageBox.Show("成功生成圖檔信息!");}
3 結(jié)束語(yǔ)
通過(guò)上面的代碼可以實(shí)現(xiàn)從AutoCAD文件中讀取各元素相關(guān)信息,并保存到XML文件中,其實(shí)也可以把這些信息保存到關(guān)系型數(shù)據(jù)庫(kù)中,只需要把保存到XML文件的代碼修改成保存到數(shù)據(jù)庫(kù)中的代碼就行了,該文不在贅述。
其實(shí)反過(guò)來(lái),從XML中讀取相關(guān)數(shù)據(jù),也是可以加載到AutoCAD文件中,使AutoCAD文件中的元素信息依據(jù)XML中的數(shù)據(jù)進(jìn)行更新。因此只要我們通過(guò)信息管理軟件對(duì)XML或數(shù)據(jù)庫(kù)中的相關(guān)數(shù)據(jù)進(jìn)行更新,我們?cè)诩虞dXML文件時(shí),同樣也可以把AutoCAD文件對(duì)應(yīng)的相關(guān)元素信息進(jìn)行更新,從而可以保持AutoCAD文件里的數(shù)據(jù)共享,方便不同部門或不同區(qū)域的人員使用。
參考文獻(xiàn):
[1] Christian Nagel. C#高級(jí)編程[M].7版.清華大學(xué)出版社,2010.
[2] Andrew Troelsen. C#與.NET 4高級(jí)程序設(shè)計(jì)[M].5版.人民郵電出版社,2011.
[3] 周衛(wèi).AUTO CAD地圖制圖與系統(tǒng)開(kāi)發(fā)[M].科學(xué)出版社,2010.
[4] 林昌華,黃霞,楊巖.機(jī)械CAD開(kāi)發(fā)技術(shù)[M].國(guó)防工業(yè)出版社,2013.
{ string sStatus =element.ChildNodes[i].ChildNodes[11].FirstChild.Value.ToString().Trim(); }}}
doc.SendStringToExecute("_qsave", true, false, false); }}}}}
2.2把DWG中各元素信息寫入XML文件中
首先把打開(kāi)的DWG文件用DocumentLock docLock = doc.LockDocument()進(jìn)行鎖定,使用XmlTextWriter xtw = new XmlTextWriter(sPathFileName, Encoding.UTF8)創(chuàng)建實(shí)例,然后從DWG文檔中讀取出來(lái)的信息寫入XML文件中。記錄圖紙的句柄、所屬圖層、所屬空間、對(duì)象類型、對(duì)象類別(關(guān)聯(lián)字段)、坐標(biāo)信息(x1y1z1,x2y2z2、長(zhǎng)度或周長(zhǎng)、方位角、面積等)、顏色、線型、線寬、線型比例、樣式、字體、文字、比例、寬度比例因子、傾斜角度、旋轉(zhuǎn)角度等信息。
Document doc = acadApp.DocumentManager.MdiActiveDocument;
//保存
using (DocumentLock docLock = doc.LockDocument())
{doc.SendStringToExecute("_qsave", true, false, false);}
string fileName = doc.Name.ToString().Trim();
// 取文檔信息
if (!File.Exists(fileName))
{throw new FileNotFoundException();}
else
{ //文件全路徑名
string spath = System.IO.Path.GetDirectoryName(fileName);
string sGetFileName = System.IO.Path.GetFileNameWithoutExtension(fileName);
string sDWFFileName = spath + sGetFileName + ".dwf";
if (IFCreateSWF.Checked == true)
{SimplePlot(sDWFFileName);}
docInfo = new DocumentInfo(fileName);
rectInfoList.Clear();
textInfoList.Clear();
GetAllEntityInfo(docInfo.Database);
XmlDocument DocXml = new XmlDocument();
string sPathFileName = spath + "\\" + sGetFileName + ".xml";
if (File.Exists(sPathFileName))
{File.Delete(sPathFileName);}
XmlTextWriter xtw = new XmlTextWriter(sPathFileName, Encoding.UTF8);
xtw.WriteStartDocument();
xtw.WriteStartElement("CADDoc");
xtw.WriteEndElement();
xtw.WriteEndDocument();
xtw.Close();
DocXml.Load(sPathFileName);
int icount = 0;
foreach (RectangleInfo item in rectInfoList)
{ icount++;
RectangleGroup group = new RectangleGroup(item);
XmlElement newRectangleInfo = DocXml.CreateElement("Rectangle");
XmlAttribute newID = DocXml.CreateAttribute("id");
newID.InnerText = icount.ToString();
newRectangleInfo.SetAttributeNode(newID);
//句柄
XmlElement newHandle = DocXml.CreateElement("Handle");
newHandle.InnerText = group.Handle.ToString().Trim();
newRectangleInfo.AppendChild(newHandle);
//圖層
XmlElement newLayer = DocXml.CreateElement("Layer");
newLayer.InnerText = group.Layer.ToString().Trim();
newRectangleInfo.AppendChild(newLayer);
DocXml.DocumentElement.AppendChild(newRectangleInfo); }
DocXml.Save(sPathFileName);
MessageBox.Show("成功生成圖檔信息!");}
3 結(jié)束語(yǔ)
通過(guò)上面的代碼可以實(shí)現(xiàn)從AutoCAD文件中讀取各元素相關(guān)信息,并保存到XML文件中,其實(shí)也可以把這些信息保存到關(guān)系型數(shù)據(jù)庫(kù)中,只需要把保存到XML文件的代碼修改成保存到數(shù)據(jù)庫(kù)中的代碼就行了,該文不在贅述。
其實(shí)反過(guò)來(lái),從XML中讀取相關(guān)數(shù)據(jù),也是可以加載到AutoCAD文件中,使AutoCAD文件中的元素信息依據(jù)XML中的數(shù)據(jù)進(jìn)行更新。因此只要我們通過(guò)信息管理軟件對(duì)XML或數(shù)據(jù)庫(kù)中的相關(guān)數(shù)據(jù)進(jìn)行更新,我們?cè)诩虞dXML文件時(shí),同樣也可以把AutoCAD文件對(duì)應(yīng)的相關(guān)元素信息進(jìn)行更新,從而可以保持AutoCAD文件里的數(shù)據(jù)共享,方便不同部門或不同區(qū)域的人員使用。
參考文獻(xiàn):
[1] Christian Nagel. C#高級(jí)編程[M].7版.清華大學(xué)出版社,2010.
[2] Andrew Troelsen. C#與.NET 4高級(jí)程序設(shè)計(jì)[M].5版.人民郵電出版社,2011.
[3] 周衛(wèi).AUTO CAD地圖制圖與系統(tǒng)開(kāi)發(fā)[M].科學(xué)出版社,2010.
[4] 林昌華,黃霞,楊巖.機(jī)械CAD開(kāi)發(fā)技術(shù)[M].國(guó)防工業(yè)出版社,2013.