上一篇文件中点出了资料获取的途径,这里就要进入具体的读取了。
本人感觉对文件的读取,核心是对文件的语法,语义的解析。语法决定了对文件内容的读取大小,语义则决定了读取内容的含义。这两部分的细节内容都可以在AutoCAD的帮助文档中找到。
首先来说下DXF文件的几个主要的组成大块。
在DXF文件中,各个段是按顺序排列好的,段的基本格式大概如下:
0
SECTION //开始
2
CLASSES //段名,如HEADER、CLASSES……等
/******************/ //其中就是段的内容了
*
*
*
/******************/
0ENDSEC //段结束
在DXF文件中基本都是2行为一个组合,第一行为数字,叫组码;第二行就很复杂了,叫组码值。具体含义可以查看文档说明。
由于本人的项目需求主要是读取DXF数据内容,所以只要对TABLES段和ENTITIES段进行解析就可以了。
其他部分就忽略,如果要进行写操作,那么就得都解析了。
先说TABLES段,里面有很多内容
TABLES段的组成大概如下
0
SECTION
2
TABLES //TABLES 段的开始
0
TABLE //通用表组码;为每个条目重复一次
2
<表类型> //APPID、LAYER、LTYPE等
5
<句柄>
100
AcDbSymbolTable
70
<最大条目数量> //这个TABLE中所含的表中条目的数量
//下面开始罗列表中的所有条目具体信息
0
<表类型> //表条目数据;为每个表记录重复一次
5
<句柄>
100
AcDbSymbolTableRecord
.
. <数据>
.
0
ENDTAB //TABLE结束
0
ENDSEC //段结束 (TABLES结束)
本人只需要层信息,只需要解析其中LAYER块就可以了。LAYER组码说明
在CAD中建立如下的层
DXF文件中LAYER表的数据如下
0
TABLE
2
LAYER
5
2
102
{ACAD_XDICTIONARY
360
1FF
102
}
330
0
100
AcDbSymbolTable
70
4
0
LAYER
5
10
102
{ACAD_XDICTIONARY
360
13C
102
}
330
2
100
AcDbSymbolTableRecord
100
AcDbLayerTableRecord
2
0
70
0
62
5
6
Continuous
370
-3
390
F
0
LAYER
5
25E
330
2
100
AcDbSymbolTableRecord
100
AcDbLayerTableRecord
2
测试1
70
0
62
3
6
Continuous
370
-3
390
F
1001
AcAecLayerStandard
1000
1000
1001
AcCmTransparency
1071
0
0
LAYER
5
261
330
2
100
AcDbSymbolTableRecord
100
AcDbLayerTableRecord
2
测试2
70
0
62
2
6
Continuous
370
-3
390
F
1001
AcAecLayerStandard
1000
1000
1001
AcCmTransparency
1071
0
0
LAYER
5
262
330
2
100
AcDbSymbolTableRecord
100
AcDbLayerTableRecord
2
测试3
70
0
62
1
6
Continuous
370
-3
390
F
1001
AcAecLayerStandard
1000
1000
1001
AcCmTransparency
1071
0
0
ENDTAB
上面内容只需要获取层数,层名称就可以了。这个数据将在图元中使用。
下面是一段读取LAYER层数据,并保存到全局变量的函数
int AssistLayer_DXF(std::ifstream& ifsSur)
{
std::string strKey, strData;
while (1)
{
std::getline(ifsSur, strKey);
if(ifsSur.eof()) break;
g_VectFileStrData.push_back(strKey);
strKey.erase(std::remove(strKey.begin(), strKey.end(), ' '), strKey.end());
std::getline(ifsSur, strData);
if(ifsSur.eof()) break;
g_VectFileStrData.push_back(strData);
strData.erase(std::remove(strData.begin(), strData.end(), ' '), strData.end());
if (("0" == strKey)&&("ENDTAB" == strData))
return 2;
if (("0" == strKey)&&("LAYER" == strData))
break;
if ("EOF" == strData)
return 1;
if ("2" == strKey)
{
DxfTool temToolDxf; //层工具结构体
temToolDxf.iIndex = g_VectTool.size();
temToolDxf.strName = strData;
g_VectDxfTool.push_back(temToolDxf);}
}
return 0;
}