CurveCurve::IntersectionsXY得到的交点都是从指定方向投影后的交点,而且只能是轮廓线上的交点。如果我们在三维空间下有一个任意方向的面和任意一条线,该如何获取这两者之间的真实交点呢?我们需要调用mdlSolid_XXX函数去求得交点,测试代码如下所示:
void IntersectsOfCurveAndSurface(bvector<DPoint3d>& intersectPts,ElementHandleCR eehCurve,ElementHandleCR eehSurface) { mdlSolid_beginCurrTrans(ACTIVEMODEL); BODY_TAG bodySurface; Transform tranSurface; if (SUCCESS != mdlSolid_elementToBody(&bodySurface, &tranSurface, (MSElementDescrP)eehSurface.GetElementDescrCP(), ACTIVEMODEL)) { mdlSolid_endCurrTrans(); return; } BODY_TAG bodyCurve; Transform tranCurve; if (SUCCESS != mdlSolid_elementToBody(&bodyCurve, &tranCurve, (MSElementDescrP)eehCurve.GetElementDescrCP(), ACTIVEMODEL)) { mdlSolid_endCurrTrans(); return; } Transform tranInv, tranCurveToSurface; mdlTMatrix_getInverse(&tranInv, &tranSurface); mdlTMatrix_multiply(&tranCurveToSurface, &tranInv, &tranCurve); mdlSolid_applyTransform(bodyCurve, &tranCurveToSurface); TAG_ENTITY_LIST* edgeList = NULL; mdlSolid_listCreate(&edgeList); mdlSolid_getEdgeList(edgeList, bodyCurve); int count = 0; mdlSolid_listCount(&count, edgeList); if (count < 1) { mdlSolid_freeBody(bodySurface); mdlSolid_freeBody(bodyCurve); mdlSolid_listDelete(&edgeList); mdlSolid_endCurrTrans(); return; } ENTITY_TAG edge; mdlSolid_listNthEl(&edge, edgeList, 0); CURVE_TAG curve_tag = 0L; double startParam = 0, endParam = 0; int result = mdlSolid_edgeData(NULL, NULL, NULL, NULL, &startParam, &endParam, NULL, &curve_tag, NULL, edge); TAG_ENTITY_LIST* faceList = NULL; mdlSolid_listCreate(&faceList); mdlSolid_getFaceList(faceList, bodySurface); ENTITY_TAG face; mdlSolid_listCount(&count, faceList); for (int i = 0; i < count; i++) { mdlSolid_listNthEl(&face, faceList, i); int ptNum = 0; DPoint3d* interPtP = NULL; if (SUCCESS != mdlSolid_faceIntersectCurve(&interPtP, NULL, NULL, &ptNum, face, curve_tag, startParam, endParam)) { continue; } mdlTMatrix_transformPointArray(interPtP, &tranSurface, ptNum); mdlCurrTrans_transformPointArray(interPtP, interPtP, ptNum); intersectPts.insert(intersectPts.end(), interPtP, interPtP + ptNum); delete[] interPtP; } mdlSolid_endCurrTrans(); mdlSolid_freeBody(bodySurface); mdlSolid_freeBody(bodyCurve); mdlSolid_listDelete(&faceList); mdlSolid_listDelete(&edgeList); return; }
这个函数需要三个参数,第一个参数是输出参数,其中保存了计算得到的所有交点,如果函数返回后,容器中的点数为0的话就是没有相交。第二个参数是空间曲线,第三个参数是空间曲面。函数中将曲线和面都通过mdlSolid_elementToBody函数转换为BODY_TAG类型,mdlSolid_elementToBody还返回给了我们一个变换矩阵Transform的类型实例。在使用mdlSolid_XXX函数时,需要将Mstn元素转换为ParaSolid数据结构,再转换后元素的几何数据也从Mstn的设计坐标系转换到了ParaSolid的坐标系下了。通过mdlSolid_elementToBody返回的变换矩阵,我们可以将ParaSolid坐标系下的几何数据转换到Mstn的设计坐标系下。由于曲线和曲面都转换到了各自的ParaSolid坐标系下了,所有两者之间的相对位置关系也发生了改变,所以我们要将其中一个变换到另外一个的局部ParaSolid坐标系下。这一步是通过如下代码来实现的:
Transform tranInv, tranCurveToSurface; mdlTMatrix_getInverse(&tranInv, &tranSurface); mdlTMatrix_multiply(&tranCurveToSurface, &tranInv, &tranCurve); mdlSolid_applyTransform(bodyCurve, &tranCurveToSurface);
转换以后两者在Mstn设计坐标系下的相对位置关系,就在ParaSolid坐标系下又恢复了,后面我们就可以通过mdlSolid_faceIntersectCurve函数来求得两者之间的交点了。但是求得的交点同样也是在ParaSolid坐标系下的交点,所以我们还要将其再变换会Mstn设计坐标系下。由于我们是将曲线变换到了曲面的ParaSolid局部坐标系下,所以我们通过转换曲面时返回的变换矩阵将交点变换回Mstn的设计坐标系下的。