在 Teigha BIM 中覆盖元素的视觉样式

众所周知,应用于元素的材质在着色模式和真实模式下是不同的。但是,此规则不适用于某些元素。

让我们看看 OdBmImposterLight 元素。下图显示了一个放置在拉伸体上的伪装光源。光源和拉伸体都具有相同的材质,在着色模式下为红色,在真实模式下为灰色。

image1

放置在拉伸体上的伪装光源

要为所需元素实现此行为,只需实现 OdBmOverriddenVisualStyle 和 OdBmOverriddenVisualStyleImpl 类的后代即可。

以下是声明:

class TB_DB_EXPORT OdBmOverriddenVisualStyleForImposterLight : public OdBmOverriddenVisualStyle {
  ODBM_DECLARE_CUSTOM_CLASS_MEMBERS(OdBmOverriddenVisualStyleForImposterLight);
public:
  virtual void overrideByDbView(const OdBmDBViewPtr&);
};

class TB_DB_EXPORT OdBmOverriddenVisualStyleForImposterLightImpl 
	: public OdBmOverriddenVisualStyleImpl {
  ODBM_DECLARE_CUSTOM_CLASS_IMPL_MEMBERS(OdBmOverriddenVisualStyleForImposterLight);
public:
  OdBmOverriddenVisualStyleForImposterLightImpl();
  virtual ~OdBmOverriddenVisualStyleForImposterLightImpl(){};
  virtual void overrideByDbView(const OdBmDBViewPtr&);
};

以及定义:

#define NEW_CONSTR2(CLASS) OdRxObjectImpl<OdBmOverriddenVisualStyleForImposterLight>::createObject()
ODTF_DEFINE_MEMBERS2(OdBmOverriddenVisualStyleForImposterLight, OdBmOverriddenVisualStyle, NULL, NULL, OdBmOverriddenVisualStyleForImposterLight::pseudoConstructor, 
                     OD_T("OdBmOverriddenVisualStyleForImposterLight"))
ODRX_DEFINE_PSEUDOCONSTRUCTOR(OdBmOverriddenVisualStyleForImposterLight, NEW_CONSTR2)


OdBmOverriddenVisualStyleForImposterLight::OdBmOverriddenVisualStyleForImposterLight(
  OdBmOverriddenVisualStyleForImposterLightImpl* pImpl) : OdBmOverriddenVisualStyle(pImpl) {
}

OdBmOverriddenVisualStyleForImposterLight::OdBmOverriddenVisualStyleForImposterLight() : 
  OdBmOverriddenVisualStyle(new OdBmOverriddenVisualStyleForImposterLightImpl) {
}

void OdBmOverriddenVisualStyleForImposterLight::overrideByDbView(const OdBmDBViewPtr& view) {
  getImpl()->overrideByDbView(view);
}

OdBmOverriddenVisualStyleForImposterLightImpl::OdBmOverriddenVisualStyleForImposterLightImpl(): OdBmOverriddenVisualStyleImpl() {
}

void OdBmOverriddenVisualStyleForImposterLightImpl::overrideByDbView(const OdBmDBViewPtr& view) {
  OdBmDBViewImpl* pView = OdBmSystemInternals::getImpl(view);
  if (pView) {
    OdGiVisualStyle& viewStyle = pView->getVisualStyle();
    (OdGiVisualStyle&)m_visualStyle = viewStyle;
    // disable textures for imposter light - will use shaded colors in realistic mode
    m_visualStyle.displayStyle().setDisplaySettingsFlag(OdGiDisplayStyle::kTextures, false);
  }
}

OdUInt32 OdBmOverriddenVisualStyleImpl::subSetAttributes(OdGiDrawableTraits* traits) const
{
  OdGiVisualStyleTraitsPtr pVsTraits = OdGiVisualStyleTraits::cast(traits);
  if (pVsTraits.get())
    pVsTraits->setOdGiVisualStyle(m_visualStyle);
 
  return OdBmObjectImpl::subSetAttributes(traits) | OdGiDrawable::kDrawableUsesNesting; //It is container;
}

请注意,您需要根据 GI 的要求在数据库中注册被覆盖的视觉样式:

OdBmSystemInternals::getImpl(pDb)->addElement(
OdBmOverriddenVisualStyleForImposterLight::createObject(),
    OdBm::OverriddenVisualStyles::ImposterLight, OdBmObjectId::kNull, false);

例如,此代码可以放在 OdBmMaterialTableNewImpl::setDocument() 方法中。

此外,您还需要为所需的类实现 subViewportDraw() 方法。

void OdBmImposterLightImpl::subViewportDraw(OdGiViewportDraw *pVd) const {
  OdBmViewportPtr pViewport = OdBmObjectId(pVd->viewportObjectId()).safeOpenObject();
  OdBmDBViewPtr pView = pViewport->getDbViewId().safeOpenObject();

  OdBmDatabase* pDb = static_cast<OdBmDatabase*>(pVd->context()->database());
  OdDbStub* pVisualStyle = 
pDb->getObjectId(OdBm::OverriddenVisualStyles::ImposterLight);
  if (pVisualStyle) {
    OdBmOverriddenVisualStylePtr pStyle = OdBmObjectId(pVisualStyle).openObject();
    pStyle->overrideByDbView(pView);
    pVd->subEntityTraits().setVisualStyle(pVisualStyle);
  }
  OdBmImposterLightInternalImpl::subViewportDraw(pVd);
}

完成。

今天就开始行动

免费试用 ODA 软件 60 天。
无风险,无需信用卡。

免费试用