IndexedViewportP viewPort = IViewManager::GetActiveViewSet().GetSelectedViewport(); if (viewPort == nullptr) { return false; } DgnFileP dgnFile = viewPort->GetRootModel()->GetDgnFileP(); DisplayStyleCP pDisStyle = DisplayStyleManager::FindDisplayStyleByName(L"Smooth", dgnFile); if (!pDisStyle) { return false; } int iIndex = pDisStyle->GetIndex(); ElementId eleId = 968; MSElement ele; mdlAssoc_getElement(&ele, nullptr, eleId, ACTIVEMODEL); if (SUCCESS != mdlElement_setDisplayStyle(&ele, iIndex)) { return false; } MSElementDescrP pEleDescr; mdlAssoc_getElementDescr(&pEleDescr, nullptr, eleId, ACTIVEMODEL, true); UInt32 posOld = elementRef_getFilePos(pEleDescr->h.elementRef); UInt32 posNew = mdlElmdscr_rewrite(pEleDescr, NULL, posOld); if (posOld != posNew) { return false; } return true;
您对MSElement和MSElementDescr的理解可能还没到位。如下代码测试通过:
void setElementDisplayStyle() { DgnFileP dgnFile = ISessionMgr::GetActiveDgnFile(); int styleIdx = DisplayStyleManager::GetIndexForDisplayStyle(L"Smooth", dgnFile); if (-1 == styleIdx) { mdlDialog_dmsgsPrint(L"Can not find specified display style"); return; } ElementId eleId = 1448; MSElementDescrP pEleDescr = NULL; UInt32 filePos; mdlAssoc_getElementDescr(&pEleDescr, &filePos, eleId, ACTIVEMODEL, true); if (NULL == pEleDescr) { mdlDialog_dmsgsPrint(L"Can not find specified element"); return; } MSElement ele; mdlElement_memcpy(&ele, &pEleDescr->el); mdlElement_setDisplayStyle(&ele, styleIdx); mdlElmdscr_replaceElement(&pEleDescr, &ele); mdlElmdscr_rewrite(pEleDescr, NULL, filePos); mdlElmdscr_freeAll(&pEleDescr); }
mdlElement_setDisplayStyle函数的第一个参数为什么还要mdlElement_memcpy、mdlElmdscr_replaceElement来转一下?直接由mdlAssoc_getElement得出的MSElement不行?
对于复杂元素,我们是要修改其第一个头元素。mdlElement_setDisplayStyle是通过给元素附加一个DisplayStyleIndex的Linkage来实现增加自身显示样式的,这个动作会增大头元素的尺寸(size),而原来的复杂元素中一个个元素都是紧密排列的,第一个元素被增大后后续的元素位置都需要调整。对于保存在内存区的元素描述符(MSElementDescr)来说,它是一个复杂的双向链表,我们是通过mdlElement_memcpy先从复杂元素中将第一个元素拿到另一块内存区,修改它,然后再替换回原来的内存区,这样能保持双向链表的正确性,写回磁盘时整个复杂元素也能正确被替换(其实是删除原来位置的复杂元素,在模型尾部增加新的修改过复杂元素。如果整个元素大小不变的话,是可以在原位置替换的)
Answer Verified By: 某某 某