要素に適用されるマテリアルが、シェーディングモードとリアリスティックモードで異なることはよく知られています。ただし、このルールは一部の要素には適用されません。
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);
}
完了。