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的设计坐标系下的。