- UID
- 5126
- 积分
- 0
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2002-5-16
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
来到xdcad,收益颇多。看到许多朋友提到将直线圆弧构成polyline的问题,也将自己以前做的程序贴上,虽然写的龌龊,但若能参考其中一二,也算是一点贡献。欢迎指正。
注释是我临时添加的,原是日文。
//EntityInClassification函数功能遍历当前某图层上的所有实体,并将其分类。其中,圆放入CirArray,顶点互不相连直线或圆弧放入ptrArray,用顶点相连的直线或圆弧构成的polyline放入
//PolyArray,LayerId为层AcDbObjectId。
AcGeTol tol;
//tol.setEqualPoint(0.0001);
//tol.setEqualVector(0.0001);
int CdataPalette::EntityInClassification(const AcDbObjectId LayerId,AcDbVoidPtrArray &CirArray,AcDbVoidPtrArray& ptrArray,AcDbVoidPtrArray& PolyArray)
{
AcDbVoidPtrArray ArcLineArray;
AcGePoint3dArray StPAry;
AcGePoint3dArray EdPAry;
AcDbBlockTable* pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable,AcDb::kForWrite);
AcDbBlockTableRecord* pBlkTbeRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE,pBlkTbeRecord,AcDb::kForWrite);
pBlockTable->close();
AcDbBlockTableRecordIterator* pRcdIterator;
pBlkTbeRecord->newIterator(pRcdIterator);
pBlkTbeRecord->close();
for(pRcdIterator->start();(!pRcdIterator->done());pRcdIterator->step())
{
AcDbEntity *pEntity;
pRcdIterator->getEntity(pEntity,AcDb::kForWrite);
if(pEntity->layerId() == LayerId)
{
if(pEntity->isKindOf(AcDbArc::desc())||pEntity->isKindOf(AcDbLine::desc()))
{
ArcLineArray.append(pEntity);
}
if(pEntity->isKindOf(AcDbPolyline::desc()))
{
PolyArray.append(pEntity);
}
if(pEntity->isKindOf(AcDbCircle::desc()))
{
CirArray.append(pEntity);
}
}
pEntity->close();
}
delete pRcdIterator;
//3条或3条以上圆弧或直线的顶点交于一点时,拆除其中一条,并将其放入单直线圆弧组ptrArray
for(int i2 = 0; i2 < ArcLineArray.logicalLength();)
{
int j2 = 0;
int j3 = 0;
AcDbCurve *pCurve0;
pCurve0 = (AcDbCurve*)ArcLineArray[i2];
AcGePoint3d pS00,pE00;
pCurve0->getStartPoint(pS00);
pCurve0->getEndPoint(pE00);
pCurve0->close();
for(int i3 = i2 + 1; i3 < ArcLineArray.logicalLength();i3++)
{
AcDbCurve *pCurve1;
pCurve1 = (AcDbCurve*)ArcLineArray[i3];
AcGePoint3d pS10,pE10;
pCurve1->getStartPoint(pS10);
pCurve1->getEndPoint(pE10);
pCurve1->close();
if(pS00.isEqualTo(pS10,tol)||pS00.isEqualTo(pE10,tol))
{
j2++;
}
else if(pE00.isEqualTo(pS10,tol)||pE00.isEqualTo(pE10,tol))
{
j3++;
}
}
if((j2 > 1)||(j3 > 1))
{
ptrArray.append((AcDbEntity*)ArcLineArray[i2]);
ArcLineArray.removeAt(i2);
i2 = 0;
}
else
{
i2 ++;
}
}
//线,圆弧组空时返回0,为1时将放入单直线圆弧组ptrArray
int i0,j0;
AcGePoint3d StPtemp,EdPtemp,initP;
AcDbVoidPtrArray ptrTempArray(ArcLineArray);
ArcLineArray.setLogicalLength(0);
if(ptrTempArray.logicalLength() == 0)return 0;
if(ptrTempArray.logicalLength() == 1)
{
ptrArray.append(ptrTempArray[0]);
ptrTempArray.setLogicalLength(0);
return 0;
}
//将首尾相连的直线或圆弧放入TempPolyArray
AcDbVoidPtrArray TempPolyAry;
TempPolyAry.append(ptrTempArray[0]);
ptrTempArray.removeAt(0);
for(i0 = 0;0 < ptrTempArray.logicalLength();)
{
AcDbCurve *pCirOrLine;
pCirOrLine = (AcDbCurve*)TempPolyAry[i0];
AcGePoint3d pStart0,pEnd0;
pCirOrLine->getStartPoint(pStart0);
pCirOrLine->getEndPoint(pEnd0);
bool bLoop = true;
bool leftOk = true,Right = true;
for(j0 = 0;bLoop&&(j0 < ptrTempArray.logicalLength());)
{
AcGePoint3d pStart1,pEnd1;
AcDbCurve* kCurve = (AcDbCurve*)ptrTempArray[j0];
kCurve->getStartPoint(pStart1);
kCurve->getEndPoint(pEnd1);
if (leftOk&&(pStart0.isEqualTo(pStart1,tol)||pStart0.isEqualTo(pEnd1,tol)))
{
TempPolyAry.append(kCurve);
ptrTempArray.removeAt(j0);
leftOk = false;
}
else if(Right&&(pEnd0.isEqualTo(pStart1,tol)||pEnd0.isEqualTo(pEnd1,tol)))
{
TempPolyAry.append(kCurve);
ptrTempArray.removeAt(j0);
Right = false;
}
else
{
j0++;
}
if(j0 == (ptrTempArray.logicalLength()))
bLoop = Right&&leftOk;
kCurve->close();
}
if((bLoop&&(i0 == (TempPolyAry.logicalLength()-1)))||ptrTempArray.logicalLength() == 0)
{
//TempPolyArray长度大于1时,调用CirLineToPoly函数将其转化成polyline
if(TempPolyAry.logicalLength() > 1)
{
AcDbPolyline* tempPoly = new AcDbPolyline();
CirLineToPoly(TempPolyAry,tempPoly);
tempPoly->setColorIndex(2);
tempPoly->setLayer(ThinLayerId);
PolyArray.append(tempPoly);
tempPoly->close();
AcDbObjectId id0;
addToModelSpace(id0,tempPoly);
TempPolyAry.setLogicalLength(0);
if(ptrTempArray.logicalLength() > 0)
{
TempPolyAry.append(ptrTempArray[0]);
ptrTempArray.removeAt(0);
}
}
//TempPolyArray长度等于1时,视为单直线或圆弧
else if(TempPolyAry.logicalLength() == 1)
{
ptrArray.append(pCirOrLine);
TempPolyAry.setLogicalLength(0);
if(ptrTempArray.logicalLength() > 1)
{
TempPolyAry.append(ptrTempArray[0]);
ptrTempArray.removeAt(0);
}
else if(ptrTempArray.logicalLength() == 1)
{
ptrArray.append(ptrTempArray[0]);
ptrTempArray.removeAt(0);
}
}
//TempPolyArray长度等于0时,返回.
else
{
TempPolyAry.setLogicalLength(0);
ptrTempArray.setLogicalLength(0);
pCirOrLine->close();
return 0;
}
i0 = 0;
}
else
{
i0++;
}
pCirOrLine->close();
}
return 1;
}
//
//CirLineToPoly函数功能;用顶点相连的直线或圆弧组CirLinePtrA构成Polyline.
//
int CdataPalette::CirLineToPoly(AcDbVoidPtrArray& CirLinePtrA,AcDbPolyline*& Polyline)
{
AcGePoint3d p1;
AcGePoint3dArray StPAry;
AcGePoint3dArray EdPAry;
AcDbVoidPtrArray ptrArray;
AcGeDoubleArray bulgeArray;
//求出所有直线圆弧顶点
for(int n0 = 0;n0 < CirLinePtrA.logicalLength();n0++)
{
AcDbCurve* pEntity = (AcDbCurve*)CirLinePtrA[n0];
pEntity->getStartPoint(p1);
StPAry.append(p1);
pEntity->getEndPoint(p1);
EdPAry.append(p1);
ptrArray.append(pEntity);
pEntity->close();
}
//组空,则返回0;
if(ptrArray.logicalLength() < 1)
{
return 0;
}
//判断将要组成的polyline的开口形状(始点开口,终点开口,或为封闭),开口时polyline的起始点也必须是开口直线或弧的顶点(始点或终点)
AcGePoint3d StPtemp,EdPtemp,initP;
int i0,j0;
int b0 = -1;
for(int i0 = 0 ; i0 < ptrArray.logicalLength();i0++)
{
AcDbCurve *pFirst;
pFirst = (AcDbCurve *)ptrArray[i0];
AcGePoint3d ps0,pe0,ps1,pe1;
pFirst->getStartPoint(ps0);
pFirst->getEndPoint(pe0);
bool bs = false,br = false;
for(int i1 = 0; i1 < ptrArray.logicalLength();i1++)
{
AcDbCurve *pSec;
pSec = (AcDbCurve *)ptrArray[i1];
pSec->getStartPoint(ps1);
pSec->getEndPoint(pe1);
if(pFirst->objectId() != pSec->objectId())
{
if(ps0.isEqualTo(ps1,tol)||ps0.isEqualTo(pe1,tol))
{
bs = true;
}
}
pSec->close();
}
for(int i1 = 0; i1 < ptrArray.logicalLength();i1++)
{
AcDbCurve *pSec;
pSec = (AcDbCurve *)ptrArray[i1];
pSec->getStartPoint(ps1);
pSec->getEndPoint(pe1);
if(pFirst->objectId() != pSec->objectId())
{
if(pe0.isEqualTo(ps1,tol)||pe0.isEqualTo(pe1,tol))
{
br = true;
}
}
pSec->close();
}
if(!(bs&br))
{
b0 = i0;
if(!br)
{ //终点开口时
initP = EdPAry[b0];
}
else //始点开口时
{
initP = StPAry[b0];
}
break;
}
else //封闭时
{
initP = EdPAry[0];
}
pFirst->close();
}
//从开口直线或圆弧开始逐一有序的将直线或圆弧放入ptrTempArray
AcDbVoidPtrArray ptrTempArray;
for(i0 = 0;i0 < EdPAry.logicalLength();i0=i0)
{
for(j0 = 0;j0 < StPAry.logicalLength();j0++)
{
if(initP.isEqualTo(StPAry[j0],tol)||initP.isEqualTo(EdPAry[j0],tol))
{
AcDbEntity* kCurve = (AcDbEntity*)ptrArray[j0];
if(initP.isEqualTo(EdPAry[j0],tol))
{
//当上一直线或圆弧的终点与下一直线或圆弧的终点相连,则改变下一直线或圆弧的方向,
//以使上一直线圆弧的终点始终与下一直线圆弧的始点相连。同时,为计算bulge作准备
if(kCurve->isKindOf(AcDbLine::desc()))
{
AcDbLine* kLine = (AcDbLine*)ptrArray[j0];
kLine->subOpen(AcDb::kForWrite);
AcGePoint3d kLineinit = AcGePoint3d(0.0001,0.0001,0.2);
AcGePoint3d kLineP = kLine->startPoint();
AcGePoint3d kLinePe = kLine->endPoint();
AcDbLine* kkLine = new AcDbLine(kLinePe,kLineP);
initP = kLineP;
bulgeArray.append(0.0);
ptrTempArray.append(kkLine);
kkLine->close();//
kLine->close();
}
if(kCurve->isKindOf(AcDbArc::desc()))
{
AcGePoint3d kArcSt,kArcEnd;
AcDbArc* kArc = (AcDbArc*)ptrArray[j0];
kArc->getStartPoint(kArcSt);
kArc->getEndPoint(kArcEnd);
double ia = kArc->endAngle();
double ib = kArc->startAngle();
bulgeArray.append(ib - ia);
AcDbArc* kkArc = new AcDbArc(kArc->center(),AcGeVector3d(0,0,-1),kArc->radius(),kArc->endAngle(),kArc->startAngle());
initP = kArcSt;
ptrTempArray.append(kkArc);
kkArc->close();
kArc->close();
}
}
else
{
AcDbEntity* mEntity = (AcDbEntity*)ptrArray[j0];
if(mEntity->isKindOf(AcDbArc::desc()))
{
AcDbArc* newmArc = (AcDbArc*)ptrArray[j0];
bulgeArray.append(newmArc->endAngle() - newmArc->startAngle());
newmArc->close();
}
else
{
bulgeArray.append(0.0);
}
mEntity->close();
ptrTempArray.append(ptrArray[j0]);
initP = EdPAry[j0];
}
StPAry.removeAt(j0);
EdPAry.removeAt(j0);
ptrArray.removeAt(j0);
kCurve->close();
break;
}
}
}
StPAry.setLogicalLength(0);
EdPAry.setLogicalLength(0);
ptrArray.append(ptrTempArray);
ptrTempArray.setLogicalLength(0);
//计算bulge并构成polyline,同时确定是否设成封闭
if(ptrArray.logicalLength() > 0)
{
for(int i0 = 0; i0 < ptrArray.logicalLength();i0++)
{
AcGePoint3d p0;
AcDbEntity* Entityi = (AcDbEntity*)ptrArray[i0];
if(Entityi->isKindOf(AcDbArc::desc()))
{
AcDbArc* arcTemp = (AcDbArc*)ptrArray[i0];
if(0 ==i0)
arcTemp->getStartPoint(p0);
AcGeCircArc2d* AcGeArc = new AcGeCircArc2d(AcGePoint2d(arcTemp->center().x,arcTemp->center().y),arcTemp->radius(),arcTemp->startAngle(),arcTemp->endAngle());//,AcGeVector2d::kXAxis,Adesk::kTrue);
double bulge = 0.0;
double kbulge = bulgeArray[i0];
if(kbulge < 0)
{
kbulge = 2 * PI314 - abs(kbulge);
}
if(-1.0 == arcTemp->normal().z)
{
bulge = -tan(0.25 * (2 * PI314 - kbulge));
}
else
{
bulge = tan(0.25 * kbulge);
}
AcGePoint3d p1;
arcTemp->getEndPoint(p1);
Polyline->addVertexAt(i0,AcGeArc->startPoint(),bulge);
if(i0==((ptrArray.logicalLength()-1)))
{
if(!p0.isEqualTo(p1,tol))
Polyline->addVertexAt(i0+1,AcGePoint2d(AcGeArc->endPoint().x,AcGeArc->endPoint().y));
else
Polyline->setClosed(Adesk::kTrue);
}
delete AcGeArc;
arcTemp->close();
}
if(Entityi->isKindOf(AcDbLine::desc()))
{
AcDbLine* lineTemp = (AcDbLine*)ptrArray[i0];
if(0 ==i0)
lineTemp->getStartPoint(p0);
Polyline->addVertexAt(i0,AcGePoint2d(lineTemp->startPoint().x,lineTemp->startPoint().y));
if(i0==((ptrArray.logicalLength()-1)))
{
Polyline->getPointAt(0,p0);
if(!p0.isEqualTo(lineTemp->endPoint(),tol))
Polyline->addVertexAt(i0+1,AcGePoint2d(lineTemp->endPoint().x,lineTemp->endPoint().y));
else
Polyline->setClosed(Adesk::kTrue);
}
lineTemp->close();
}
Entityi->close();
}
}
bulgeArray.setLogicalLength(0);
ptrArray.setLogicalLength(0);
return 0;
}
//addToModelSpace功能;将实体pEntity放入模型空间
Acad::ErrorStatus CdataPalette::addToModelSpace(AcDbObjectId &objId, AcDbEntity* pEntity)const
{
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,AcDb::kForWrite);
pBlockTable->close();
Acad::ErrorStatus err1;
err1 = pBlockTableRecord->appendAcDbEntity(objId, pEntity);
pBlockTableRecord->close();
pEntity->close();
return err1;
} |
|