找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1068|回复: 4

[ARX函数]:关于将直线圆弧构成polyline的源代码。

[复制链接]
发表于 2009-1-7 08:45:30 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
来到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;
}
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2009-1-8 10:16:53 | 显示全部楼层
正好需要,感谢了!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2009-1-13 09:53:22 | 显示全部楼层
感谢楼主,直接贴出来了
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2009-1-16 10:19:48 | 显示全部楼层
感谢楼主!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2009-4-13 17:12:06 | 显示全部楼层
好人一个
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-9-24 08:32 , Processed in 0.451995 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表