ベクトル化中のカラーパレットオーバーライドの操作

通常、データベースのグラフィックベクトル化中、ベクトライザーは、レンダリングデバイスに設定されたカラーパレットを使用して、インデックス付きカラー(.dwgデータベースのACIカラーインデックス、.dgnデータベースのDgnIndexカラーなど)を解決します。場合によっては(特定のオブジェクトの場合)、このパレットを完全にまたは部分的にオーバーライドする必要があるかもしれません。たとえば、この機能は、異なる色を持つブロックコンテンツの再作成を回避し、代わりに異なるパレット色でブロックを描画するために、ブロック挿入のベクトル化に役立つ場合があります。

パレットオーバーライドには、OdGiSubEntityTraitsクラスに2つの新しいメソッドがあります。

virtual bool pushPaletteOverride(const OdGiPalette* pOverride); 

および

virtual void popPaletteOverride();

これら2つのメソッドは常にペアで呼び出す必要があります。描画可能なオブジェクトがパレットオーバーライドをプッシュする場合、その後でpopPaletteOverrideメソッドを呼び出す必要があります。これは、安定したベクトル化結果を維持するために重要です。

エンティティベクトル化中のパレットオーバーライドの使用

この例では、描画可能なグラフィック出力でパレットオーバーライドを使用する方法を示します。

bool subWorldDraw(OdGiWorldDraw* pWd) const
{ // Create palette override
  OdGiPalettePtr pPalette = OdGiPalette::createDynamic();
  // Set first palette color (typically red for ACI) as blue.
  pPalette->setColor(1, ODRGB(0, 0, 255));
  // Inform palette that we will use this color for overriding.
  pPalette->setEntryActivity(1, true);
  // Set fifth palette color (typically blue for ACI) as red.
  pPalette->setColor(5, ODRGB(255, 0, 0));
  // Inform palette that we will use this color for overriding.
  pPalette->setEntryActivity(5, true);
  // Set up palette override
  pWd->subEntityTraits().pushPaletteOverride(pPalette);
  // Draw some geometry
  pWd->subEntityTraits().setColor(1);
  pWd->geometry().circle(OdGePoint3d::kOrigin, 10.0, OdGeVector3d::kZAxis);
  pWd->subEntityTraits().setColor(5);
  pWd->geometry().circle(OdGePoint3d::kOrigin, 15.0, OdGeVector3d::kZAxis);
  // Disable palette override
  pWd->subEntityTraits().popPaletteOverride(pPalette);
  return true;
}

この例では、パレット内の2つの色のみがオーバーライドされます。最初の色(以前は赤でした)は青にオーバーライドされ、5番目の色(以前は青でした)は赤にオーバーライドされます。その後、パレットオーバーライドをパレットオーバーライドスタックにプッシュし、2つの円を描画します。小さい円は青で描画され、もう1つの円は赤で描画されます。パレットオーバーライドを無効にすると、色が交換されます。

このコードは、デストラクタでpopPaletteOverrideメソッドを自動的に呼び出す特別なヘルパーを使用して簡素化できます。このヘルパーは、ジオメトリ描画のソースコードに多くの分岐が含まれている場合に非常に役立ちます。

  // Set up palette override
  OdGiPaletteOverrideHelper poh(pWd->subEntityTraits(), *pPalette);
  // Draw some geometry
  pWd->subEntityTraits().setColor(1);
  pWd->geometry().circle(OdGePoint3d::kOrigin, 10.0, OdGeVector3d::kZAxis);
  pWd->subEntityTraits().setColor(5);
  pWd->geometry().circle(OdGePoint3d::kOrigin, 15.0, OdGeVector3d::kZAxis);
  return true;
}

このユースケースは可能ですが、このコンテキストではジオメトリ描画に他のカラーインデックスを単純に使用できるため、あまり役立ちません。パレットオーバーライドが役立つ最適なユースケースは、オブジェクト自体を変更せずに、他の(すでに利用可能な)オブジェクトをオーバーライドされた色で描画する場合です。

たとえば、カスタムエンティティからオーバーライドされたパレット色でブロックを描画できます。

// Set up palette override
OdGiPaletteOverrideHelper poh(pWd->subEntityTraits(), *pPalette);
// Draw some geometry
OdDbDatabasePtr pDb(pWd->context()->database());
pWd->geometry().draw(OdDbBlockTable::cast(pDb->getBlockTableId().openObject())->getAt(OD_T("TestBlock"), OdDb::kForRead));

オーバーライドを伴うパレットオーバーライドの使用

パレットオーバーライドをオーバーライド機能と組み合わせて使用​​し、ベクトル化されるデータベース内のオブジェクトのすべてまたは一部のパレットをオーバーライドします。

class BlockRefDrawableOverrule : public OdGiDrawableOverrule
{
  public:
    BlockRefDrawableOverrule()
    {
      OdRxOverrule::setIsOverruling(true);
      // Attach overrule to OdDbBlockReference entity
      OdRxOverrule::addOverrule(OdDbBlockReference::desc(), this);
    }
    ~BlockRefDrawableOverrule()
    {
      OdRxOverrule::removeOverrule(OdDbBlockReference::desc(), this);
      OdRxOverrule::setIsOverruling(false);
    }

    virtual bool isApplicable(const OdRxObject* /*pOverruledSubject*/) const { return true; }

    virtual bool worldDraw(const OdGiDrawable* pSubject, OdGiWorldDraw *wd)
    {
      OdGiPalettePtr pPalette;
      // Since subSetAttributes for drawable already called we can get current drawable layer from subEntityTraits
      OdDbStub *layerId = wd->subEntityTraits().layer();
      OdDbBlockTableRecordPtr pLayer = OdDbObjectId(layerId).openObject();
      if (pLayer->getName() == OD_T("Layer1"))
      { // Set inverted palette for block references onto Layer1.
        pPalette = OdGiPalette::createDynamic();
        for (OdUInt32 nClr = 0; nClr < 256; nClr++)
        {
          ODCOLORREF clr = OdCmEntityColor::lookUpRGB((OdUInt8)nClr);
          clr = ODRGB(ODGETBLUE(clr), ODGETGREEN(clr), ODGETRED(clr));
          clr = (clr & 0xFF000000) | (~clr & 0x00FFFFFF); // Invert color avoiding alpha channel
          pPalette->setColor((OdInt32)nClr, clr);
          pPalette->setEntryActivity((OdInt32)nClr, true);
        }
      }
      else if (pLayer->getName() == OD_T("Layer2"))
      { // Set palette which exchanges blue and red color channels for block references onto Layer2.
        pPalette = OdGiPalette::createDynamic();
        for (OdUInt32 nClr = 0; nClr < 256; nClr++)
        {
          ODCOLORREF clr = OdCmEntityColor::lookUpRGB((OdUInt8)nClr);
          clr = ODRGB(ODGETBLUE(clr), ODGETGREEN(clr), ODGETRED(clr));
          // Exchange red and blue color channels.
          clr = (clr & 0xFF00FF00) | ((clr & 0x00FF0000) >> 16) | ((clr & 0x000000FF) << 16);
          pPalette->setColor((OdInt32)nClr, clr);
          pPalette->setEntryActivity((OdInt32)nClr, true);
        }
      }
      else if (pLayer->getName() == OD_T("Layer3"))
      { // Set grayscale palette override for block references onto Layer3
        pPalette = OdGiPalette::createDynamic();
        // Override first 8 palette colors using grayscale colors gradient.
        pPalette->install(OdGiGrayRamp::createDynamic(8));
      }
      // Set up palette override
      if (!pPalette.isNull())
        wd->subEntityTraits().pushPaletteOverride(pPalette);
      // Call subWorldDraw of original entity
      const bool bResult = OdGiDrawableOverrule::worldDraw(pSubject, wd);
      // Pop palette override
      if (!pPalette.isNull())
        wd->subEntityTraits().popPaletteOverride();
      return bResult; 
    }
};

このクラスは、コンストラクタでオーバーライドを有効にし、デストラクタで無効にします。ベクトル化される各ブロック参照について、worldDrawメソッドが呼び出され、パレットオーバーライドをパレットオーバーライドスタックに配置し、元のエンティティ描画メソッドを呼び出し、スタックからパレットオーバーライドを削除します。

この例では、元のエンティティのレイヤー名を使用して、どのパレットオーバーライドをスタックに配置する必要があるかを理解しています。これは可能なユースケースの1つです。

パレットオーバーライドを使用したレンダリングの例:

image1

 

この例では、異なるネストされたエンティティに最初の6つのパレットインデックスカラーを使用するブロック参照があります(元の色は画像の左上隅に表示されています)。

「Layer1」に配置されたブロック参照の場合、パレット内の256色すべてを反転させます(結果は画像の右上隅に表示されています)。

「Layer2」に配置されたブロック参照の場合、パレットカラーの赤と青のカラーチャネルを交換します(結果は画像の左下隅に表示されます)。

「Layer3」に配置されたブロック参照の場合、グレースケールグラデーションジェネレーターを使用して、パレットオーバーライドの最初の8色を塗りつぶします(結果は画像の右下隅に表示されます)。

結論

この機能は、すべてのODAベクトル化モジュールでサポートされています。ODA 19.4中間リリース以降利用可能であり、すべてのODA製品で使用できます。

今すぐ始める

ODAソフトウェアを60日間無料でお試しください。
リスクなし、クレジットカード不要。

無料で試す