Mstn SDK中有一个C函数:mdlElmdscr_hiddenLineRemoval3,可以让我们获取多个元素消隐后的结果。此函数的原型如下所示:
StatusInt mdlElmdscr_hiddenLineRemoval3 ( LegacyPFHiddenLineOutput preFunction, LegacyPFHiddenLineOutput visibleFunction, LegacyPFHiddenLineOutput hiddenFunction, MSElementDescrCP inEdP, int viewNumber, double tolerance, BoolInt outputTo3D, BoolInt ruleLines, BoolInt calculateIntersections, BoolInt curveHiding, BoolInt surfaceHiding, unsigned int otherFlags, int zBufferResolution );
其中第四个参数inEdP指定了参与消隐的元素,inEdP的类型是MSElementDescrP,即MSElementDescr类型的指针。MSElementDescr是一个复杂的链表结构,用来表达复杂元素(需要多个MSElement才能表达的元素)的。如果参与消隐的元素有多个的话,我们需要先通过mdlElmdscr_addToChain将多个元素串连成一个MSElementDescr传递给mdlElmdscr_hiddenLineRemoval3函数,例如想要对选择集中的所有元素消隐的话,我们可以通过如下代码将选择集中的所有元素串连成一个MSElementDescr去处理:
ElementAgenda selectset; SelectionSetManager::GetManager().BuildAgenda(selectset); if (!selectset.GetCount()) { return; } MSElementDescrP elmdscr = NULL; mdlElmdscr_duplicate(&elmdscr, selectset[0].GetElementDescrCP()); for (size_t i = 1; i < selectset.GetCount(); i++) { EditElementHandleR eeh = selectset.at(i); MSElementDescrP curElmdscr = NULL; mdlElmdscr_duplicate(&curElmdscr, eeh.GetElementDescrCP()); mdlElmdscr_addToChain(elmdscr, curElmdscr); } /* ... mdlElmdscr_hiddenLineRemoval3(...,elmdscr,...) ... */ mdlElmdscr_freeAll(&elmdscr);
mdlElmdscr_hiddenLineRemoval3的第二、三个参数可以让我们设置两个回调函数,消隐的结果将通过这两个函数传递给我们,其中可见边(Visible Edges)通过第二个参数visibleFunction设置的回调函数传递给我们,隐藏边(Hidden Edges)通过第三个参数设置的回调函数传递给我们。但是有一个问题是我们如何在传递给我们的结果中区分是来自于哪个元素上消隐得来的?mdlElmdscr_hiddenLineRemoval3函数没有为我们提供相应的机制去区分,所以我们只能另寻他法了。通过测试发现接收到的消隐结果保持了原有元素的颜色,线型,线宽等Symbol属性,我们可以在消隐之前,将不同元素设置成不同的颜色,线宽(不使用线型来区分的原因是,mdlElmdscr_hiddenLineRemoval3函数将消隐结果中的隐藏边设置成“2”线型了),然后在接收消隐结果的回调函数中根据消隐结果的颜色、线宽来区分来自于哪个元素。如下所示,是我们的测试代码。程序运行之前需要先通过选择集选中若干元素,程序会将选中的元素按顺序设置不同的颜色,运行后消隐结果保持了所属元素的颜色。
int HiddenLineRemoval_visibleFunction ( MSElementDescr *edP3d, MSElementDescr *edP2d, DgnModelRefP modelRef ) { mdlElmdscr_add(edP3d); return SUCCESS; } int HiddenLineRemoval_hiddenFunction(MSElementDescrP pDescr3D, MSElementDescrP pDescr2d, DgnModelRefP modelRef) { mdlElmdscr_add(pDescr3D); return SUCCESS; } void HiddenDrawingSample() { ElementAgenda selectset; SelectionSetManager::GetManager().BuildAgenda(selectset); if (!selectset.GetCount()) { return; } ElementPropertiesSetterPtr elePropSet = ElementPropertiesSetter::Create(); EditElementHandleR eeh = selectset.at(0); elePropSet->SetColor(0); elePropSet->Apply(eeh); MSElementDescrP elmdscr = NULL; mdlElmdscr_duplicate(&elmdscr, eeh.GetElementDescrCP()); for (size_t i = 1; i < selectset.GetCount(); i++) { EditElementHandleR eehCur = selectset.at(i); elePropSet->SetColor((UInt32)i); elePropSet->Apply(eehCur); MSElementDescrP curElmdscr = NULL; mdlElmdscr_duplicate(&curElmdscr, eehCur.GetElementDescrCP()); mdlElmdscr_addToChain(elmdscr, curElmdscr); } mdlElmdscr_hiddenLineRemoval3(NULL, HiddenLineRemoval_visibleFunction, HiddenLineRemoval_hiddenFunction, elmdscr, tcb->lstvw, 0, FALSE, FALSE, TRUE, FALSE, FALSE, 0, FALSE); mdlElmdscr_freeAll(&elmdscr); }