DXF庫(dxflib)使用指南


DXF庫(dxflib)使用指南

作者:Andrew Mustun
版權:2004-2005 RibbonSoft公司. 保留所有權利。
日期:2005年3月
原文:http://www.ribbonsoft.com/dxflib/manual.pdf
源碼:http://www.ribbonsoft.com/archives/dxflib/dxflib-2.0.4.8-2.src.tar.gz
翻譯:柴樹杉(http://sites.google.com/site/chaishushan/)

目錄

第一章 簡介

dxflib是一個用來讀寫DXF文件的C++庫。當讀DXF文件的時候,dxflib分析文件並且調用用戶自己定義的函數來添加實體、層、等。

需要注意的是,dxflib並不保存任何實體或者信息。它只是從DXF文件中分析可以識別的實體以及其他的對象。

使用dxflib庫讀DXF文件並不需要知道所有的DXF格式信息。當然,像實體、屬性、層、段等基本概念還是需要了解的。如果是用dxflib庫寫DXF文件,則需要知道DXF文件是如何組織的。

dxflib完全基於C/C++標准庫實現,不依賴任何其他的庫。

第二章 編譯dxflib庫

Unix/Linux

在Unix/Linux系統中編譯dxflib庫,需要輸入以下命令:

./configure
make

 

該命令生成一個"./lib/dxflib.a"靜態庫。如果需要創建一個動態連接庫,需要用"make shared"代替前面的"make"命令。這樣就生成一個"./lib/libdxf.so.2.0.x.x"文件,然后再創建一個"./lib/libdxf.so"連接到"./lib/libdxf.so.2.0.x.x"。

如果不使用"make install"命令,你也可以直接將頭文件和生成的庫文件復制到你需要的目錄中。

Windows

在windows系統中編譯dxflib庫可以有多中選擇,你可以使用VC、Borland C++、GCC以及其他各種編譯器。

在這里我們采用cygwin和gcc編譯:

./configure
MinGW32-make

 

第三章 讀DXF文件

dxf-libmanual.jpg

工作原理:dxflib分析DXF文件,然后調用用戶定義的回調函數。用戶可以在回調函數中處理各種實體,或者將它們保存到容器中。

實現Creation接口

用戶操作DXF的類,需要由DL_CreationInterface或者DL_CreationAdapter派生。在一般情況下DL_CreationAdapter是一個常用的選擇,因為它並不強迫子類實現所有的虛函數。

1 class MyDxfFilter : public DL_CreationAdapter
2 {
3     virtual void addLine(const DL_LineData& d);
4     ...
5 }

 

在重新實現的虛函數addLine中,用戶可以選擇將實體保存到容器,也可以選擇其他的方式處理。

1 void MyDxfFilter::addLine(const DL_LineData& d)
2 {
3     std::cout << "Line: " << d.x1 << "/" << d.y1
4     << " " << d.x2 << "/" << d.y2 << std::endl;
5 }

 

讀DXF文件的時候,你只需要將自己派生的類傳遞給分析器就可以了。

1 MyDxfFilter f;
2 DL_Dxf dxf;
3 if (!dxf.in("drawing.dxf", &f))
4 {
5     std::cerr << "drawing.dxf could not be opened.\n";
6 }

 

第四章 寫DXF文件

為了寫DXF文件,你可能需要反復嵌套調用dxflib的許多函數。dxflib本身並不存儲任何entities,你需要到達entities的位置,並且對每個entities調用相應的寫函數。你必須確保以正確的順序調用dxflib的函數,否則生成的DXF文件可能不符合標准。

4.1 創建一個Writer對象

為了創建Writer,你需要指定DXF文件的版本號。目前只有兩種可用的DXF版本:R12和DXF 2000/2002。R12對應的dxflib編碼是DL_CodesAC1009,DXF 2000/2002對應的是DL_CodesAC1015。

用兩種API接口可以用於寫DXF文件。DL_WriterA接口提供一種相對底層的操作key/value元祖的方式。用DL_WriterA接口創建一個有效的DXF文件是很繁瑣的。因此,還有一個相對高級的DL_Dxf接口可以再不了解key/value的前提下直接寫入整條線。

下面的代碼創建並以寫方式打開一個DXF 2000/2002文件:

1 DL_Dxf dxf;
2 DL_Codes::version exportVersion = DL_Codes::AC1015;
3 DL_WriterA* dw = dxf.out("myfile.dxf", exportVersion);
4 if (dw==NULL)
5 {
6     printf("Cannot open file 'myfile.dxf' \
7         for writing.");
8     // abort function e.g. with return
9 }

 

4.2 寫DXF Header

4.2.1 打開DXF Header

DXF Header包含了DXF文件的版本信息。因此,必須用dxf.writeHeader(*dw)再最開始寫入DXF Header。下面的列表顯示了一個DXF Header的典型布局:

999
dxflib 2.0.4.8
  0
SECTION
  2
HEADER
  9
$ACADVER
  1
AC1015
  9
$HANDSEED
  5
FFFF

 

如你所見,writeHeader()函數並不關閉header。這是因為你可能需要再header中存儲一些變量。如果你需要存儲變量,可以再這個時候進行。如果不存儲變量,可以直接關閉header。

4.2.2 存儲附加的變量

DXF header中的變量用於保存DXF文件對應圖形的元信息。如果像了解DXF所支持的全部變量,可以參考DXF的文檔。

下面的代碼片段顯示了如果存儲不同類型的變量。你可以存儲很多變量,但是你必須確保以創建時變量的順序來支持它。

 1 // int variable:
 2 dw->dxfString(9, "$INSUNITS");
 3 dw->dxfInt(70, 4);
 4 // real (double, float) variable:
 5 dw->dxfString(9, "$DIMEXE");
 6 dw->dxfReal(40, 1.25);
 7 // string variable:
 8 dw->dxfString(9, "$TEXTSTYLE");
 9 dw->dxfString(7, "Standard");
10 // vector variable:
11 dw->dxfString(9, "$LIMMIN");
12 dw->dxfReal(10, 0.0);
13 dw->dxfReal(20, 0.0);

 

 

4.2.3 關閉Header

使用下面的函數可以關閉DXF header(結束當前的Section):

dw->sectionEnd();

 

4.3 寫Tables Section

4.3.1 打開Tables Section

DXF文件的tables section包含了tables的一些定義,如viewports、linestyles、layers等信息。可以用下面的函數打開tables section:

dw->sectionTables();

 

4.3.2 寫Viewports

Viewports再dxflib還沒有得到很好的支持。但是它對於一個有效的DXF文件卻是必須的。不過我們可以使用下面的函數寫入一個標准的viewports:

dxf.writeVPort(*dw);

 

4.3.3 寫Linetypes

其實DXF文件中只有linetypes是必須定義的。你可以用dxflib簡單低存儲全部的linetypes,如下面的代碼:

 1 dw->tableLineTypes(25);
 2 dxf.writeLineType(*dw, DL_LineTypeData("BYBLOCK", 0));
 3 dxf.writeLineType(*dw, DL_LineTypeData("BYLAYER", 0));
 4 dxf.writeLineType(*dw, DL_LineTypeData("CONTINUOUS", 0));
 5 dxf.writeLineType(*dw, DL_LineTypeData("ACAD_ISO02W100", 0));
 6 dxf.writeLineType(*dw, DL_LineTypeData("ACAD_ISO03W100", 0));
 7 dxf.writeLineType(*dw, DL_LineTypeData("ACAD_ISO04W100", 0));
 8 dxf.writeLineType(*dw, DL_LineTypeData("ACAD_ISO05W100", 0));
 9 dxf.writeLineType(*dw, DL_LineTypeData("BORDER", 0));
10 dxf.writeLineType(*dw, DL_LineTypeData("BORDER2", 0));
11 dxf.writeLineType(*dw, DL_LineTypeData("BORDERX2", 0));
12 dxf.writeLineType(*dw, DL_LineTypeData("CENTER", 0));
13 dxf.writeLineType(*dw, DL_LineTypeData("CENTER2", 0));
14 dxf.writeLineType(*dw, DL_LineTypeData("CENTERX2", 0));
15 dxf.writeLineType(*dw, DL_LineTypeData("DASHDOT", 0));
16 dxf.writeLineType(*dw, DL_LineTypeData("DASHDOT2", 0));
17 dxf.writeLineType(*dw, DL_LineTypeData("DASHDOTX2", 0));
18 dxf.writeLineType(*dw, DL_LineTypeData("DASHED", 0));
19 dxf.writeLineType(*dw, DL_LineTypeData("DASHED2", 0));
20 dxf.writeLineType(*dw, DL_LineTypeData("DASHEDX2", 0));
21 dxf.writeLineType(*dw, DL_LineTypeData("DIVIDE", 0));
22 dxf.writeLineType(*dw, DL_LineTypeData("DIVIDE2", 0));
23 dxf.writeLineType(*dw, DL_LineTypeData("DIVIDEX2", 0));
24 dxf.writeLineType(*dw, DL_LineTypeData("DOT", 0));
25 dxf.writeLineType(*dw, DL_LineTypeData("DOT2", 0));
26 dxf.writeLineType(*dw, DL_LineTypeData("DOTX2", 0));
27 dw->tableEnd();

 

4.3.4 寫Layers

Layers對於很多DXF圖形而言是一個比較重要的部分。繪圖中所涉及到的所有layers需要在table section中定義。下面的實例代碼在DXF文件中創建了3個layers,分別命名為:"0"、"mainlayer"和"anotherlayer"。需要注意的是,在寫layers的時候你需要指明總共會需要多少個layers。Layer "0"是一個默認的layer,不能省略。

 1 int numberOfLayers = 3;
 2 
 3 dw->tableLayers(numberOfLayers);
 4 
 5 dxf.writeLayer(*dw,
 6     DL_LayerData("0", 0),
 7     DL_Attributes(
 8         std::string(""),    // leave empty
 9         DL_Codes::black,    // default color
10         100,                // default width
11         "CONTINUOUS"));     // default line style
12 
13 dxf.writeLayer(*dw,
14     DL_LayerData("mainlayer", 0),
15     DL_Attributes(
16         std::string(""),
17         DL_Codes::red,
18         100,
19         "CONTINUOUS"));
20 
21 dxf.writeLayer(*dw,
22     DL_LayerData("anotherlayer", 0),
23     DL_Attributes(
24         std::string(""),
25         DL_Codes::black,
26         100,
27         "CONTINUOUS"));
28 
29 dw->tableEnd();

 

默認的line width單位為1/100mm。DL_Codes命名空間的color枚舉(enum)類型定義了許多常見的顏色。

4.3.5 寫其他的Tables

這些tables並不是必須的。如果像了解具體細節,可以參考DXF文檔。

1 dxf.writeStyle(*dw);
2 dxf.writeView(*dw);
3 dxf.writeUcs(*dw);
4 
5 dw->tableAppid(1);
6 dw->tableAppidEntry(0x12);
7 dw->dxfString(2, "ACAD");
8 dw->dxfInt(70, 0);
9 dw->tableEnd();

 

4.3.6 寫Dimension Styles

Dimension Styles定義了外觀尺度。

dxf.writeDimStyle(*dw,
    arrowSize,
    extensionLineExtension,
    extensionLineOffset,
    dimensionGap,
    dimensionTextSize);

 

4.3.7 寫Block Records

Block records定義了DXF文件中用到的blocks。下面的代碼定義了"myblock1"和"myblock2"兩個blocks。第一行調用是必須的,它打開blocks table,並且可能寫入一些和DXF版本相關的信息。

1 dxf.writeBlockRecord(*dw);
2 dxf.writeBlockRecord(*dw, "myblock1");
3 dxf.writeBlockRecord(*dw, "myblock2");
4 dw->tableEnd();

 

4.3.8 結束Tables Section

dw->sectionEnd();

 

4.4 寫Blocks Section

Blocks section定義了每個block中的一些實體(entities).

 1 dw->sectionBlocks();
 2 
 3 dxf.writeBlock(*dw,
 4     DL_BlockData("*Model_Space", 0, 0.0, 0.0, 0.0));
 5 dxf.writeEndBlock(*dw, "*Model_Space");
 6 
 7 dxf.writeBlock(*dw,
 8     DL_BlockData("*Paper_Space", 0, 0.0, 0.0, 0.0));
 9 dxf.writeEndBlock(*dw, "*Paper_Space");
10 
11 dxf.writeBlock(*dw,
12     DL_BlockData("*Paper_Space0", 0, 0.0, 0.0, 0.0));
13 dxf.writeEndBlock(*dw, "*Paper_Space0");
14 
15 dxf.writeBlock(*dw,
16     DL_BlockData("myblock1", 0, 0.0, 0.0, 0.0));
17 
18 // ...
19 // write block entities e.g. with dxf.writeLine(), ..
20 // ...
21 dxf.writeEndBlock(*dw, "myblock1");
22 
23 dxf.writeBlock(*dw,
24     DL_BlockData("myblock2", 0, 0.0, 0.0, 0.0));
25 
26 // ...
27 // write block entities e.g. with dxf.writeLine(), ..
28 // ...
29 dxf.writeEndBlock(*dw, "myblock2");
30 
31 dw->sectionEnd();

 

4.5 寫Entities Section

Entities section定義了entities的一些信息。下面代碼中的兩個entities使用了它們layer的一些屬性(256 = layer的顏色, -1 = layer的line width, "BYLAYER" = layer的line style)。

 1 dw->sectionEntities();
 2 
 3 // write all your entities..
 4 
 5 dxf.writePoint(*dw,
 6     DL_PointData(10.0, 45.0, 0.0),
 7     DL_Attributes("mainlayer", 256, -1, "BYLAYER"));
 8 
 9 dxf.writeLine(*dw,
10     DL_LineData(25.0, 30.0, 0.0,   // start point
11              100.0, 120.0, 0.0),   // end point
12     DL_Attributes("mainlayer", 256, -1, "BYLAYER"));
13 dw->sectionEnd();

 

4.6 寫Objects Section

dxf.writeObjects(*dw);
dxf.writeObjectsEnd(*dw);

 

4.7 結束並且關閉文件

dw->dxfEOF();
dw->close();
delete dw;

 

附錄參考

[DXF]
http://www.autodesk.com/techpubs/autocad/acad2000/dxf
Autodesk DXF Reference

[CYGWIN]
http://www.cygwin.com
cygwin - a Linux-like environment for Windows.


Generated at Thu Aug 14 14:14:47 2008 by  doxygen 1.5.4


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM