众所周知,应用于元素的材质在着色模式和真实模式下是不同的。但是,此规则不适用于某些元素。
让我们看看 OdBmImposterLight 元素。下图显示了一个放置在拉伸体上的伪装光源。光源和拉伸体都具有相同的材质,在着色模式下为红色,在真实模式下为灰色。
放置在拉伸体上的伪装光源
要为所需元素实现此行为,只需实现 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);
}
完成。