dxf格式(R12/LT2)文本手动解析

自己写的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;
}

更多的交流,欢迎留言。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值