| 
本帖最后由 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同样的工作
 
 
   
   
 
  (defun c:tt ()
  (defun _traversface (e pnt)
    (setq br (xdbr::constructor e))
    (setq tr (xdbr::constructor "brepfacetraverser" br))
    ;;FACE遍历
    (setq face-count 0)
    (xdrx_entity_delete co-ss)
    (xdrx_setmark)
    (while (not (xdbr::traverser:done tr));循环遍历
      (if (setq face (xdbr::getpropertyvalue tr "face"));;AcBrFace对象
        (progn (setq face-count  (1+ face-count)
                     gface       (xdbr::getpropertyvalue face "surface") ;;得到AcGeSurface对象
                     closest-pnt (xdge::getpropertyvalue gface "closestpointto" pnt);;最近点
                     dist        (distance pnt closest-pnt)
               )
          (xdrx_object_release gface face);;释放AcBrFace、AcGeSurface
          (xdrx_point_make closest-pnt)
          (xdrx_entity_setcolor (entlast) 2)
          (xdrx_line_make pnt closest-pnt)
          (xdrx_entity_setcolor (entlast) 1)
               (xdrx_prompt
                 (xdrx_string_format "\n - 面[%d]: 最近点 [%f, %f, %f]   距离 %f"
                                     face-count
                                     (car closest-pnt)
                                     (cadr closest-pnt)
                                     (caddr closest-pnt)
                                     dist
                 )
               )
        )
      )
      (setq co-ss (xdrx_getss))
      (xdbr::traverser:next tr)
    )
    (xdrx_object_release tr br)
  )
  (if (setq e (car (xdrx_entsel "\n选取3DSOLID<退出>:" '((0 . "3DSOLID")))))
    (progn
      (xdrx_begin)
      (xdrx_sysvar_push '("osmode" 512))
      (xdrx_setvar "pdmode" 35)
      (while (setq pt (getpoint "\n点取测试点<退出>:"))
      (_traversface e (setq pt (trans pt 1 0))))
      (xdrx_end)
    )
  )
  (princ)
)
 
 |