明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索

[几何] 曲线转换类

  [复制链接]
发表于 2010-7-29 10:26 | 显示全部楼层
我也来发一个arx版本的,关于spline和3dpolyline,以及2dpolyline的处理比较复杂。
另外感觉楼主的两个地方考虑欠妥。
1、是对于polyline 在3d空间状态下的转换如果normal不是(0,0,1),会出问题。
2、对于spline的处理,用Nurb得到的如果转成AcDbSpline,在封闭情况下,会跟原来的不一致。

特别感谢楼主的代码,我转化为arx的时候从中受益颇多。
  1. #include "Conversion.h"
  2. // LINE
  3. Acad::ErrorStatus AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbLine * pLine)
  4. {
  5. pGe = new AcGeLineSeg3d(pLine->startPoint(), pLine->endPoint());
  6. return Acad::eOk;
  7. }
  8. Acad::ErrorStatus AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGeLineSeg3d * pGe)
  9. {
  10. pDb= new AcDbLine(pGe->startPoint(),pGe->endPoint());
  11. return Acad::eOk;
  12. }
  13. // ARC
  14. Acad::ErrorStatus  AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbArc * pDbArc)
  15. {
  16. pGe =  new AcGeCircArc3d(
  17.   pDbArc->center(),
  18.   pDbArc->normal(),
  19.   pDbArc->normal().perpVector(),
  20.   pDbArc->radius(),
  21.   pDbArc->startAngle(),
  22.   pDbArc->endAngle());
  23. return Acad::eOk;
  24. }
  25. Acad::ErrorStatus AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGeCircArc3d * pGe)
  26. {
  27. if (pGe->isClosed())
  28. {
  29.   pDb = new AcDbCircle(pGe->center(),pGe->normal(),pGe->radius());
  30. }
  31. else
  32. {
  33.   pDb = new AcDbArc(pGe->center(),pGe->normal(),pGe->radius(),pGe->startAng(),pGe->endAng());
  34. }
  35. return Acad::eOk;
  36. }
  37. // CIRCLE
  38. Acad::ErrorStatus  AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbCircle * pDbCircle)
  39. {
  40. pGe =  new AcGeCircArc3d(pDbCircle->center(),pDbCircle->normal(),pDbCircle->radius());
  41. return Acad::eOk;
  42. }
  43. // ELLIPSE
  44. Acad::ErrorStatus  AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbEllipse * pDb)
  45. {
  46. pGe =  new AcGeEllipArc3d(
  47.   pDb->center(),
  48.   pDb->majorAxis(),
  49.   pDb->minorAxis(),
  50.   pDb->majorAxis().length(),
  51.   pDb->minorAxis().length(),
  52.   pDb->startAngle(),
  53.   pDb->endAngle());
  54. return Acad::eOk;
  55. }
  56. Acad::ErrorStatus  AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGeEllipArc3d * pGe)
  57. {
  58. pDb = new AcDbEllipse(
  59.   pGe->center(),
  60.   pGe->normal(),
  61.   pGe->majorAxis()*pGe->majorRadius(),
  62.   pGe->minorRadius()/pGe->majorRadius(),
  63.   pGe->startAng(),
  64.   pGe->endAng());
  65. return Acad::eOk;
  66. }
  67. // SPLINE
  68. Acad::ErrorStatus AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbSpline * pSpline,bool isFit)
  69. {
  70. Acad::ErrorStatus es;
  71. int degree;
  72. double fitTolerance,controlPtTol,knotTol;
  73. Adesk::Boolean tangentsExist,tangentStartDef,tangentEndDef,bIsRational,bIsPeriodic,bIsClosed;
  74. AcGeVector3d startTangent,endTangent;
  75. AcGePoint3dArray controlPoints,fitPoints;
  76. AcGeDoubleArray knots,weights;
  77. bIsClosed = pSpline->isClosed();
  78. AcGeNurbCurve3d *pNurb = NULL;
  79. if (pSpline->hasFitData() && isFit)
  80. {
  81.   AcGeTol tol;
  82.   es = pSpline->getFitData(fitPoints,degree,fitTolerance,tangentsExist,startTangent,endTangent);
  83.   if (es == Acad::eOk)
  84.   {
  85.    tangentStartDef = tangentsExist;
  86.    tangentEndDef   = tangentsExist;
  87.    AcGeTol fitTol;
  88.    pSpline->fitTolerance();
  89.    fitTol.setEqualPoint(fitTolerance);
  90.    if (tangentsExist)
  91.    {
  92.     pNurb = new AcGeNurbCurve3d(fitPoints,startTangent,endTangent,tangentStartDef,tangentEndDef,fitTol);
  93.    }
  94.    else
  95.    {
  96.     pNurb = new AcGeNurbCurve3d(fitPoints,fitTol);
  97.    }
  98.   }
  99.   else
  100.   {
  101.    return Acad::eNotImplementedYet;
  102.   }
  103. }
  104. else
  105. {
  106.   es = pSpline->getNurbsData(degree,bIsRational,bIsClosed,bIsPeriodic,controlPoints,knots,weights,controlPtTol,knotTol);
  107.   if (es == Acad::eOk)
  108.   {
  109.    if (bIsRational)
  110.    {
  111.     pNurb = new AcGeNurbCurve3d(degree,knots,controlPoints,weights,bIsPeriodic);
  112.    }
  113.    else
  114.    {
  115.     pNurb = new AcGeNurbCurve3d(degree,knots,controlPoints,bIsPeriodic);
  116.    }
  117.   }
  118.   else
  119.   {
  120.    return Acad::eNotImplementedYet;
  121.   }
  122. }
  123. bIsClosed?pNurb->makeClosed():pNurb->makeOpen();
  124. pGe = pNurb;
  125. return es;
  126. }
  127. Acad::ErrorStatus AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGeNurbCurve3d * pGe)
  128. {
  129. if (pGe->hasFitData())
  130. {
  131.   AcGePoint3dArray fitPoints;
  132.   AcGeTol fitTolerance;
  133.   Adesk::Boolean tangentsExist;
  134.   AcGeVector3d startTangent;
  135.   AcGeVector3d endTangent;
  136.   double tol;
  137.   pGe->getFitData(fitPoints,fitTolerance,tangentsExist,startTangent,endTangent);
  138.   pDb = new AcDbSpline(fitPoints,startTangent,endTangent,pGe->order(),fitTolerance.equalPoint());
  139. }
  140. else
  141. {
  142.   int degree;
  143.   Adesk::Boolean bIsRational,periodic;
  144.   AcGePoint3dArray controlPoints;
  145.   AcGeKnotVector knots1;
  146.   AcGeDoubleArray weights;
  147.   pGe->getDefinitionData(degree,bIsRational,periodic,knots1,controlPoints,weights);
  148.   AcGeDoubleArray knots;
  149.   for (int i = 0;i<knots1.length();i++)
  150.   {
  151.       knots.append(knots1[i]);
  152.   }
  153.   pDb =new AcDbSpline(degree,bIsRational,pGe->isClosed(),periodic,controlPoints,knots,weights,0.0,pGe->knots().tolerance());
  154. }
  155. return Acad::eOk;
  156. }
  157. // POLYLINE
  158. Acad::ErrorStatus  AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbPolyline * pPoly)
  159. {
  160. AcGeLineSeg3d *pLine = NULL;
  161. AcGeCircArc3d *pArc = NULL;
  162. AcGeVoidPointerArray GeCurves;
  163. for( int i = 0; i < pPoly->numVerts(); i++ )
  164. {
  165.   if( pPoly->segType(i) == AcDbPolyline::kLine )
  166.   {
  167.    pLine = new AcGeLineSeg3d;
  168.    pPoly->getLineSegAt(i, *pLine);
  169.    GeCurves.append(pLine);
  170.   }
  171.   else if( pPoly->segType(i) == AcDbPolyline::kArc )
  172.   {
  173.    pArc = new AcGeCircArc3d;
  174.    pPoly->getArcSegAt(i, *pArc);
  175.    GeCurves.append(pArc);
  176.   }
  177. }
  178. pGe =  new AcGeCompositeCurve3d(GeCurves);
  179. return Acad::eOk;
  180. }
  181. Acad::ErrorStatus AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGeCompositeCurve3d * pGe)
  182. {  
  183. AcGePoint3d startPnt,endPnt;
  184. if( pGe->hasEndPoint(endPnt) == Adesk ::kFalse ||
  185.   pGe->hasStartPoint(startPnt) == Adesk::kFalse)
  186. {
  187.   return Acad::eNotImplementedYet;
  188. }
  189. //get the plane of Curve3d
  190. AcGePlane plane;
  191. AcGeLine3d line;
  192. AcGePoint3d p1,p2,p3;
  193. if(pGe->isPlanar(plane))
  194. {
  195.   if(pGe->isLinear(line))    //Oh,it's a little tricky!
  196.   {
  197.    line.getPerpPlane(startPnt,plane);
  198.    plane.get(p1,p2,p3);
  199.    plane.set(p2,p3-p2);
  200.   }
  201.   plane.get(p1,p2,p3);
  202. }
  203. else
  204. {
  205.   return Acad::eNotImplementedYet;
  206. }
  207. //Creat a polyline
  208. AcDbPolyline *pPoly = new AcDbPolyline();
  209. AcGeVoidPointerArray curveList;
  210. pGe->getCurveList(curveList);  //get all the segments
  211. AcGeCurve3d *pCurve = NULL;
  212. AcGeCircArc3d *pArc = NULL;
  213. int i;
  214. double b;
  215. AcGePoint2d pt;
  216. for(i = 0;i < curveList.length();i++)
  217. {
  218.   pCurve  =  (AcGeCurve3d *) (curveList[i]);
  219.   pCurve->hasStartPoint(startPnt);
  220.   pt = startPnt.convert2d(plane);
  221.   if (pCurve->isKindOf(AcGe::kCircArc3d))
  222.   {
  223.    pArc = (AcGeCircArc3d *)(pCurve);
  224.    b = tan(0.25 * pArc->endAng());
  225.    if (pArc->normal()!=plane.normal())
  226.    {
  227.     pPoly->addVertexAt(i,pt,-b);
  228.    }
  229.    else
  230.    {
  231.     pPoly->addVertexAt(i,pt,b);
  232.    }
  233.   }
  234.   else
  235.   {
  236.    pPoly->addVertexAt(i,pt);
  237.   }
  238. }
  239. if(!pGe->isClosed())
  240. {
  241.   pt = endPnt.convert2d(plane);
  242.   pPoly->addVertexAt(i,pt);
  243. }
  244. else
  245. {
  246.   pPoly->setClosed(Adesk::kTrue);
  247. }
  248. //the most important step;
  249. AcGeMatrix3d xform;
  250. AcGeVector3d XAxis = p1-p2;
  251. AcGeVector3d YAxis = p3-p2;
  252. AcGeVector3d ZAxis = XAxis.crossProduct(YAxis);
  253. xform.setCoordSystem(p2,XAxis,YAxis,ZAxis);
  254. pPoly->transformBy(xform);
  255. pDb = pPoly;
  256. return Acad::eOk;
  257. }
  258. // POLYLINE3D
  259. Acad::ErrorStatus AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDb3dPolyline * pPoly3d,bool isFit)
  260. {
  261. AcGeVoidPointerArray GeCurves;
  262. AcGePoint3d pt1;
  263. AcGePoint3d pt2;
  264. double Param;
  265. pPoly3d->getEndParam(Param);
  266. GeCurves.setLogicalLength((int)Param);
  267. for (int i= 0; i < (int)Param;i++)
  268. {
  269.   pPoly3d->getPointAtParam(i,pt1);
  270.   pPoly3d->getPointAtParam(i+1,pt2);
  271.   GeCurves[i] = new AcGeLineSeg3d(pt1,pt2);
  272. }
  273. if (!isFit)
  274. {
  275.   pGe  = new AcGeCompositeCurve3d(GeCurves);
  276.   return Acad::eOk;
  277. }
  278. AcDbSpline *pSpline= NULL;
  279. pPoly3d->getSpline(pSpline);
  280. Acad::ErrorStatus es = AcDbCurveToAcGeCurve(pGe,pSpline);
  281. delete pSpline;
  282. pSpline = NULL;
  283. return es;
  284. }
  285. Acad::ErrorStatus AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGePolyline3d *pGe)
  286. {
  287. AcGePoint3dArray pts;
  288. for (int i = 0;i < pGe->numControlPoints();i++)
  289. {
  290.   pts.append(pGe->controlPointAt(i));
  291. }
  292. pDb = new AcDb3dPolyline((AcDb::Poly3dType)pGe->type(),pts,pGe->isClosed());
  293. return Acad::eOk;
  294. }
  295. // POLYLINE2D
  296. Acad::ErrorStatus AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDb2dPolyline *pPoly2d,bool isFit)
  297. {
  298. AcDb::Poly2dType type;
  299. type=pPoly2d->polyType();
  300. AcDbPolyline * pLwpoly = NULL;
  301. Acad::ErrorStatus es;
  302. if ((type==AcDb::k2dSimplePoly)||(type==AcDb::k2dFitCurvePoly))
  303. {
  304.   pLwpoly=new AcDbPolyline;
  305.   es = pLwpoly->convertFrom((AcDbEntity *&)pPoly2d,Adesk::kFalse);
  306.   if (es!=Acad::eOk)
  307.   {
  308.    delete pLwpoly;
  309.    pLwpoly=NULL;
  310.    return es;
  311.   }
  312.   es = AcDbCurveToAcGeCurve(pGe,pLwpoly);
  313.   pLwpoly->close();
  314.   return es;
  315. }
  316. else
  317. {
  318.   AcGeVoidPointerArray GeCurves;
  319.   AcGePoint3d pt1;
  320.   AcGePoint3d pt2;
  321.   double Param;
  322.   pPoly2d->getEndParam(Param);
  323.   AcGeLineSeg3d *pLine = NULL;
  324.   for (int i= 0; i < (int)Param;i++)
  325.   {
  326.    pPoly2d->getPointAtParam(i,pt1);
  327.    pPoly2d->getPointAtParam(i+1,pt2);
  328.    pLine = new AcGeLineSeg3d(pt1,pt2);
  329.    GeCurves.append(pLine);
  330.   }
  331.   pGe = new AcGeCompositeCurve3d(GeCurves);
  332.   return Acad::eOk;
  333. }
  334. }
  335. // catch all for all other entity types.
  336. Acad::ErrorStatus AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbCurve *pDbCurve)
  337. {
  338. if (pDbCurve->isKindOf(AcDbLine::desc()))
  339. {
  340.   return AcDbCurveToAcGeCurve(pGe,(AcDbLine *)pDbCurve);
  341. }
  342. if (pDbCurve->isKindOf(AcDbArc::desc()))
  343. {
  344.   return AcDbCurveToAcGeCurve(pGe,(AcDbArc *)pDbCurve);
  345. }
  346. if (pDbCurve->isKindOf(AcDbCircle::desc()))
  347. {
  348.   return AcDbCurveToAcGeCurve(pGe,(AcDbCircle *)pDbCurve);
  349. }
  350. if (pDbCurve->isKindOf(AcDbEllipse::desc()))
  351. {
  352.   return AcDbCurveToAcGeCurve(pGe,(AcDbEllipse *)pDbCurve);
  353. }
  354. if (pDbCurve->isKindOf(AcDbSpline::desc()))
  355. {
  356.   return AcDbCurveToAcGeCurve(pGe,(AcDbSpline *)pDbCurve);
  357. }
  358. if (pDbCurve->isKindOf(AcDbPolyline::desc()))
  359. {
  360.   return AcDbCurveToAcGeCurve(pGe,(AcDbPolyline *)pDbCurve);
  361. }
  362. if (pDbCurve->isKindOf(AcDb3dPolyline::desc()))
  363. {
  364.   return AcDbCurveToAcGeCurve(pGe,(AcDb3dPolyline *)pDbCurve);
  365. }
  366. if (pDbCurve->isKindOf(AcDb2dPolyline::desc()))
  367. {
  368.   return AcDbCurveToAcGeCurve(pGe,(AcDb2dPolyline *)pDbCurve);
  369. }
  370. return Acad::eNotImplementedYet;
  371. }
  372. Acad::ErrorStatus AcDbCurveToAcGeCurve(AcGeCurve3d * &pGe,const AcDbEntity *pEnt)
  373. {
  374. if (pEnt->isKindOf(AcDbCurve::desc()))
  375. {
  376.   return AcDbCurveToAcGeCurve(pGe,(AcDbCurve *)pEnt);
  377. }
  378. return Acad::eNotImplementedYet;
  379. }
  380. Acad::ErrorStatus AcGeCurveToAcDbCurve(AcDbCurve * &pDb,const AcGeCurve3d * pGe)
  381. {
  382. AcGe::EntityId type = pGe->type();
  383. switch (type)
  384. {
  385.   case AcGe::kLineSeg3d:
  386.    return AcGeCurveToAcDbCurve(pDb,(AcGeLineSeg3d *) pGe);
  387.   case AcGe::kCircArc3d:
  388.    return AcGeCurveToAcDbCurve(pDb,(AcGeCircArc3d *) pGe);
  389.   case AcGe::kEllipArc3d:
  390.    return AcGeCurveToAcDbCurve(pDb,(AcGeEllipArc3d *) pGe);
  391.   case AcGe::kNurbCurve3d:
  392.    return AcGeCurveToAcDbCurve(pDb,(AcGeNurbCurve3d *) pGe);
  393.   case AcGe::kCompositeCrv3d:
  394.    return AcGeCurveToAcDbCurve(pDb,(AcGeCompositeCurve3d*) pGe);
  395.   case AcGe::kPolyline3d:
  396.    return AcGeCurveToAcDbCurve(pDb,(AcGePolyline3d *) pGe);
  397.   default:
  398.    return Acad::eNotImplementedYet;
  399. }
  400. }
复制代码

评分

参与人数 1威望 +1 明经币 +2 金钱 +10 贡献 +10 激情 +10 收起 理由
雪山飞狐_lzh + 1 + 2 + 10 + 10 + 10 【好评】好程序 受教了! 找个时间把Bug修

查看全部评分

 楼主| 发表于 2010-7-29 10:38 | 显示全部楼层

polyline确实没考虑,谢谢highflybird的提醒

spline的处理要仔细看下了,以前的处理确实有问题

发表于 2010-7-29 10:46 | 显示全部楼层

实际上我仔细研究了一下AcDb3dPolyline和AcGePolyline3d的转换问题,觉得如下问题应该考虑:

AcGePolyline3d没有拟合类型,这样如果AcDb转成AcGe的时候,在有拟合的情况下,就无从处理,因此只能具体情况具体处理了。

2dpolyline也类似。

有点需要说明的是:Arx跟C#的处理有点不一样的是,arx在转换后, 如果你不需要那个类了,你应该delete或者free你创建的。

 

另参见我的: 

http://www.objectarx.net/forum.php?mod=viewthread&tid=4935&extra=page%3D1

发表于 2010-10-28 10:31 | 显示全部楼层
本帖最后由 作者 于 2010-10-28 14:22:34 编辑

楼主的曲线转换类包括了以下三部分:
1.转换Ge2d曲线为Db曲线
2.转换Ge3d曲线为Db曲线
3.转换Db曲线为Ge3d曲线

好像缺少了下面一些内容,不知能否添加上?
1.没有转换Db曲线为Ge2d曲线的方法
2.转换Ge2d曲线为Db曲线中,没有CompositeCurve2dToPolyline

另外,对于转换LineSegment2d为Line曲线,似乎执行下面函数就可以了:
  1. public static Line ToLine(LineSegment2d ls2d)
  2.         {
  3.             Plane plane = ();
  4.             return
  5.                 new Line(
  6.                     new Point3d(plane, ls2d.StartPoint),
  7.                     new Point3d(plane, ls2d.EndPoint));
  8.         }
复制代码
为何还要执行这一步,TransformBy在这里起什么作用?
  1. public static Line ToLine(LineSegment2d ls2d, Matrix3d mat)
  2.         {
  3.             Line l = ToLine(ls2d);
  4.             l.TransformBy(mat);
  5.             return l;
  6.         }
复制代码



 楼主| 发表于 2010-10-28 19:34 | 显示全部楼层

Db曲线为Ge2d曲线的方法没有做,当时感觉没有这种需求

TransformBy主要考虑三维的操作

发表于 2010-10-28 19:51 | 显示全部楼层

能否把这个先加上:CompositeCurve2dToPolyline


 

 楼主| 发表于 2010-10-29 10:00 | 显示全部楼层

这个可以直接参考

public static Polyline ToPolyline(this CompositeCurve3d cc3d)

CompositeCurve的处理有点郁闷,在DB库没有严格对应的对象

 楼主| 发表于 2010-10-29 10:05 | 显示全部楼层
发表于 2010-10-29 10:25 | 显示全部楼层

刚开始用VB.NET,只是初步,通过转换C#到VB.NET来学习AutoCAD .NET API。

目前DLL还用不上。CompositeCurve3dToPolyline和CompositeCurve2dToPolyline应该有些差别,放到以后再做吧。

 

 

发表于 2010-10-31 18:04 | 显示全部楼层
学习了,一定要顶
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-26 01:11 , Processed in 0.251182 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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