找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1013|回复: 2

[发布] 【AcBr库应用(四)】求空间点到3DSOLID各个面的最近点

[复制链接]

已领礼包: 40个

财富等级: 招财进宝

发表于 2018-5-26 02:01:38 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 newer 于 2018-5-26 14:00 编辑


问题:

I have a point in 3D space and I would like to get the closest point on a 3D solid from this input point. Is there any API to achieve this?


求输入点到3DSOLID最近点,哪个API可以解决?

解决方案:


It is possible to realize that using the BRep API (located in the <ObjectARX 2009 Path>\utils\brep directory): you need to traverse all the faces that are contained in your 3D solid and for each face use the AcBrFace::getFace method. It returns an AcGeSurface object from where you can use AcGeSurface::closestPointTo, passing in your input point.


使用BRep API,您需要遍历3D实体中包含的所有面,并为每个面使用AcBrFace :: getFace方法,得到AcGeSurface对象, 使用AcGeSurface :: closestPointTo获得输入点和AcGeSurface对象的最近点。



下面是ARX代码:
[C++] 纯文本查看 复制代码
static AcBr::ErrorStatus TraverseFaces(const AcBrBrep& brepEntity, const AcGePoint3d& pointToTest)
{
        AcBr::ErrorStatus returnValue = AcBr::eOk;
        // make a global face traverser
        AcBrBrepFaceTraverser brepFaceTrav;
        returnValue = brepFaceTrav.setBrep(brepEntity);
        if (returnValue != AcBr::eOk)
        {
                acutPrintf(ACRX_T("\n Error in AcBrBrepFaceTraverser::setBrep:"));
                errorReport(returnValue);
                return returnValue;
        }
        int faceCount = 0;
       while (!brepFaceTrav.done() && (returnValue == AcBr::eOk))
        {
                ++faceCount;
                AcBrFace face;
                if (brepFaceTrav.getFace(face) == AcBr::ErrorStatus::eOk)
                {
                        AcGeSurface* pSurface;
                        if (face.getSurface(pSurface) == AcBr::ErrorStatus::eOk)
                        {
                                AcGePoint3d closestPoint = pSurface->closestPointTo(pointToTest);

                                double dist = AcGeVector3d(closestPoint.asVector() - pointToTest.asVector()).length();

                                acutPrintf(L"\n - Face[%d]: closest point [%f, %f, %f]   Distance: %f", faceCount, closestPoint.x, closestPoint.y, closestPoint.z, dist);

                                delete pSurface;
                        }
                }
                returnValue = brepFaceTrav.next();
                if (returnValue != AcBr::eOk) {
                        acutPrintf(ACRX_T("\n Error in AcBrBrepFaceTraverser::next:"));
                        errorReport(returnValue);
                        return returnValue;
                }
        }
        return returnValue;
}
void TestClosestPoint(void)
{
        AcBr::ErrorStatus returnValue = AcBr::eOk;
        Acad::ErrorStatus acadReturnValue = eOk;
        AcGePoint3d pointToTest;
        // pick a point
        acedGetPoint(NULL, L"\nPick a point: ", asDblArray(pointToTest));
        // Get the subentity path for a brep
        AcDbFullSubentPath subPath(kNullSubent);
        acadReturnValue = selectEntity(AcDb::kNullSubentType, subPath);
        if (acadReturnValue != eOk)
        {
                acutPrintf(ACRX_T("\n Error in getPath: %d"), acadReturnValue);
                return;
        }
        // Make a brep entity to access the solid
        AcBrBrep brepEntity;
        returnValue = ((AcBrEntity*)&brepEntity)->set(subPath);
        if (returnValue != AcBr::eOk)
        {
                acutPrintf(ACRX_T("\n Error in AcBrBrep::set:"));
                errorReport(returnValue);
                return;
        }
        returnValue = TraverseFaces(brepEntity, pointToTest);
        if (returnValue != AcBr::eOk)
        {
                acutPrintf(ACRX_T("\n Error in TraverseFaces:"));
                errorReport(returnValue);
                return;
        }
}



下面使用XDRX API的 ACBR库函数,完成上面ARX同样的工作

3DSOLID-最近点.gif
搜狗截图20180526135921.gif

  1. (defun c:tt ()
  2.   (defun _traversface (e pnt)
  3.     (setq br (xdbr::constructor e))
  4.     (setq tr (xdbr::constructor "brepfacetraverser" br))
  5.     ;;FACE遍历
  6.     (setq face-count 0)
  7.     (xdrx_entity_delete co-ss)
  8.     (xdrx_setmark)
  9.     (while (not (xdbr::traverser:done tr));循环遍历
  10.       (if (setq face (xdbr::getpropertyvalue tr "face"));;AcBrFace对象
  11.         (progn (setq face-count  (1+ face-count)
  12.                      gface       (xdbr::getpropertyvalue face "surface") ;;得到AcGeSurface对象
  13.                      closest-pnt (xdge::getpropertyvalue gface "closestpointto" pnt);;最近点
  14.                      dist        (distance pnt closest-pnt)
  15.                )
  16.           (xdrx_object_release gface face);;释放AcBrFace、AcGeSurface
  17.           (xdrx_point_make closest-pnt)
  18.           (xdrx_entity_setcolor (entlast) 2)
  19.           (xdrx_line_make pnt closest-pnt)
  20.           (xdrx_entity_setcolor (entlast) 1)
  21.                (xdrx_prompt
  22.                  (xdrx_string_format "\n - 面[%d]: 最近点 [%f, %f, %f]   距离 %f"
  23.                                      face-count
  24.                                      (car closest-pnt)
  25.                                      (cadr closest-pnt)
  26.                                      (caddr closest-pnt)
  27.                                      dist
  28.                  )
  29.                )
  30.         )
  31.       )
  32.       (setq co-ss (xdrx_getss))
  33.       (xdbr::traverser:next tr)
  34.     )
  35.     (xdrx_object_release tr br)
  36.   )
  37.   (if (setq e (car (xdrx_entsel "\n选取3DSOLID<退出>:" '((0 . "3DSOLID")))))
  38.     (progn
  39.       (xdrx_begin)
  40.       (xdrx_sysvar_push '("osmode" 512))
  41.       (xdrx_setvar "pdmode" 35)
  42.       (while (setq pt (getpoint "\n点取测试点<退出>:"))
  43.       (_traversface e (setq pt (trans pt 1 0))))
  44.       (xdrx_end)
  45.     )
  46.   )
  47.   (princ)
  48. )


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

已领礼包: 1个

财富等级: 恭喜发财

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

使用道具 举报

已领礼包: 776个

财富等级: 财运亨通

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-20 13:05 , Processed in 0.392894 second(s), 35 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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