|
头文件xxxx.h:
#pragma once
#include <vector>
using namespace std;
//给所有的点编号,多次出现的点只编一个号,后面用编号来代替点,简化过程
struct PointNum
{
AcGePoint3d pt; //点
int nNum; //编号
};
//相连的点,用编号与编号连表示
struct NumMap
{
int nNum1; //编号
int nNum2; //编号
double dBulge; //凸度
};
//绘制点
struct DrawPoint
{
int nNum; //编号
double dBulge; //到下一点的凸度
};
class UserHelp
{
public:
UserHelp(void);
public:
~UserHelp(void);
private:
//-----------------------------------------------------------------------------
//Summary:找出与这一点相连的下一点,以及与之相连的凸度
//Par:
// nm 相连信息数组
// nThisNum 点编号
// dThisBulge 凸度
// nNextNum 点编号(查找不成功时,为-1)
//Return:
// 查找成功为true,查找不成功为false
//-----------------------------------------------------------------------------
static bool FindNextPointNum(vector<NumMap>& nm, int nThisNum, double& dThisBulge, int& nNextNum);
//-----------------------------------------------------------------------------
//Summary:通过编号查找相应的点
//Par:
// vecPt2Num 点编号数组
// dThisBulge 凸度
// ptThis 对应的点
//Return:
// 查找成功为true,查找不成功为false
//-----------------------------------------------------------------------------
static bool NumToPoint(vector<PointNum>& vecPt2Num, int nThisNum, AcGePoint3d& ptThis);
//-----------------------------------------------------------------------------
//Summary:将实体添加到数据库中
//Par:
// pEnt 实体指针
//Return:
// 返回添加实体ID号
//-----------------------------------------------------------------------------
static AcDbObjectId Append(AcDbEntity* pEnt);
//-----------------------------------------------------------------------------
//Summary:计算圆弧的凸度
//Par:
// pArc 圆弧指针
//Return:
// 返回计算的结果
//-----------------------------------------------------------------------------
static double GetBulge(AcDbArc*& pArc);
//-----------------------------------------------------------------------------
//Summary:得到某两点间的绘制信息,包括点编号,连接信息
//Par:
// vecPt2Num 点编号数组
// vecNumMap 连接信息数组
// nCodeNum 需要编号的第几个点
// ptStart 起点
// ptEnd 终点
// dBulge ptStart到ptEnd的凸度
//Return:
// 无。
//-----------------------------------------------------------------------------
static void GetDrawInfo(vector<PointNum>& vecPt2Num, vector<NumMap>& vecNumMap, int& nCodeNum,
const AcGePoint3d& ptStart, const AcGePoint3d ptEnd, double dBulge);
//-----------------------------------------------------------------------------
//Summary:将直线,圆弧,多段线转化为(合并)多段线
//Par:
// idObjArr 直线,圆弧,多段线的id
// idPolyline 转化后多段线的ID
//Return:
// 转换成功为true,不成功为false。
//-----------------------------------------------------------------------------
public:
static bool ChangeToPolyLine(AcDbObjectIdArray& idObjArr, AcDbObjectId& idPolyline);
};
实现文件xxxx.cpp:
#include "StdAfx.h"
#include "UserHelp.h"
#include <algorithm>
UserHelp::UserHelp(void)
{
}
UserHelp::~UserHelp(void)
{
}
AcDbObjectId UserHelp::Append(AcDbEntity* pEnt)
{
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,
AcDb::kForWrite);
pBlockTable->close();
AcDbObjectId EntId;
pBlockTableRecord->appendAcDbEntity(EntId, pEnt);
pBlockTableRecord->close();
return EntId;
}
double UserHelp::GetBulge(AcDbArc*& pArc)
{
double dStartAngle = pArc->startAngle();
double dEndAngle = pArc->endAngle();
double dAlfa = dEndAngle - dStartAngle;
if (dAlfa < 0.0)//如果终点角度小于起点角度,取补角
{
dAlfa = 2 * PI + dAlfa;
}
double dBulge = 0.0;
dBulge = tan((dAlfa) / 4.0);
return dBulge;
}
bool UserHelp::FindNextPointNum(vector<NumMap>& nm, int nThisNum, double& dThisBulge, int& nNextNum)
{
bool bFind = false;
//以第一个编号给为起点查找
vector<NumMap>::iterator itr;
for (itr = nm.begin(); itr != nm.end(); itr++)
{
if ((*itr).nNum1 == nThisNum)
{
nNextNum = (*itr).nNum2;
dThisBulge = (*itr).dBulge;
bFind = true;
nm.erase(itr);
break;
}
}
if (!bFind)//如果以第一个编号给为起点未找到,就以第二个编号给为起点查找
{
for (itr = nm.begin(); itr != nm.end(); itr++)
{
if ((*itr).nNum2 == nThisNum)
{
nNextNum = (*itr).nNum1;
dThisBulge = -(*itr).dBulge;//凸度取反
bFind = true;
nm.erase(itr);
break;
}
}
}
if (bFind)
{
return true;
}
else
{
nNextNum = -1;
dThisBulge = 0.0;
}
return false;
}
bool UserHelp::NumToPoint(vector<PointNum>& vecPt2Num, int nThisNum, AcGePoint3d& ptThis)
{
bool bFind = false;
vector<PointNum>::iterator itr;
for (itr = vecPt2Num.begin(); itr != vecPt2Num.end(); itr++)
{
if ((*itr).nNum == nThisNum)
{
ptThis = (*itr).pt;
bFind = true;
break;
}
}
return bFind;
}
void UserHelp::GetDrawInfo(vector<PointNum>& vecPt2Num, vector<NumMap>& vecNumMap, int& nCodeNum,
const AcGePoint3d& ptStart, const AcGePoint3d ptEnd, double dBulge)
{
bool bStartNew = true; //起点是否编号
bool bEndNew = true; //终点是否编号
NumMap nummap;//两点之间的联系信息
nummap.dBulge = dBulge;
//处理起点
vector<PointNum>::iterator itr;
for (itr = vecPt2Num.begin(); itr != vecPt2Num.end(); itr++)
{
if ((*itr).pt == ptStart)
{
bStartNew = false;
nummap.nNum1 = (*itr).nNum;
break;
}
}
if (bStartNew)
{
PointNum pn;
pn.nNum = nCodeNum++;
pn.pt = ptStart;
vecPt2Num.push_back(pn);
nummap.nNum1 = pn.nNum;
}
//处理终点
for (itr = vecPt2Num.begin(); itr != vecPt2Num.end(); itr++)
{
if ((*itr).pt == ptEnd)
{
bEndNew = false;
nummap.nNum2 = (*itr).nNum;
break;
}
}
if (bEndNew)
{
PointNum pn;
pn.nNum = nCodeNum++;
pn.pt = ptEnd;
vecPt2Num.push_back(pn);
nummap.nNum2 = pn.nNum;
}
//添加联系信息
vecNumMap.push_back(nummap);
}
bool UserHelp::ChangeToPolyLine(AcDbObjectIdArray& idObjArr, AcDbObjectId& idPolyline)
{
vector<PointNum> vecPt2Num;//所有点编号
vector<NumMap> vecNumMap;//所有连接信息
int nCodeNum = 0;
int length = idObjArr.length();
for (int i = 0; i < length; i++)
{
// 获得指向当前元素的指针
AcDbEntity *pEnt;
Acad::ErrorStatus es = acdbOpenAcDbEntity(pEnt, idObjArr.at(i),
AcDb::kForRead);
// 选择到作为边界的多段线了,直接跳过该次循环
if (es != Acad::eOk)
{
continue;
}
if(pEnt->isKindOf(AcDbArc::desc()))//圆弧
{
AcDbArc* pArc = AcDbArc::cast(pEnt);
if (pArc == NULL)
{
continue;
}
AcGePoint3d ptStart, ptEnd;
pArc->getStartPoint(ptStart);
pArc->getEndPoint(ptEnd);
double dBulge = 0.0;
dBulge = UserHelp::GetBulge(pArc);
UserHelp::GetDrawInfo(vecPt2Num, vecNumMap, nCodeNum, ptStart, ptEnd, dBulge);
pArc->close();
}
else if (pEnt->isKindOf(AcDbLine::desc()))//直线
{
AcDbLine* pLine = AcDbLine::cast(pEnt);
if (pLine == NULL)
{
continue;
}
AcGePoint3d ptStart, ptEnd;
pLine->getStartPoint(ptStart);
pLine->getEndPoint(ptEnd);
double dBulge = 0.0;
UserHelp::GetDrawInfo(vecPt2Num, vecNumMap, nCodeNum, ptStart, ptEnd, dBulge);
pLine->close();
}
else if (pEnt->isKindOf(AcDbPolyline::desc()))
{
AcDbPolyline* pPolyLine = AcDbPolyline::cast(pEnt);
if (pPolyLine == NULL)
{
continue;
}
int nVerCount = 0;
nVerCount = pPolyLine->numVerts();
if (nVerCount <= 1)
{
continue;
}
AcGePoint3d ptFirst;
double dBugle = -1000.0;
pPolyLine->getPointAt(0, ptFirst);
pPolyLine->getBulgeAt(0,dBugle);
for (int i = 1; i < nVerCount; i++)
{
AcGePoint3d ptVer;
pPolyLine->getPointAt(i, ptVer);
UserHelp::GetDrawInfo(vecPt2Num, vecNumMap, nCodeNum, ptFirst, ptVer, dBugle);
ptFirst = ptVer;
pPolyLine->getBulgeAt(i, dBugle);
}
pPolyLine->close();
}
pEnt->close();
}
AcGePoint3d pt1, pt2;
double dBulge = 0.0;
vector<NumMap>::iterator itr1;// vecNumMap;
vector<NumMap>::iterator itr2;// vecNumMap;
vector< vector<DrawPoint> > vecLines;
if (vecNumMap.size() > 0)
{
itr1 = vecNumMap.begin();
}
while(itr1 != vecNumMap.end())
{
//从某点出发向一个方向搜索
vector<DrawPoint> vecOneLine;
int nBegin = (*itr1).nNum1;
int nThisNum = nBegin;
int nLastNum = nThisNum;
DrawPoint drawpoint;
while(vecNumMap.size() > 0)
{
bool bSuc = false;
double dThisBulge = 0.0;
int nNextNum = 0;
bSuc = UserHelp::FindNextPointNum(vecNumMap, nThisNum, dThisBulge, nNextNum);
if (bSuc)
{
drawpoint.nNum = nThisNum;
drawpoint.dBulge =dThisBulge;
vecOneLine.push_back(drawpoint);
nThisNum = nNextNum;
nLastNum = nThisNum;
}
else
{
break;
}
}
//处理最近一个点
drawpoint.nNum = nLastNum;
drawpoint.dBulge = 0.0;
vecOneLine.push_back(drawpoint);
//从某点出发向另一个方向搜索
vector<DrawPoint> vecOtherLine;
nThisNum = nBegin;
nLastNum = nThisNum;
while(vecNumMap.size() > 0)
{
bool bSuc = false;
double dThisBulge = 0.0;
int nNextNum = 0;
bSuc = UserHelp::FindNextPointNum(vecNumMap, nThisNum, dThisBulge, nNextNum);
if (bSuc)
{
drawpoint.nNum = nNextNum;
drawpoint.dBulge =dThisBulge;
vecOtherLine.push_back(drawpoint);
nThisNum = nNextNum;
}
else
{
break;
}
}
//两个方向拼接
reverse(vecOtherLine.begin(), vecOtherLine.end());
vector<DrawPoint>::iterator itrTmp;
for (itrTmp = vecOtherLine.begin(); itrTmp != vecOtherLine.end(); itrTmp++)
{
(*itrTmp).dBulge *= -1.0;
}
vecOtherLine.insert(vecOtherLine.end(), vecOneLine.begin(), vecOneLine.end());
vecLines.push_back(vecOtherLine);
itr1 = vecNumMap.begin();
}
//绘制多段线
vector< vector<DrawPoint> >::iterator itr_1;
vector<DrawPoint>::iterator itr_2;
for (itr_1 = vecLines.begin(); itr_1 != vecLines.end(); itr_1++)
{
AcDbPolyline* pPolyLine = new AcDbPolyline;
int i = 0;
vector<DrawPoint>& vecPoints = (*itr_1);
for (itr_2 = vecPoints.begin(); itr_2 != vecPoints.end(); itr_2++)
{
int nNum = (*itr_2).nNum;
AcGePoint3d ptVer;
if (UserHelp::NumToPoint(vecPt2Num, nNum, ptVer))
{
pPolyLine->addVertexAt(i++, ptVer.convert2d(AcGePlane::kXYPlane),(*itr_2).dBulge);
}
}
idPolyline = UserHelp::Append(pPolyLine);
pPolyLine->close();
}
return true;
} |
|