找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 3291|回复: 21

[教学] 【AcBr库应用(五)】求直线与任意曲面、3DSOLID实体的交点

[复制链接]

已领礼包: 40个

财富等级: 招财进宝

发表于 2018-5-29 01:25:46 | 显示全部楼层 |阅读模式

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

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

×
曲面:AcDbSurface
实体:3DSOLID

ARX提供了AcGeCurveSurfInt,它可以让你获得3D曲线和曲面的交点。 AcGeCurveSurfInt构造方法或AcGeCurveSurfInt :: Set可输入曲线和曲面。 它需要AcGeSurface, 所以我们需要从AcDbSurface转换到AcGeSurface。 这需要AcBrBrep作为中间对象。

ARX实现代码如下:
[C++] 纯文本查看 复制代码
static AcGePoint3dArray Intersect(AcDbSurface* pSurface, AcGeLine3d line)
{
        AcGePoint3dArray returnPtArray;
        AcDbBody* pBody = new AcDbBody();

        // 2013
        // Acad::ErrorStatus es = pBody->setASMBody(pSurface->ASMBodyCopy());
        //before 20123
        Acad::ErrorStatus es = pBody->setBody(pSurface->body());

        //build AcBrBrep
        AcBrBrep* pBrep = new AcBrBrep();
        //
        if (AcBr::eOk == pBrep->set(*pBody))
        {
                AcBrBrepFaceTraverser* pFaceTrav = new AcBrBrepFaceTraverser;
                if (AcBr::eOk == pFaceTrav->setBrep(*pBrep))
                {
                        for (pFaceTrav->restart(); !pFaceTrav->done(); pFaceTrav->next())
                        {
                                AcBrFace face;

                                if (AcBr::eOk == pFaceTrav->getFace(face))
                                {
                                        double area = 0.0f;
                                        face.getSurfaceArea(area);

                                        acutPrintf(L"\nSurface Area: %f", area);

                                        //*****whole surface of the Brep face******        
                                        //AcGeNurbSurface nurbSurface;
                                        //face.getSurfaceAsNurb(nurbSurface);
                                        //AcGeCurveSurfInt curveSI;
                                        ////input the curve and line
                                        //curveSI.set(line,nurbSurface);
                                        ////get the count of intersect points
                                        //int count = curveSI.numIntPoints(err_1);
                                        //    if(err_1 == AcGe::kXXOk && count >0 )
                                        //    {       
                                        //        AcGeIntersectError err_2;
                                        //        for(int index = 0 ;index < count; index ++)
                                        //        {
                                        //           AcGePoint3d pt =
                                        //             curveSI.intPoint(index,err_2);      
                                        //            returnPtArray.append(pt);
                                        //        }      
                                        //      
                                        //    }
                                        //**********

                                        //****real surface of the orignal AcDbSurface       
                                        AcGeExternalBoundedSurface** nurbs = NULL;
                                        Adesk::UInt32 numNurbs = 0;
                                        face.getSurfaceAsTrimmedNurbs(numNurbs, nurbs);
                                        //*****

                                        for (Adesk::UInt32 i = 0; i < numNurbs; i++)
                                        {
                                                AcGeCurveSurfInt curveSI;
                                                AcGeIntersectError  err_1 = AcGe::kXXOk;
                                                //input the curve and line
                                                curveSI.set(line, *nurbs[i]);

                                                //get the count of intersect points
                                                int count = curveSI.numIntPoints(err_1);
                                                if (err_1 == AcGe::kXXOk && count >0)
                                                {
                                                        AcGeIntersectError err_2;
                                                        for (int index = 0; index < count; index++)
                                                        {
                                                                AcGePoint3d pt =
                                                                        curveSI.intPoint(index, err_2);
                                                                returnPtArray.append(pt);
                                                        }
                                                }
                                                delete nurbs[i];
                                        }
                                        // your responsibility to delete the
                                        // array of surfaces
                                        delete[] nurbs;
                                }
                        }
                }
                delete pFaceTrav;
        }
        delete pBrep;
        return returnPtArray;
}
static void getIntersectPts(void)
{
        ads_name ename;
        ads_point pickpt;
        AcDbObjectId objId;
        AcDbObject *pObj;

        int rc;
        // select a surface
        rc = acedEntSel(L"\nSelect Surface: ", ename, pickpt);
        if (rc != RTNORM)
        {
                if (rc != RTCAN)
                        acutPrintf(L"\nError selecting entity ");
                return;
        }
        acdbGetObjectId(objId, ename);
        acdbOpenObject(pObj, objId, AcDb::kForRead);
        AcDbSurface* pEntity1 = AcDbSurface::cast(pObj);
        if (!pEntity1)
        {
                acutPrintf(L"\nSelection Invalid...");
                pObj->close();
                return;
        }
        // call Intersect
        AcGePoint3dArray points =
                Intersect(pEntity1, AcGeLine3d(AcGePoint3d(0, 0, 0),
                        AcGePoint3d(0, 0, 1)));
        if (points.length() >0)
        {
                // iterate the points
        }
        pObj->close();
}




直线和曲面交点.gif

下面是XDRX API 的ACBR库函数的LISP实现上面ARX功能的代码:

  1. (defun c:tt ()
  2.   (defun _traversface (e ln)
  3.     (setq gln (xdge::constructor ln))
  4.     ;;构建直线几何对象AcGeLineSeg3d
  5.     (setq body (xdrx_body_make))
  6.     ;;创建一个内存AcDbBody对象
  7.     (xdrx_set_body body e)
  8.     ;;将选取的曲面或3DSOLID对象的模型数据设置到BODY对象
  9.     (setq br (xdbr::constructor body))
  10.     ;;从BODY创建AcBrBrep
  11.     (setq tr (xdbr::constructor "brepfacetraverser" br))
  12.     ;;构建Brep->Face遍历器
  13.     ;;FACE遍历
  14.     (setq i    0
  15.           ints nil
  16.     )
  17.     (while (not (xdbr::traverser:done tr))
  18.       (if (setq face (xdbr::getpropertyvalue tr "face"))
  19.         ;;当前遍历位置获得AcBrFace
  20.         (progn
  21.           (setq gface (xdbr::getpropertyvalue face "SurfaceAsTrimmedNurbs"))
  22.           ;;AcBrFace->SurfaceAsTrimmedNurbs几何对象
  23.           (setq j -1)
  24.           (repeat (length gface)
  25.             (setq gface1 (nth (setq j (1+ j)) gface))
  26.             (setq mInt (xdge::constructor "kCurveSurfaceInt" gln gface1))
  27.             ;;构建曲线和曲面求交kCurveSurfaceInt对象
  28.             (if (> (xdge::getpropertyvalue mint "numintpoints") 0)
  29.               ;;交点数大于0
  30.               (progn
  31.                 (setq ar (xdbr::getpropertyvalue face "area"))
  32.                 (xdrx_prompt (xdrx_string_format "\n发现交点,Surface[%d] Area: %f"
  33.                                                  (setq i (1+ i))
  34.                                                  ar
  35.                              )
  36.                 )
  37.                 (setq ints (cons (xdge::getpropertyvalue mint "intpoints") ints))
  38.                 ;;交点保存到全局变量
  39.               )
  40.             )
  41.           )
  42.           (xdrx_object_release face)
  43.         )
  44.       )
  45.       (xdbr::traverser:next tr)
  46.     )
  47.     (xdrx_setvar "pdmode" 35)
  48.     (xdrx_entity_setcolor (xdrx_point_make ints) 2)
  49.     (xdrx_object_release tr br body)
  50.   )
  51.   (if
  52.     (and
  53.       (setq e (car (xdrx_entsel "\n选取曲面、3DSOLID<退出>:" '((0 . "SURFACE,3DSOLID")))))
  54.       (setq ln (car (xdrx_entsel "\n选择直线<退出>:" '((0 . "LINE")))))
  55.     )
  56.      (progn (xdrx_begin) (_traversface e ln) (xdrx_end))
  57.   )
  58.   (princ)
  59. )


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

已领礼包: 194个

财富等级: 日进斗金

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

使用道具 举报

已领礼包: 769个

财富等级: 财运亨通

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

使用道具 举报

已领礼包: 4803个

财富等级: 富可敌国

发表于 2018-5-29 16:41:01 | 显示全部楼层
在2018X64+XDRX-API-2018.05.28下运行,出现
Application Error: 0 :- 参数类型错误:
请问版主是怎么回事。

点评

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

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2018-5-29 16:50:45 | 显示全部楼层
scnjlwb 发表于 2018-5-29 16:41
在2018X64+XDRX-API-2018.05.28下运行,出现
Application Error: 0 :- 参数类型错误:
请问版主是怎么回 ...

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

使用道具 举报

已领礼包: 4803个

财富等级: 富可敌国

发表于 2018-5-30 10:17:30 | 显示全部楼层
重新下载API安装后,直线与实体3DSOLID求交能正常运行了,谢谢。
但直线与曲面(EXTRUDEDSURFACE)求交不行,能不能增加该部分功能?

点评

代码只选择SURFACE,你把代码 (setq e (car (xdrx_entsel "\n选取曲面、3DSOLID:" '((0 . "SURFACE,3DSOLID"))))) 改成: (setq e (car (xdrx_entsel "\n选取曲面、3DSOLID:" '((0 . "*SURFACE,3DSOLID")  详情 回复 发表于 2018-6-4 20:36
上传下你的DWG。  详情 回复 发表于 2018-5-30 11:32
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

 楼主| 发表于 2018-5-30 11:32:21 | 显示全部楼层
scnjlwb 发表于 2018-5-30 10:17
重新下载API安装后,直线与实体3DSOLID求交能正常运行了,谢谢。
但直线与曲面(EXTRUDEDSURFACE)求交不 ...

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

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2018-6-4 20:36:19 | 显示全部楼层
scnjlwb 发表于 2018-5-30 10:17
重新下载API安装后,直线与实体3DSOLID求交能正常运行了,谢谢。
但直线与曲面(EXTRUDEDSURFACE)求交不 ...

代码只选择SURFACE,你把代码


(setq e (car (xdrx_entsel "\n选取曲面、3DSOLID<退出>:" '((0 . "SURFACE,3DSOLID")))))

改成:

(setq e (car (xdrx_entsel "\n选取曲面、3DSOLID<退出>:" '((0 . "*SURFACE,3DSOLID")))))

就可以了。

点评

我改成两个三维体..不管是否相交都返回T..这怎么回事呢  详情 回复 发表于 2020-5-14 11:22
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 2476个

财富等级: 金玉满堂

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

使用道具 举报

已领礼包: 19个

财富等级: 恭喜发财

发表于 2020-5-14 11:22:29 | 显示全部楼层
q3_2006 发表于 2020-5-14 11:17
我用版主的程序算两三维体交点...算不出来呀..

参加代码,你应该建立两个AcBrBrep,
然后循环里面用 "kSurfaceSurfaceInt"

点评

不会呢..应该说是没看懂..拜托帮我写个范例..谢谢哈  详情 回复 发表于 2020-5-14 11:23
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 2476个

财富等级: 金玉满堂

发表于 2020-5-14 11:22:30 | 显示全部楼层
XDSoft 发表于 2018-6-4 20:36
代码只选择SURFACE,你把代码

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

使用道具 举报

已领礼包: 2476个

财富等级: 金玉满堂

发表于 2020-5-14 11:23:38 | 显示全部楼层
Lisphk 发表于 2020-5-14 11:22
参加代码,你应该建立两个AcBrBrep,
然后循环里面用 "kSurfaceSurfaceInt"

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

使用道具 举报

已领礼包: 2476个

财富等级: 金玉满堂

发表于 2020-5-14 12:59:03 | 显示全部楼层
我改成两三维体求交点..提示这个..当前类不支持 numintpoints 属性查询,或参数不对. 请问哪里能查..没说明头雾水呀..

点评

求交应该是 面 , 不是点 去看看ARX手册,arxref.chm  详情 回复 发表于 2020-5-14 13:32
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

 楼主| 发表于 2020-5-14 13:32:29 | 显示全部楼层
本帖最后由 newer 于 2020-5-14 13:34 编辑
q3_2006 发表于 2020-5-14 12:59
我改成两三维体求交点..提示这个..当前类不支持 numintpoints 属性查询,或参数不对. 请问哪里能查..没说明 ...

求交应该是 面 , 不是点,由面 求 边(线), 边在求点
去看看ARX手册,arxref.chm

点评

arx门槛太高了真看不懂下不了手,拜托帮我修改一下嘛  详情 回复 发表于 2020-5-15 11:33
真的急用..麻烦帮我改一下哈..红包感谢..加我一下吧1434177703  详情 回复 发表于 2020-5-14 21:15
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 2476个

财富等级: 金玉满堂

发表于 2020-5-14 21:15:27 | 显示全部楼层
newer 发表于 2020-5-14 13:32
求交应该是 面 , 不是点,由面 求 边(线), 边在求点
去看看ARX手册,arxref.chm

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-18 11:41 , Processed in 0.333137 second(s), 68 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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