admin 发表于 2024-2-23 22:53:07

[研讨] AcDbCurve转换AcGeCurve中的样条化3dpoly

在 AutoCAD 2014 SDK 中 AcDbCurve 提供了 getAcGeCurve() 方法,同时 AcDbCurve::createFromAcGeCurve(), 经测试在 AcDbCurve 是 3dpoly 经过 Pedit S 后,如果使用前者再使用后者添加到数据库后可以生成真正的 Spline,而对 LWPOLYLINE 经过 S 后,生成的曲线和原曲线一致

对 3dpoly 样条化后在 AcDb 时表现为折线模拟,getAcGeCurve()获取的反而是真正的 Spline ,这和 AcDb表现不一致,应该是一个Bugstatic void asdkMyGroupCTest(void)
      {
                ads采用name ent;
                ads采用point pt;
                if(RTNORM != acedEntSel(NULL,ent,pt))
                {
                        return;
                }
                AcDbObjectId id;
                acdbGetObjectId(id,ent);
                AcDbEntityPointer pEnt(id,AcDb::kForRead);
                if (pEnt.openStatus()!=Acad::eOk||!pEnt->isKindOf(AcDbCurve::desc()))
                {
                        return;
                }
                AcDbCurve *pCurve=NULL;
                pCurve=AcDbCurve::cast(pEnt);
                if(pCurve==NULL)
                {
                        return;
                }
                AcGeCurve3d *pGe=NULL;
                Acad::ErrorStatus es=pCurve->getAcGeCurve(pGe);
                pCurve->closes();
                if (es!=Acad::eOk)
                {
                        return;
                }
                AcDbBlockTableRecordPointer btr(curDoc()->database()->currentSpaceId(),AcDb::kForWrite);
                if (btr.openStatus()!=Acad::eOk)
                {
                     delete pGe;
                     return;
                }
                AcDbCurve *pDbCv=NULL;
                es=AcDbCurve::createFromAcGeCurve(*pGe,pDbCv);
                delete pGe;
                if (es!=Acad::eOk)
                {
                        return;
                }         
                btr->appendAcDbEntity(pDbCv);
                pDbCv->close();   
      }

admin 发表于 2024-2-23 22:53:21

// POLYLINE3D ?fit 后是折线模拟
Acad::ErrorStatus Conversion::AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDb3dPolyline * pPoly3d)
{
      AcGePoint3dArray pts;
      AcGePoint3d pt1;
      AcDbObjectId id;
      AcDbVertex *p3dVertex=NULL;
      Acad::ErrorStatus es;
      AcDb3dPolylineVertex *pPoly3dVertex=NULL;
      AcDbObjectIterator* vertexIterator = pPoly3d->vertexIterator();
      for (vertexIterator->start();!vertexIterator==vertexIterator->done();vertexIterator->step())
      {
                id=vertexIterator->objectId();
                es=acdbOpenObject(p3dVertex,id,AcDb::kForRead);
                if (es==Acad::eOk)
                {
                        pPoly3dVertex=AcDb3dPolylineVertex::cast(p3dVertex);
                        if (pPoly3dVertex->vertexType()!=AcDb::k3dControlVertex)
                        {
                              pts.append(pPoly3dVertex->position());
                        }                     
                }
                if (p3dVertex!=NULL)
                {
                        p3dVertex->close();
                }
                if (pPoly3dVertex!=NULL)
                {
                        pPoly3dVertex->close();
                }
      }
      delete vertexIterator;
      if (pPoly3d->isClosed())
      {
                pPoly3d->getStartPoint(pt1);
                pts.append(pt1);
      }
      pGe=new AcGePolyline3d(pts);      
      return Acad::eOk;
}

admin 发表于 2024-2-23 22:53:36

#pragma once
class CConversion
{
public:
      CConversion(void);
      virtual ~CConversion(void);
      static Acad::ErrorStatus AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGeCurve3d * pGe);
      static Acad::ErrorStatus AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbEntity *pEnt);
      static Acad::ErrorStatus AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbCurve *pDbCurve);
private:      
      static Acad::ErrorStatus AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDb2dPolyline *pPoly2d);
      static Acad::ErrorStatus AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDb3dPolyline * pPoly3d);
      static Acad::ErrorStatus AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbPolyline * pPoly);
      static Acad::ErrorStatus AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbSpline * pSpline);
      static Acad::ErrorStatus AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbEllipse * pDb);
      static Acad::ErrorStatus AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbCircle * pDbCircle);
      static Acad::ErrorStatus AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbArc * pDbArc);
      static Acad::ErrorStatus AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbLine * pLine);

      static Acad::ErrorStatus AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGePolyline3d *pGe);
      static Acad::ErrorStatus AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGeCompositeCurve3d * pGe);
      static Acad::ErrorStatus AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGeNurbCurve3d * pGe);
      static Acad::ErrorStatus AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGeEllipArc3d * pGe);
      static Acad::ErrorStatus AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGeCircArc3d * pGe);
      static Acad::ErrorStatus AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGeLineSeg3d * pGe);
};

admin 发表于 2024-2-23 22:54:01

#include "stdafx.h"
#include "CConversion.h"


CConversion::CConversion(void)
{
}

CConversion::~CConversion(void)
{
}
//////////////////////////////////////////////////////////////////////////
// catch all for all other entity types.
Acad::ErrorStatus CConversion::AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbCurve *pDbCurve)
{
      if (pDbCurve->isKindOf(AcDbLine::desc()))
      {
                return AcDbCurveToAcGeCurve(pGe,(AcDbLine *)pDbCurve);
      }
      if (pDbCurve->isKindOf(AcDbArc::desc()))
      {
                return AcDbCurveToAcGeCurve(pGe,(AcDbArc *)pDbCurve);
      }
      if (pDbCurve->isKindOf(AcDbCircle::desc()))
      {
                return AcDbCurveToAcGeCurve(pGe,(AcDbCircle *)pDbCurve);
      }
      if (pDbCurve->isKindOf(AcDbEllipse::desc()))
      {
                return AcDbCurveToAcGeCurve(pGe,(AcDbEllipse *)pDbCurve);
      }
      if (pDbCurve->isKindOf(AcDbSpline::desc()))
      {
                return AcDbCurveToAcGeCurve(pGe,(AcDbSpline *)pDbCurve);
      }
      if (pDbCurve->isKindOf(AcDbPolyline::desc()))
      {
                return AcDbCurveToAcGeCurve(pGe,(AcDbPolyline *)pDbCurve);
      }
      if (pDbCurve->isKindOf(AcDb3dPolyline::desc()))
      {
                return AcDbCurveToAcGeCurve(pGe,(AcDb3dPolyline *)pDbCurve);
      }
      if (pDbCurve->isKindOf(AcDb2dPolyline::desc()))
      {
                return AcDbCurveToAcGeCurve(pGe,(AcDb2dPolyline *)pDbCurve);
      }
      return Acad::eNotImplementedYet;
}
Acad::ErrorStatus CConversion::AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbEntity *pEnt)
{
      if (pEnt->isKindOf(AcDbCurve::desc()))
      {
                return AcDbCurveToAcGeCurve(pGe,(AcDbCurve *)pEnt);
      }
      return Acad::eNotImplementedYet;
}

Acad::ErrorStatus CConversion::AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGeCurve3d * pGe)
{
      AcGe::EntityId type = pGe->type();
      switch (type)
      {
      case AcGe::kLineSeg3d:
                return AcGeCurveToAcDbCurve(pDb,(AcGeLineSeg3d *) pGe);
      case AcGe::kCircArc3d:
                return AcGeCurveToAcDbCurve(pDb,(AcGeCircArc3d *) pGe);
      case AcGe::kEllipArc3d:
                return AcGeCurveToAcDbCurve(pDb,(AcGeEllipArc3d *) pGe);
      case AcGe::kNurbCurve3d:
                return AcGeCurveToAcDbCurve(pDb,(AcGeNurbCurve3d *) pGe);
      case AcGe::kCompositeCrv3d:
                return AcGeCurveToAcDbCurve(pDb,(AcGeCompositeCurve3d*) pGe);
      case AcGe::kPolyline3d:
                return AcGeCurveToAcDbCurve(pDb,(AcGePolyline3d *) pGe);
      default:
                return Acad::eNotImplementedYet;
      }
}
//////////////////////////////////////////////////////////////////////////
//#include "Conversion.h"
// LINE
Acad::ErrorStatus CConversion::AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbLine * pLine)
{
      pGe = new AcGeLineSeg3d(pLine->startPoint(), pLine->endPoint());
      return Acad::eOk;
}
Acad::ErrorStatus CConversion::AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGeLineSeg3d * pGe)
{
      pDb= new AcDbLine(pGe->startPoint(),pGe->endPoint());
      return Acad::eOk;
}
// ARC
Acad::ErrorStatusCConversion::AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbArc * pDbArc)
{
      pGe =new AcGeCircArc3d(
                pDbArc->center(),
                pDbArc->normal(),
                pDbArc->normal().perpVector(),
                pDbArc->radius(),
                pDbArc->startAngle(),
                pDbArc->endAngle());
      return Acad::eOk;
}
Acad::ErrorStatus CConversion::AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGeCircArc3d * pGe)
{
      if (pGe->isClosed())
      {
                pDb = new AcDbCircle(pGe->center(),pGe->normal(),pGe->radius());
      }
      else
      {
                pDb = new AcDbArc(pGe->center(),pGe->normal(),pGe->radius(),pGe->startAng(),pGe->endAng());
      }
      return Acad::eOk;
}

// CIRCLE
Acad::ErrorStatusCConversion::AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbCircle * pDbCircle)
{
      pGe =new AcGeCircArc3d(pDbCircle->center(),pDbCircle->normal(),pDbCircle->radius());
      return Acad::eOk;
}

// ELLIPSE
Acad::ErrorStatusCConversion::AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbEllipse * pDb)
{
      pGe =new AcGeEllipArc3d(
                pDb->center(),
                pDb->majorAxis(),
                pDb->minorAxis(),
                pDb->majorAxis().length(),
                pDb->minorAxis().length(),
                pDb->startAngle(),
                pDb->endAngle());
      return Acad::eOk;
}
Acad::ErrorStatusCConversion::AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGeEllipArc3d * pGe)
{
      pDb = new AcDbEllipse(
                pGe->center(),
                pGe->normal(),
                pGe->majorAxis()*pGe->majorRadius(),
                pGe->minorRadius()/pGe->majorRadius(),
                pGe->startAng(),
                pGe->endAng());
      return Acad::eOk;
}
// SPLINE
Acad::ErrorStatus CConversion::AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbSpline * pSpline/*bool isFit*/)
{
      Acad::ErrorStatus es;
      int degree;
      double fitTolerance,controlPtTol,knotTol;
      Adesk::Boolean tangent**ist,tangentStartDef,tangentEndDef,bIsRational,bIsPeriodic,bIsClosed;
      AcGeVector3d startTangent,endTangent;
      AcGePoint3dArray controlPoints,fitPoints;
      AcGeDoubleArray knots,weights;
      bIsClosed = pSpline->isClosed();
      AcGeNurbCurve3d *pNurb = NULL;
      if (pSpline->hasFitData()==Adesk::kTrue/* && isFit*/)
      {
                AcGeTol tol;
                es = pSpline->getFitData(fitPoints,degree,fitTolerance,tangent**ist,startTangent,endTangent);
                if (es == Acad::eOk)
                {
                        tangentStartDef = tangent**ist;
                        tangentEndDef   = tangent**ist;
                        AcGeTol fitTol;
                        pSpline->fitTolerance();
                        fitTol.setEqualPoint(fitTolerance);
                        if (tangent**ist)
                        {
                              pNurb = new AcGeNurbCurve3d(fitPoints,startTangent,endTangent,tangentStartDef,tangentEndDef,fitTol);
                        }
                        else
                        {
                              pNurb = new AcGeNurbCurve3d(fitPoints,fitTol);
                        }
                }
                else
                {
                        return Acad::eNotImplementedYet;
                }
      }
      else
      {
                es = pSpline->getNurbsData(degree,bIsRational,bIsClosed,bIsPeriodic,controlPoints,knots,weights,controlPtTol,knotTol);
                if (es == Acad::eOk)
                {
                        if (bIsRational)
                        {
                              pNurb = new AcGeNurbCurve3d(degree,knots,controlPoints,weights,bIsPeriodic);
                        }
                        else
                        {
                              pNurb = new AcGeNurbCurve3d(degree,knots,controlPoints,bIsPeriodic);
                        }
                }
                else
                {
                        return Acad::eNotImplementedYet;
                }
      }
      bIsClosed?pNurb->makeClosed():pNurb->makeOpen();
      pGe = pNurb;
      return es;
}
Acad::ErrorStatus CConversion::AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGeNurbCurve3d * pGe)
{
      if (pGe->hasFitData())
      {
                AcGePoint3dArray fitPoints;
                AcGeTol fitTolerance;
                Adesk::Boolean tangent**ist;
                AcGeVector3d startTangent;
                AcGeVector3d endTangent;
                //double tol;
                pGe->getFitData(fitPoints,fitTolerance,tangent**ist,startTangent,endTangent);
                pDb = new AcDbSpline(fitPoints,startTangent,endTangent,pGe->order(),fitTolerance.equalPoint());
      }
      else
      {
                int degree;
                Adesk::Boolean bIsRational,periodic;
                AcGePoint3dArray controlPoints;
                AcGeKnotVector knots1;
                AcGeDoubleArray weights;
                pGe->getDefinitionData(degree,bIsRational,periodic,knots1,controlPoints,weights);
                AcGeDoubleArray knots;
                for (int i = 0;i<knots1.length();i++)
                {
                        knots.append(knots1);
                }
                pDb =new AcDbSpline(degree,bIsRational,pGe->isClosed(),periodic,controlPoints,knots,weights,0.0,pGe->knots().tolerance());
      }
      return Acad::eOk;
}
// POLYLINE
Acad::ErrorStatusCConversion::AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbPolyline * pPoly)
{
      AcGeLineSeg3d *pLine = NULL;
      AcGeCircArc3d *pArc = NULL;
      AcGeVoidPointerArray GeCurves;
      for( int i = 0; i <(int)pPoly->numVerts(); i++ )
      {
                if( pPoly->segType(i) == AcDbPolyline::kLine )
                {
                        pLine = new AcGeLineSeg3d;
                        pPoly->getLineSegAt(i, *pLine);
                        GeCurves.append(pLine);
                }
                else if( pPoly->segType(i) == AcDbPolyline::kArc )
                {
                        pArc = new AcGeCircArc3d;
                        pPoly->getArcSegAt(i, *pArc);
                        GeCurves.append(pArc);
                }
      }
      pGe =new AcGeCompositeCurve3d(GeCurves);
      return Acad::eOk;
}
Acad::ErrorStatus CConversion::AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGeCompositeCurve3d * pGe)
{
      AcGePoint3d startPnt,endPnt;
      if( pGe->hasEndPoint(endPnt) == Adesk ::kFalse ||
                pGe->hasStartPoint(startPnt) == Adesk::kFalse)
      {
                return Acad::eNotImplementedYet;
      }
      //get the plane of Curve3d
      AcGePlane plane;
      AcGeLine3d line;
      AcGePoint3d p1,p2,p3;
      if(pGe->isPlanar(plane))
      {
                if(pGe->isLinear(line))    //Oh,it's a little tricky!
                {
                        line.getPerpPlane(startPnt,plane);
                        plane.get(p1,p2,p3);
                        plane.set(p2,p3-p2);
                }
                plane.get(p1,p2,p3);
      }
      else
      {
                return Acad::eNotImplementedYet;
      }
      //Creat a polyline
      AcDbPolyline *pPoly = new AcDbPolyline();
      AcGeVoidPointerArray curveList;
      pGe->getCurveList(curveList);//get all the segments
      AcGeCurve3d *pCurve = NULL;
      AcGeCircArc3d *pArc = NULL;
      int i;
      double b;
      AcGePoint2d pt;
      for(i = 0;i < curveList.length();i++)
      {
                pCurve=(AcGeCurve3d *) (curveList);
                pCurve->hasStartPoint(startPnt);
                pt = startPnt.convert2d(plane);
                if (pCurve->isKindOf(AcGe::kCircArc3d))
                {
                        pArc = (AcGeCircArc3d *)(pCurve);
                        b = tan(0.25 * pArc->endAng());
                        if (pArc->normal()!=plane.normal())
                        {
                              pPoly->addVertexAt(i,pt,-b);
                        }
                        else
                        {
                              pPoly->addVertexAt(i,pt,b);
                        }
                }
                else
                {
                        pPoly->addVertexAt(i,pt);
                }
      }
      if(!pGe->isClosed())
      {
                pt = endPnt.convert2d(plane);
                pPoly->addVertexAt(i,pt);
      }
      else
      {
                pPoly->setClosed(Adesk::kTrue);
      }
      //the most important step;
      AcGeMatrix3d xform;
      AcGeVector3d XAxis = p1-p2;
      AcGeVector3d YAxis = p3-p2;
      AcGeVector3d ZAxis = XAxis.crossProduct(YAxis);
      xform.setCoordSystem(p2,XAxis,YAxis,ZAxis);
      pPoly->transformBy(xform);
      pDb = pPoly;
      return Acad::eOk;
}
// POLYLINE3D ?fit 后是折线模拟
Acad::ErrorStatus CConversion::AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDb3dPolyline * pPoly3d)
{
      AcGePoint3dArray pts;
      AcGePoint3d pt1;
      AcDbObjectId id;
      AcDbVertex *p3dVertex=NULL;
      Acad::ErrorStatus es;
      AcDb3dPolylineVertex *pPoly3dVertex=NULL;
      AcDbObjectIterator* vertexIterator = pPoly3d->vertexIterator();
      for (vertexIterator->start();!vertexIterator==vertexIterator->done();vertexIterator->step())
      {
                id=vertexIterator->objectId();
                es=acdbOpenObject(p3dVertex,id,AcDb::kForRead);
                if (es==Acad::eOk)
                {
                        pPoly3dVertex=AcDb3dPolylineVertex::cast(p3dVertex);
                        if (pPoly3dVertex->vertexType()!=AcDb::k3dControlVertex)
                        {
                              pts.append(pPoly3dVertex->position());
                        }                     
                }
                if (p3dVertex!=NULL)
                {
                        p3dVertex->close();
                }
                if (pPoly3dVertex!=NULL)
                {
                        pPoly3dVertex->close();
                }
      }
      delete vertexIterator;
      if (pPoly3d->isClosed())
      {
                pPoly3d->getStartPoint(pt1);
                pts.append(pt1);
      }
      pGe=new AcGePolyline3d(pts);      
      return Acad::eOk;
}
Acad::ErrorStatus CConversion::AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGePolyline3d *pGe)
{
      AcGePoint3dArray pts;
      for (int i = 0;i < pGe->numControlPoints();i++)
      {
                pts.append(pGe->controlPointAt(i));
      }
      pDb = new AcDb3dPolyline((AcDb::Poly3dType)pGe->type(),pts,pGe->isClosed());
      return Acad::eOk;
}
// POLYLINE2D
Acad::ErrorStatus CConversion::AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDb2dPolyline *pPoly2d)
{
      AcDb::Poly2dType type;
      type=pPoly2d->polyType();
      AcDbPolyline * pLwpoly = NULL;
      Acad::ErrorStatus es;
      if ((type==AcDb::k2d**Poly)||(type==AcDb::k2dFitCurvePoly))
      {
                pLwpoly=new AcDbPolyline;
                es = pLwpoly->convertFrom((AcDbEntity *&)pPoly2d,Adesk::kFalse);
                if (es!=Acad::eOk)
                {
                        delete pLwpoly;
                        pLwpoly=NULL;
                        return es;
                }
                es = AcDbCurveToAcGeCurve(pGe,pLwpoly);
                pLwpoly->close();
                return es;
      }
      else
      {
                AcGeVoidPointerArray GeCurves;
                AcGePoint3d pt1;
                AcGePoint3d pt2;
                double Param;
                pPoly2d->getEndParam(Param);
                AcGeLineSeg3d *pLine = NULL;
                for (int i= 0; i < (int)Param;i++)
                {
                        pPoly2d->getPointAtParam(i,pt1);
                        pPoly2d->getPointAtParam(i+1,pt2);
                        pLine = new AcGeLineSeg3d(pt1,pt2);
                        GeCurves.append(pLine);
                }
                pGe = new AcGeCompositeCurve3d(GeCurves);
                return Acad::eOk;
      }
}
页: [1]
查看完整版本: [研讨] AcDbCurve转换AcGeCurve中的样条化3dpoly