注册 登录
明经CAD社区 返回首页

风树的个人空间 http://www.mjtd.com/?408117 [收藏] [复制] [分享] [RSS]

日志

关于arx提取填充边界的问题

已有 1036 次阅读2013-12-20 22:16 |系统分类:应用

 提取填充图案边界线,从arx2008到2012都存在一个有趣的问题。

代码逻辑上暂时没发现有问题,但当填充图案是使用框选边界生成,含有两个以上的圆弧,形状如下图时,提取将会失败。

原因是代码中AcDbArc *pArc = new AcDbArc(geCenter, dRadius, dStartAng, dEndAng)”的部分,当碰到这种情况,有可能有圆弧不能正确生成。
换成“AcDbArc *pArc = new AcDbArc(pGeArc ->center(), pGeArc->radius(), pGeArc->startAng(), pGeArc->endAng())”时也是不行。
只能变通点,按以下方式提取,在重塑边界时排除其中的悬挂线才能解决。
pArc = new AcDbArc(pGeArc->center(),pGeArc->normal(),pGeArc->radius(),pGeArc->startAng(),pGeArc->endAng());
pArc = new AcDbArc(pGeArc->center(),-pGeArc->normal(),pGeArc->radius(),-pGeArc->endAng(),-pGeArc->startAng());

圆弧构造函数也就那几个,按定义应该正确生成的,挺怪的。(补充:正确的实现见令一贴子)


原始代码粘贴如下:
//
// ObjectARX defined commands, created by Bill Zhang [2003-2-20], DevTech, Autodesk

#include "StdAfx.h"
#include "StdArx.h"

/////////////////////////////////////////////////////////////////////////////////////////
//        A utility for regenerating the boundaries of a hatch entity if they are lost.
/////////////////////////////////////////////////////////////////////////////////////////

// append an entity to the current space of AutoCAD database
void addAEntToTheCurrentSpaceAndClose(AcDbEntity* pEnt)
{
        AcDbBlockTableRecord *pBlkRec;
        AcDbObjectId objID;
        acdbOpenObject(pBlkRec, acdbCurDwg()->currentSpaceId(), AcDb::kForWrite);
        pBlkRec->appendAcDbEntity (objID, pEnt) ;                        
        pEnt->close();
        pBlkRec->close();
}

//-----------------------------------------------------------------------------
// This is command 'RESTOREHATCHBOUNDARY, by Bill Zhang [2003-2-20], DevTech, Autodesk
void BzhRestoreHatchBoundary()
{
#ifdef OARXWIZDEBUG
        acutPrintf ("\nOARXWIZDEBUG - BzhRestoreHatchBoundary() called.");
#endif // OARXWIZDEBUG

        // TODO: Implement the command
        // create a resbuf which is filled with filter conditions.
  struct resbuf *filter = acutBuildList(RTDXF0, "HATCH", RTNONE);
  ads_name ss;
  // ask users to select hatch entities.
  int res = acedSSGet(NULL, NULL, NULL, filter, ss);
  // release filter resbuf.
  acutRelRb (filter);
  if( res != RTNORM )
  {
          acutPrintf("\nNo hatch entities selected!");
          return;
  }

  long length=0l;
  acedSSLength (ss, &length);
  for(long indexSS=0l; indexSS<length; indexSS++)
  {
        ads_name eName;
        res = acedSSName(ss, indexSS, eName);
    if( res != RTNORM )
                continue;

        AcDbObjectId id;  
        acdbGetObjectId(id, eName );
        AcDbHatch*pHatch=NULL;   
        acdbOpenObject(pHatch, id, AcDb::kForRead );
        if( pHatch == NULL ) 
        continue;

        // For each loop, draw the boundary.
        int nLoops = pHatch->numLoops();
        for( int i=0;i<nLoops; i++ ) 
        {
                long loopType;
                if( pHatch->loopTypeAt( i ) & AcDbHatch::kPolyline ) 
                {         
                        AcGePoint2dArray vertices;
                        AcGeDoubleArray bulges;
                        pHatch->getLoopAt( i, loopType, vertices, bulges );    
                        int nVertices = vertices.length();
                        AcDbPolyline *pPoly = new AcDbPolyline(nVertices); 
                        for( int vx=0;vx<nVertices;vx++ ) 
                        {
                                double bulge = bulges.length() < nVertices ? 0.0: bulges[vx];
                                pPoly->addVertexAt( vx, vertices[vx], bulge );
                        }   
                        // append it to the current space of AutoCAD database
                        pPoly->setColorIndex(1);
                        addAEntToTheCurrentSpaceAndClose(pPoly);
                }      
                else 
                {         
                        AcGePoint2dArray vertices;
                        AcGeDoubleArray bulges;
                        AcGeVoidPointerArray edgePtrs; 
                        AcGeIntArray edgeTypes;  
                        pHatch->getLoopAt(i, loopType,edgePtrs, edgeTypes ); 
                        for(int j=0; j<edgePtrs.length(); j++)
                        {
                                switch (edgeTypes[j]){
                                case AcDbHatch::kLine:
                                        {
                                                AcGeLineSeg3d *pGeLine3d = (AcGeLineSeg3d*)edgePtrs[j];
                                                AcGePoint3d geP1, geP2;
                                                geP1 = pGeLine3d->startPoint();
                                                geP2 = pGeLine3d->endPoint();
                                                AcDbLine *pLine = new AcDbLine(geP1, geP2);
                                                pLine->setColorIndex(1);
                                                addAEntToTheCurrentSpaceAndClose(pLine);
                                        }
                                        break;
                                case AcDbHatch::kCirArc:
                                        {
                                                AcGePoint3d geCenter;
                                                double dRadius, dStartAng, dEndAng;
                                                AcGeCircArc3d *pGeArc = (AcGeCircArc3d*)edgePtrs[j];
                                                geCenter = pGeArc->center();
                                                dRadius = pGeArc->radius();
                                                dStartAng = pGeArc->startAng();
                                                dEndAng = pGeArc->endAng();
                                                double dAngDiff;
                                                dAngDiff = fabs( dEndAng - dStartAng - atan(1)*8 );
                                                if( dAngDiff > 1e-5 ) // It's an ARC. 
                                                {
                                                        AcDbArc *pArc = new AcDbArc(geCenter, dRadius, dStartAng, dEndAng);
                                                        pArc->setColorIndex(1);
                                                        addAEntToTheCurrentSpaceAndClose(pArc);
                                                }
                                                else        // It's a circle.
                                                {
                                                        AcGeVector3d geNorm = pGeArc->normal();
                                                        AcDbCircle *pCir = new AcDbCircle(geCenter, geNorm, dRadius);
                                                        pCir->setColorIndex(1);
                                                        addAEntToTheCurrentSpaceAndClose(pCir);
                                                }
                                        }
                                        break;
                                case AcDbHatch::kEllArc:
                                        {
                                                AcGePoint3d geCenter;
                                                AcGeVector3d geNorm,dMajorAxis, dMinorAxis;
                                                double dMajorRadius, dMinorRadius;
                                                double dStartAng, dEndAng;
                                                AcGeEllipArc3d *pGeEllip = (AcGeEllipArc3d*)edgePtrs[j];
                                                geCenter = pGeEllip->center();
                                                dStartAng = pGeEllip->startAng();
                                                dEndAng = pGeEllip->endAng();
                                                geNorm = pGeEllip->normal();
                                                dMajorAxis = pGeEllip->majorAxis();
                                                dMinorAxis = pGeEllip->minorAxis();
                                                dMajorRadius = pGeEllip->majorRadius();
                                                dMinorRadius = pGeEllip->minorRadius();
                                                AcDbEllipse *pEllip = new AcDbEllipse();
                                                // Note: radiusRatio = dMinorRadius/dMajorRadius (must be within [0, 1]) 
                                                pEllip->set(geCenter,geNorm,dMajorAxis*dMajorRadius,dMinorRadius/dMajorRadius);
                                                pEllip->setStartParam(dStartAng);
                                                pEllip->setEndParam(dEndAng);
                                                if( pEllip->isNull() == Adesk::kTrue)
                                                {
                                                        acutPrintf("\nFailed to create an ellipse.");
                                                        break;
                                                }
                                                else
                                                {
                                                        pEllip->setColorIndex(1);
                                                        addAEntToTheCurrentSpaceAndClose(pEllip);
                                                }
                                        }
                                        break;
                                case AcDbHatch::kSpline:
                                        {
                                                Adesk::Boolean bIsFixSpline;
                                                AcGePoint3dArray fitPoints;
                                                AcGeTol fitTol;
                                                Adesk::Boolean bTangentsExist;
                                                AcGeVector3d startTangent, endTangent;
                                                int deg;
                                                AcGeNurbCurve3d  *pGeSpline=(AcGeNurbCurve3d *)edgePtrs[j];
                                                assert(pGeSpline);
                                                deg = pGeSpline->degree();
                                                bIsFixSpline = pGeSpline->getFitData(fitPoints,
                                                                                                                        fitTol,
                                                                                                                        bTangentsExist,
                                                                                                                        startTangent,
                                                                                                                        endTangent);
                                                if( bIsFixSpline == Adesk::kTrue )
                                                {
                                                        AcDbSpline *pSpline=new AcDbSpline();
                                                        pSpline->setFitData(fitPoints,
                                                                                                deg,
                                                                                                fitTol.equalVector(),
                                                                                                startTangent,
                                                                                                endTangent);
                                                        if( pSpline->isNull() == Adesk::kTrue)
                                                        {
                                                                acutPrintf("\nFailed to create a spline.");
                                                                break;
                                                        }
                                                        else
                                                        {
                                                                pSpline->setColorIndex(1);
                                                                addAEntToTheCurrentSpaceAndClose(pSpline);
                                                        }
                                                }
                                                else
                                                {
                                                        Adesk::Boolean rational,closed,periodic;
                                                        AcGePoint3dArray gePoints;
                                                        AcGeDoubleArray geWeights;
                                                        AcGePoint3d gePoint;
                                                        AcGeKnotVector geKnots;        
                                                        AcGeDoubleArray dKnots;

                                                        rational = pGeSpline->isRational();
                                                        closed = pGeSpline->isClosed();
                                                        periodic = Adesk::kFalse;
                                                        for(int k=0; k<pGeSpline->numControlPoints(); k++)
                                                        {
                                                                gePoints.append(pGeSpline->controlPointAt(k));
                                                        }
                                                        for(k=0; k<pGeSpline->numWeights(); k++)
                                                        {
                                                                geWeights.append(pGeSpline->weightAt(k));
                                                        }
                                                        geKnots = pGeSpline->knots();                                                        
                                                        for(k=0; k<geKnots.length(); k++)
                                                        {
                                                                dKnots.append(geKnots[k]);
                                                        }

                                                        AcDbSpline *pSpline=new AcDbSpline(deg,
                                                                                        rational,
                                                                                        closed,
                                                                                        periodic,
                                                                                        gePoints,
                                                                                        dKnots,
                                                                                        geWeights);
                                                        if( pSpline->isNull() == Adesk::kTrue)
                                                        {
                                                                acutPrintf("\nFailed to create a spline.");
                                                                break;
                                                        }
                                                        else
                                                        {
                                                                pSpline->setColorIndex(1);
                                                                addAEntToTheCurrentSpaceAndClose(pSpline);
                                                        }
                                                }
                                        }
                                        break;
                                default:
                                        break;
                                }
                        }
                }
        }
        pHatch->close(); 
  }

  // free up the selection set
  acedSSFree (ss);
}


路过

雷人

握手

鲜花

鸡蛋

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-5-11 01:53 , Processed in 0.089705 second(s), 15 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

返回顶部