找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 2398|回复: 6

[每日一码] AcBr 类开发代码

[复制链接]

已领礼包: 13个

财富等级: 恭喜发财

发表于 2017-2-25 12:49:43 | 显示全部楼层 |阅读模式

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

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

×
  1. //
  2. // ObjectARX defined commands
  3. #include "StdAfx.h"
  4. #include "StdArx.h"
  5. #include "brbrep.h"        // AcBrBrep
  6. #include "dbents.h"
  7. #include "dbregion.h"        // AcDbRegion
  8. #include "dbpl.h"        // AcDbPolyline
  9. #include "gecomp3d.h"        // AcGeCompositeCurve2d
  10. // 根据轻量多段线创建对应的AcGeCurve2d对象
  11. BOOL PolylineToGeCurve(const AcDbPolyline *&pPline,
  12.                                            AcGeCurve3d *&pGeCurve)
  13. {
  14.         int nSegs;        // 多段线的段数
  15.         AcGeLineSeg3d line, *pLine;        // 几何曲线的直线段部分
  16.         AcGeCircArc3d arc, *pArc;        // 几何曲线的圆弧部分
  17.         AcGeVoidPointerArray geCurves;        // 指向组成几何曲线的分段曲线的指针数组
  18.         nSegs = pPline->numVerts() - 1;
  19.         // 根据多段线创建对应的分段几何曲线
  20.         for (int i = 0; i < nSegs; i++)
  21.         {
  22.                 if (pPline->segType(i) == AcDbPolyline::kLine)
  23.                 {
  24.                         pPline->getLineSegAt(i, line);
  25.                         pLine = new AcGeLineSeg3d(line);
  26.                         geCurves.append(pLine);
  27.                 }
  28.                 else if (pPline->segType(i) == AcDbPolyline::kArc)
  29.                 {
  30.                         pPline->getArcSegAt(i, arc);
  31.                         pArc = new AcGeCircArc3d(arc);
  32.                         geCurves.append(pArc);
  33.                 }
  34.         }
  35.         // 处理闭合多段线最后一段是圆弧的情况
  36.         if (pPline->isClosed() && pPline->segType(nSegs) == AcDbPolyline::kArc)
  37.         {
  38.                 pPline->getArcSegAt(nSegs, arc);
  39.                 pArc = new AcGeCircArc3d(arc);
  40.                 pArc->setAngles(arc.startAng(), arc.endAng() -
  41.                         (arc.endAng() - arc.startAng()) / 100);
  42.                 geCurves.append(pArc);
  43.         }
  44.         // 根据分段的几何曲线创建对应的复合曲线
  45.         if (geCurves.length() == 1)
  46.         {
  47.                 pGeCurve = (AcGeCurve3d *)geCurves[0];
  48.         }
  49.         else
  50.         {
  51.                 pGeCurve = new AcGeCompositeCurve3d(geCurves);
  52.         }
  53.         // 释放动态分配的内存
  54.         for (i = 0; i < geCurves.length(); i++)
  55.         {
  56.                 delete geCurves;
  57.         }
  58.         return TRUE;
  59. }
  60. // 将实体添加到图形数据库的模型空间
  61. AcDbObjectId PostToModelSpace(AcDbEntity* pEnt)
  62. {
  63.         AcDbBlockTable *pBlockTable;
  64.         acdbHostApplicationServices()->workingDatabase()
  65.                 ->getBlockTable(pBlockTable, AcDb::kForRead);
  66.         AcDbBlockTableRecord *pBlockTableRecord;
  67.         pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,
  68.                 AcDb::kForWrite);   
  69.         AcDbObjectId entId;
  70.         pBlockTableRecord->appendAcDbEntity(entId, pEnt);
  71.         pBlockTable->close();
  72.         pBlockTableRecord->close();
  73.         pEnt->close();
  74.         return entId;
  75. }
  76. // 根据给定的边界对象创建面域
  77. AcDbObjectIdArray CreateRegion(const AcDbObjectIdArray& curveIds)
  78. {
  79.         AcDbObjectIdArray regionIds;        // 生成的面域的ID数组
  80.         AcDbVoidPtrArray curves;        // 指向作为面域边界的曲线的指针的数组
  81.         AcDbVoidPtrArray regions;        // 指向创建的面域对象的指针的数组
  82.         AcDbEntity *pEnt;        // 临时指针,用来关闭边界曲线
  83.         AcDbRegion *pRegion;        // 临时对象,用来将面域添加到模型空间
  84.         // 用curveIds初始化curves
  85.         for (int i = 0; i < curveIds.length(); i++)
  86.         {
  87.                 acdbOpenAcDbEntity(pEnt, curveIds.at(i), AcDb::kForRead);
  88.                 if (pEnt->isKindOf(AcDbCurve::desc()))
  89.                 {
  90.                         curves.append(static_cast<void*>(pEnt));
  91.                 }
  92.         }
  93.         Acad::ErrorStatus es = AcDbRegion::createFromCurves(curves, regions);
  94.         if (es == Acad::eOk)
  95.         {
  96.                 // 将生成的面域添加到模型空间
  97.                 for (i = 0; i < regions.length(); i++)
  98.                 {
  99.                         // 将空指针(可指向任何类型)转化为指向面域的指针
  100.                         pRegion = static_cast<AcDbRegion*>(regions);
  101.                         pRegion->setDatabaseDefaults();
  102.                         AcDbObjectId regionId;
  103.                         regionId = PostToModelSpace(pRegion);
  104.                         regionIds.append(regionId);
  105.                 }
  106.         }
  107.         else        // 如果创建不成功,也要删除已经生成的面域
  108.         {
  109.                 for (i = 0; i < regions.length(); i++)
  110.                 {
  111.                         delete (AcRxObject*)regions;
  112.                 }
  113.         }
  114.         // 关闭作为边界的对象
  115.         for (i = 0; i < curves.length(); i++)
  116.         {
  117.                 pEnt = static_cast<AcDbEntity*>(curves);
  118.                 pEnt->close();
  119.         }
  120.         return regionIds;
  121. }
  122. // 判断点是否在指定的面域内部
  123. bool PtInRegion(AcGePoint3d &pt, AcDbRegion *pRegion)
  124. {
  125.         if (pRegion == NULL)
  126.                 return false;
  127.         AcBrBrep brep;
  128.         if (brep.set(*pRegion) != AcBr::eOk)
  129.                 return false;
  130.         AcBr::Relation relation;
  131.         AcBr::ErrorStatus es = brep.getPointRelationToBrep(pt, relation);
  132.         if (es != AcBr::eOk)
  133.                 return false;
  134.         switch (relation)
  135.         {
  136.         case AcBr::kBoundary:
  137.         case AcBr::kInside:
  138.                 return true;
  139.         default:
  140.                 return false;
  141.         }
  142. }
  143. // 判断一条多段线是否在另一条多段线内部
  144. bool PolyInRegion(AcDbPolyline *pPoly, AcDbRegion *pRegion)
  145. {
  146.         if ((pPoly == NULL) || (pRegion == NULL))
  147.                 return false;
  148.         // 创建Brep实体
  149.         AcBrBrep brep;
  150.         if (brep.set(*pRegion) != AcBr::eOk)
  151.                 return false;
  152.         // 根据多段线创建对应的几何类
  153.         //AcGeCurve3d *pGeCurve = NULL;
  154.         AcGeLineSeg3d *pGeCurve = new AcGeLineSeg3d(AcGePoint3d(50, 50, 0),
  155.                 AcGePoint3d(60, 60, 0));
  156.         //PolylineToGeCurve(pPoly, pGeCurve);
  157.         AcBr::Relation relation;
  158.         AcBr::ErrorStatus es = brep.getCurveRelationToBrep(*pGeCurve, relation);
  159.         delete pGeCurve;        // 在函数PolylineToGeCurve中分配了内存
  160.         if (es != AcBr::eOk)
  161.                 return false;
  162.         switch (relation)
  163.         {
  164.         case AcBr::kBoundary:
  165.         case AcBr::kInside:
  166.                 return true;
  167.         default:
  168.                 return false;
  169.         }
  170. }
  171. // This is command 'PTINREGION'
  172. void ZffCHAP2PtInRegion()
  173. {
  174.         // 创建一个圆作为拉伸的截面
  175.         AcGeVector3d vec(0, 0, 1);        // 圆所在平面的法矢量
  176.         AcGePoint3d ptCenter(30, 0, 0);        // 圆心位置与半径的大小有关
  177.         AcDbCircle *pCircle = new AcDbCircle(ptCenter, vec, 30);
  178.         AcDbObjectId circleId = PostToModelSpace(pCircle);
  179.         // 根据圆创建一个面域
  180.         AcDbObjectIdArray boundaryIds, regionIds;
  181.         boundaryIds.append(circleId);
  182.         regionIds = CreateRegion(boundaryIds);
  183.         // 打开面域
  184.         AcDbRegion *pRegion;
  185.         acdbOpenObject(pRegion, regionIds[0], AcDb::kForRead);
  186.         AcGePoint3d pt(1, 0, 0);
  187.         if (PtInRegion(pt, pRegion) == true)
  188.         {
  189.                 acedAlert("True");
  190.         }
  191.         pRegion->close();
  192. }
  193. // This is command 'POLYCONTAIN'
  194. void ZffCHAP2PolyContain()
  195. {
  196.         // 提示用户选择对象
  197.         ads_name en1, en2;
  198.         ads_point pt;
  199.         if (acedEntSel("n选择第一条多段线:", en1, pt) != RTNORM)
  200.                 return;
  201.         if (acedEntSel("n选择第二条多段线:", en2, pt) != RTNORM)
  202.                 return;
  203.         // 获得选择对象的指针
  204.         AcDbObjectId polyId1, polyId2;
  205.         Acad::ErrorStatus es = acdbGetObjectId(polyId1, en1);
  206.         es = acdbGetObjectId(polyId2, en2);
  207.         AcDbPolyline *pPoly;
  208.         es = acdbOpenObject(pPoly, polyId1, AcDb::kForRead);
  209.         // 根据第二条多段线创建一个面域
  210.         AcDbObjectIdArray boundaryIds, regionIds;
  211.         boundaryIds.append(polyId2);
  212.         regionIds = CreateRegion(boundaryIds);
  213.         // 打开面域
  214.         AcDbRegion *pRegion;
  215.         acdbOpenObject(pRegion, regionIds[0], AcDb::kForWrite);
  216.         if (PolyInRegion(pPoly, pRegion) == true)
  217.         {
  218.                 acedAlert("第一条多段线在第二条多段线内部!");
  219.         }
  220.         pPoly->close();
  221.         pRegion->erase();
  222.         pRegion->close();
  223. }


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

已领礼包: 6568个

财富等级: 富甲天下

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

使用道具 举报

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

使用道具 举报

已领礼包: 859个

财富等级: 财运亨通

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

使用道具 举报

已领礼包: 1个

财富等级: 恭喜发财

发表于 2021-8-21 20:59:33 | 显示全部楼层
本帖最后由 netbee 于 2021-8-21 21:11 编辑

我在CAD2008使用过程中发现BOOL PolylineToGeCurve(const AcDbPolyline *&pPline,
                                           AcGeCurve3d *&pGeCurve)函数生成的  AcGeCurve3d* 并没有被释放,导致CAD的占用内存越用越大,不知道是怎么回事。
  1. // 释放动态分配的内存
  2.         for (i = 0; i < geCurves.length(); i++)
  3.         {
  4.                 delete geCurves[i];
  5.         }
复制代码
这一段语句实际上是不能运行的:
错误        4        error C2440: 'delete' : cannot convert from 'AcGeVoidPointerArray' to 'void *'        d:\backup\documents\ymf\软件开发\nbtsurvey开发版\vc\nbtsurvey\nbtsurvey\cconversion.cpp        290


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

使用道具 举报

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-21 23:10 , Processed in 0.494981 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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