この記事では、ジオメトリセクショニングコールバックの使用例を紹介します。これはシリーズの2番目の記事です。詳細を含む最初の記事については、パート1を参照してください。
この例では、4つの3Dオブジェクトを含む以下のモデルを使用します。
各オブジェクトは、異なる色で独自のレイヤーに配置されています。
この例では、レイヤー名からレイヤー番号を使用します。まず、コールバック関数実装を含む OdGiClippedGeometryOutputCallback クラスを継承した独自のクラスを実装します。
struct ClippingCallback : public OdGiClippedGeometryOutputCallback
{
static const bool pSectVis[4], pCutVis[4];
static const OdUInt16 pSectClr[4], pCutClr[4];
virtual bool clippedGeometryOutputCallbackProc(OdGiClippedGeometryOutput &pGeomOutput, const OdGiConveyorContext &pDrawContext)
{
OdDbEntity* pEnt = OdDbEntity::cast(pDrawContext.currentDrawable());
if (pEnt)
{
const OdString layer = pEnt->layer();
if (layer.left(5) == OD_T("Layer"))
{
const int lrNum = int(layer.getAt(5) - '0') - 1;
const bool bCutting = pGeomOutput.isA() == OdGiCuttedGeometryOutput::desc();
const bool *pVis = (bCutting) ? pCutVis : pSectVis;
const OdUInt16 *pClr = (bCutting) ? pCutClr : pSectClr;
pGeomOutput.setTraitsOverrideFlags(pGeomOutput.traitsOverrideFlags() | OdGiSubEntityTraitsChangedFlags::kColorChanged);
pGeomOutput.traitsOverrides().setColor(pClr[lrNum]);
return pVis[lrNum];
}
}
return true;
}
ClippingCallback() {}
};
clippedGeometryOutputCallbackProc() メソッドの実装では、4つの静的配列を呼び出します。
- bool pSectVis[4] — セクションジオメトリの可視性を含みます。
- bool pCutVis[4] — カットジオメトリの可視性を含みます。
- OdUInt16 pSectClr[4] — セクションジオメトリの色インデックスを含みます。
- OdUInt16 pCutClr[4] — カットジオメトリの色インデックスを含みます。
これらの配列のインデックスとしてレイヤー番号を使用します。このコールバックは、セクション出力ジオメトリだけでなく、カットジオメトリ出力に対しても呼び出されるため、pGeomOutputがカットジオメトリ出力であるかどうかを確認し、その後適切な配列を使用してジオメトリの色を変更し、ジオメトリの可視性フラグを返します。
セクション/カットジオメトリコールバックを構築し、ジオメトリクリッピング境界とともに設定します。
// Construct our callback object
OdGiClippedGeometryOutputCallbackPtr pSectionCallback = OdRxObjectImpl<ClippingCallback>::createObject();
// Construct clipping boundary with section planes
OdGiPlanarClipBoundary bnd; bnd.setClipPlanes(clipPlanes);
bnd.setSectionGeometryOutput(OdGiSectionGeometryOutput::createObject());
{ OdGiCuttedGeometryOutputPtr pTraitsSets = OdGiCuttedGeometryOutput::createObject();
pTraitsSets->setTraitsOverrideFlags(OdGiSubEntityTraitsChangedFlags::kTransparencyChanged);
pTraitsSets->traitsOverrides().setTransparency(OdCmTransparency(0.5));
bnd.setCuttedGeometryOutput(pTraitsSets);
}
// Setup our callback object
bnd.sectionGeometryOutput()->setGeometryProcessingCallback(pSectionCallback);
bnd.cuttedGeometryOutput()->setGeometryProcessingCallback(pSectionCallback);
// Setup viewport clipping
OdGiClipBoundary emptyBoundary;
::odgiEmptyClipBoundary(emptyBoundary);
pGsView->setViewport3dClipping(&emptyBoundary, &bnd);
このコードは、以前のセクション記事およびカットジオメトリ記事のコード例とほぼ同じです。ここでは、カットジオメトリを半透明にするために、透明度の上書きをさらに設定しています。そうしないと、ジオメトリセクションが表示されません。
まず、すべてのレイヤーでジオメトリの可視性をtrueに設定し、すべてのセクションとカットジオメトリを表示させます。そして、各レイヤーに異なる色を設定します。
const bool ClippingCallback::pSectVis[4] = { true, true, true, true };
const bool ClippingCallback::pCutVis[4] = { true, true, true, true };
const OdUInt16 ClippingCallback::pSectClr[4] = { 4, 32, 220, 81 };
const OdUInt16 ClippingCallback::pCutClr[4] = { 231, 20, 171, 9 };
生成された画像は次のようになります。
ご覧のとおり、すべてのオブジェクトについて、セクションとカットジオメトリが異なる色で生成されました。これで、一部のオブジェクトに対してジオメトリの種類(カットまたはセクション)をさらに無効にすることができます。
const bool ClippingCallback::pSectVis[4] = { true, false, false, true };
const bool ClippingCallback::pCutVis[4] = { true, true, false, false };
const OdUInt16 ClippingCallback::pSectClr[4] = { 4, 32, 220, 81 };
const OdUInt16 ClippingCallback::pCutClr[4] = { 231, 20, 171, 9 };
結果の画像は次のようになります。
ご覧のとおり、最初のオブジェクト(円錐)は、セクションジオメトリとカットジオメトリの両方が有効になっているため、それらを使用して描画されます。2番目のオブジェクト(球)は、セクションジオメトリなしで描画されますが、カットジオメトリは有効になっています。3番目のオブジェクトはクリップされますが、セクションジオメトリとカットジオメトリの両方の出力は無効になっています。そして、最後のオブジェクト(トーラス)はセクションジオメトリのみで描画されます。
この簡単な例は、クリッピングジオメトリコールバックを使用して、さまざまなグラフィックシーンオブジェクトの出力ジオメトリ動作を構成する方法を示しています。
結論
クリップされたジオメトリ出力コールバックは、データベースオブジェクトの特性に応じて、セクションおよびカットジオメトリの出力動作を構成する簡単な方法を提供します。この柔軟な機能により、すべてのソフトウェアニーズに合わせてクリップされたグラフィックシーン全体を構成できます。