zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    519,伪类和伪元素的区别
    518,自定义字体的使用场景
    517,sytlus/sass/less的区别
    516,base64的原理及优缺点
    515,前端性能优化--减少http请求(待补充)
    514 ,css不同选择器的权重(css层叠的规则)
    513,如果需要手写动画,你认为最小时间间隔是多久,为什么?
    512,a标签的target属性
    511,display:inline-block什么时候不会显示间隙?
    510,position的值,relative和absolute定位原点是
  • 原文地址:https://www.cnblogs.com/liuyunfeifei/p/2794490.html
Copyright © 2011-2022 走看看