马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
本帖最后由 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)
- )
|