消隐结果如何区分不同元素


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);
}