自己写的dxf格式(R12/LT2)文本手动解析。
dxf格式(R12/LT2),用记事本等文本编辑器打开,类似于下面这种
通过分析文本特点进行解析,提取多边形信息。
直接上代码:
#pragma once
#include "StdStrFile.h"
typedef struct _cadPtInfo
{
std::string strLayerName;
double x;
double y;
double z;
_cadPtInfo(const double& _x = 0.0, const double& _y = 0.0, const double& _z = 0.0, const std::string& _layerName = "")
{
x = _x;
y = _y;
z = _z;
strLayerName = _layerName;
}
}cadPtInfo;
class cadPolyInfo
{
public:
std::string strName;
std::string strLayerName;
std::vector<cadPtInfo> vPts;
public:
int SaveAsRrlx(const std::string& _strDirPath, const std::string _strName = "");
};
int ReadDxfPolys(const char* szDxfPath, const char* szLayerName, std::vector<cadPolyInfo>& vPolys, bool bIndexName = false);
int SaveDxfPolys(const char* szDirPath, std::vector<cadPolyInfo>& vPolys);
接着是cpp文件:
#include "ReadPolys.h"
//内部使用,外部不使用
typedef struct _cadPt
{
std::string strLayerName;
std::vector<double> vPts;
_cadPt()
{
}
}_innerCadPt;
int ReadDxfPolys(const char* szDxfPath, const char* szLayerName, std::vector<cadPolyInfo>& vPolys, bool bIndexName/* = false*/)
{
std::vector<std::string> vDxfContents;
size_t nLineNum = CStdFile::ParseTXTFile(szDxfPath, vDxfContents);
if (nLineNum == 0)
{
return -1;
}
for (size_t i = 0; i < nLineNum; ++i)
{
const std::string strCurLine = vDxfContents[i];
//判断坐标内容
if (strCurLine == "POLYLINE")
{
//开始寻找多边形
cadPolyInfo poly;
for (size_t j = i + 1; j < nLineNum; ++j)
{
const std::string strCurLineSub = vDxfContents[j];
if (strCurLineSub == "EOF")
{
//最后一个多边形已经结束
poly.strName = vDxfContents[j - 4];
break;
}
if (strCurLineSub == "POLYLINE")
{
//当前多边形已经结束
poly.strName = vDxfContents[j - 2];
i = --j;
break;
}
if (strCurLineSub == szLayerName)
{
_innerCadPt pt;
for (size_t k = j +1; k < nLineNum; ++k)
{
//此时开始读取接下来的行,并且不超过总行数
double dCoor = 0.0;
if (CStdTpl::ConvertFromString(dCoor, vDxfContents[k]) == nullptr)
{
pt.vPts.clear();
break;
}
else
{
pt.vPts.push_back(dCoor);
}
if (pt.vPts.size() == 5)
{
size_t nNextLineIndex = k + 1;
if (nNextLineIndex < nLineNum && CStdTpl::ConvertFromString(dCoor, vDxfContents[nNextLineIndex]) == nullptr)
{
pt.strLayerName = szLayerName;
}
break;
}
}
//判断当前读取的是否是坐标
if (pt.vPts.size() == 5 && fabs(pt.vPts[0] - 10.0) < 1e-6 && fabs(pt.vPts[2] - 20.0) < 1e-6)
{
cadPtInfo ptinfo;
ptinfo.strLayerName = pt.strLayerName;
ptinfo.x = pt.vPts[1];
ptinfo.y = pt.vPts[3];
ptinfo.z = pt.vPts[4];
poly.vPts.push_back(ptinfo);
i = ++j;
}
}
}
//添加最终结果,如果没有层名,则添加索引层名
if (bIndexName)
{
static int nIndex = 0;
poly.strName = CStdTpl::ConvertToString(nIndex++);
}
vPolys.push_back(poly);
}
}
return 0;
}
int SaveDxfPolys(const char* szDirPath, std::vector<cadPolyInfo>& vPolys)
{
size_t nPolyNum = vPolys.size();
for (size_t i = 0; i < nPolyNum; ++i)
{
vPolys[i].SaveAsRrlx(szDirPath);
}
return (int)nPolyNum;
}
int cadPolyInfo::SaveAsRrlx(const std::string& _strDirPath, const std::string _strName /*= ""*/)
{
std::string strSaveName(_strName);
if (strSaveName.length() == 0)
{
if (strName.length() > 0)
{
strSaveName = strName;
}
else
{
static int nNum;
strName = CStdTpl::ConvertToString(nNum++);
}
}
//如果后缀不是.rrlx则添加后缀
std::string strSuffix = CStdStr::ToUpperLower(CStdStr::GetSuffixOfFile(strSaveName));
if (strSuffix != ".rrlx")
{
strSaveName += ".rrlx";
}
std::string strSavePath = CStdStr::AddSlashIfNeeded(_strDirPath) + strSaveName;
std::vector<std::string> vSaveContent;
size_t nPtNum = vPts.size();
//首先添加点的个数
vSaveContent.push_back(CStdTpl::ConvertToString(nPtNum) + '\n');
//添加点的坐标
for (size_t i = 0; i < nPtNum; ++i)
{
const cadPtInfo& pt = vPts[i];
std::string strLine = ToString(pt.x) + '\t' + ToString(pt.y) + '\t' + '0';
vSaveContent.push_back(strLine + '\n');
}
CStdFile::SaveTXTFile(strSavePath, vSaveContent);
return 0;
}
更多的交流,欢迎留言。