.nwd (.nwc) ファイルからデータを抽出する

この記事では、.nwd (.nwc) ファイルから以下のデータを抽出する手順について説明します。

  • ジオメトリ オブジェクト
  • マテリアル
  • シーンのパラメータ

この手順は OdSimpleLoader サンプルアプリケーションに基づいており、以下の主要なステップが含まれています。

  1. ODA BimNv SDK ライブラリを初期化します。
  2. .nwd (.nwc) ファイルをロードします。
  3. ジオメトリ データを抽出します。
  4. シーン パラメータを抽出します。
  5. ODA BimNv SDK ライブラリを初期化解除します。

ODA BimNv SDK ライブラリの初期化

BimNv SDK の機能を使用する前に、ライブラリを初期化する必要があります。

odrxInitialize(&svcs);
  ::odrxDynamicLinker()->loadModule(sNwDbModuleName, false);

.nwd (.nwc) ファイルをロードする

  1. .nwd (.nwc) ファイルのテクスチャを含むフォルダがある場合は、ファイルをロードする前に OdNwHostAppServices::setTextureDirectoryPath() メソッドを使用してフォルダパスを指定します。
    void OdNwHostAppServices::setTextureDirectoryPath(const OdString& path, bool rename_path);
  2. .nwd (.nwc) ファイルをロードするには、OdNwDatabase オブジェクトを作成し、ファイルを読み込みます。
    //read file by path from szSource
    OdNwDatabasePtr pNwDb = svcs.readFile(szSource);
  3. .nwd (.nwc) ファイルデータベースには、1つのモデルのみのシーングラフが含まれています。作成された OdNwDatabase オブジェクトが .nwd または .nwc データを含んでいることを確認するには、OdNwDatabase::isComposite() メソッドを使用します。このメソッドは、OdNwDatabase オブジェクトが複合であり、複数のモデル (.nwf ファイル) を含む場合は true を返し、それ以外の場合 (.nwd または .nwc データの場合) は false を返します。データベースにモデルが1つだけ含まれていることを確認します。
    if (pNwDb->isComposite())
      {
        // .nwd (.nwc) data extraction routine
      }

.nwd (.nwc) ファイルがデータベースオブジェクトにロードされたので、データの抽出に進むことができます。

ジオメトリデータを抽出する

モデル階層内では、各項目 (ノード) は OdNwModelItem オブジェクトによって表されます。モデル階層には、ルートノードとその子が含まれており、これらはレイヤー、複合オブジェクト、または単一のジオメトリオブジェクトである場合があります。モデルグラフの末端ノードはジオメトリオブジェクトです。

ジオメトリデータを含むノードを見つけるには、データベースのモデルを取得し、次にモデル階層のルート項目を取得して、子ノードがジオメトリデータを含むかどうかを確認しながら再帰的に反復処理します。

OdNwObjectId modelItemRootId = pNwDb->getModelItemRootId();
if (!modelItemRootId.isNull())
  OdNwModelItemPtr pModelItemRoot = modelItemRootId.safeOpenObject();

  1. OdNwDatabase::getModels(OdNwObjectIdArray&) メソッドを使用してデータベースのモデルを取得します。

    OdNwObjectIdArray aModels;
    pNwDb->getModels(aModels);
    OdNwModelPtr pModel = aModels[0].openObject();
  2. OdNwModel::getModelItemRootId() を使用して、モデル階層のルートノードを取得します。

    OdNwObjectId modelItemRootId = pModel->getRootItem();
    if (!modelItemRootId.isNull())
      OdNwModelItemPtr pModelItemRoot = modelItemRootId.safeOpenObject();

  3. 特定のノードの祖先、子孫、子、および親を、それぞれ getAncestors()、getDescendants()、getChildren()、および getParent() メソッドを使用して取得します。
    ノードがジオメトリデータを含むかどうかを確認するには、OdNwModelItem::hasGeometry() メソッドを使用します。
    OdSimpleLoader サンプルアプリケーションの次のメソッドは、ルートノードによってジオメトリデータを含むノードを再帰的に検索し、それらを配列に書き込みます。

    OdResult getGeometryNodesByRoot(OdNwModelItemPtr pRoot, OdArray<OdNwModelItemPtr>& aHasGeomNodes)
    {
      OdNwObjectIdArray aRootChildren;
      OdResult res = pRoot->getChildren(aRootChildren);
      if (res!= eOk)
        return res;
      if (pRoot->hasGeometry())
        aHasGeomNodes.push_back(pRoot);
      for (OdNwObjectIdArray::const_iterator itRootChildren = aRootChildren.begin(); itRootChildren != aRootChildren.end(); ++itRootChildren)
      {
        if (!itRootChildren->isNull())
        {
          OdNwModelItemPtr pRootChildren = itRootChildren->safeOpenObject();
          res = getGeometryNodesByRoot(pRootChildren, aHasGeomNodes);
          if (res != eOk)
            return res;
        }
      }
      return eOk;
    }

ジオメトリノードの配列を取得したら、それぞれのジオメトリコンポーネントを取得できます。ジオメトリコンポーネントは、ジオメトリフラグメント (ジオメトリオブジェクト自体を含む) と、コンポーネントに適用されるマテリアルおよび透明度を含む OdNwComponent オブジェクトによって表されます。

for (OdArray&lt;OdNwModelItemPtr&gt;::iterator itHasGeomNode = aHasGeometryNodes.begin(); itHasGeomNode != aHasGeometryNodes.end(); ++itHasGeomNode)
{
  OdNwObjectId compId = (*itHasGeomNode)->getGeometryComponentId();
  OdNwComponentPtr pComp = compId.safeOpenObject();
  // Actions with geometry components, for example, getting materials, geometry fragments etc.
}
Extract Geometry Fragments of Geometry Components

各 OdNwComponent オブジェクトについて、ジオメトリフラグメントの配列を取得できます。

OdNwObjectIdArray aCompFragIds;
pComp->getFragments(aCompFragIds);

各フラグメントについて、変換行列、ジオメトリタイプ、およびジオメトリオブジェクト自体を取得できます。

OdGeMatrix3d trMat = pFrag->getTransformation();
OdNwGeometryPtr pGeometry = pFrag->getGeometryId().safeOpenObject();
if (pGeometry->isA() == OdNwGeometryLineSet::desc())
  OdNwGeometryLineSetPtr pGeomertyLineSet = pGeometry;
else if (pGeometry->isA() == OdNwGeometryEllipticalShape::desc())
  OdNwGeometryEllipticalShapePtr pGeometryEllipticalShape = pGeometry;
else if (pGeometry->isA() == OdNwGeometryMesh::desc())
  OdNwGeometryMeshPtr pGeometrMesh = pGeometry;
else if (pGeometry->isA() == OdNwGeometryPointSet::desc())
  OdNwGeometryPointSetPtr pGeometryPointSet = pGeometry;
else if (pGeometry->isA() == OdNwGeometryText::desc())
  OdNwGeometryTextPtr pGeometrText = pGeometry;
else if (pGeometry->isA() == OdNwGeometryCylinder::desc())
  OdNwGeometryCylinderPtr pGeometrCyl = pGeometry;

各ジオメトリオブジェクトには、対応する「get」メソッドを使用して取得できる独自の属性セットがあります。次のコードは、線セット、楕円、メッシュ、点セット、テキスト、および円柱オブジェクトの属性を取得する方法を示しています。

// Line set
OdNwVerticesDataPtr pVerticesData = pGeomertyLineSet->getVerticesData();
OdGePoint3dArray aVertexes = pVerticesData->getVertices();
OdUInt32Array aColors = pVerticesData->getColors();
OdUInt16Array aVertexPerLine = pGeomertyLineSet->getVerticesCountPerLine();

// Ellipse
OdGePoint3d origin = pGeometryEllipticalShape->getOrigin();
OdGeVector3d xVector = pGeometryEllipticalShape->getXVector();
double Radius = pGeometryEllipticalShape->getRadius();
OdGeVector3d yVector = pGeometryEllipticalShape->getYVector();

// Mesh
OdNwVerticesDataPtr pVerticesData = pGeometrMesh->getVerticesData();
OdGePoint3dArray aVertexes = pVerticesData->getVertices();
OdUInt32Array aColors = pVerticesData->getColors();
OdGeVector3dArray aNormales = pVerticesData->getNormals();
OdGePoint2dArray aUvParams = pVerticesData->getTexCoords();
OdUInt16Array aVertexPerLine = pGeometrMesh->getVerticesPerFace();
OdUInt16Array aIndexes = pGeometrMesh->getIndices();
OdArray aFaces = pGeometrMesh->getTriangles();

// Point set
OdNwVerticesDataPtr pVerticesData = pGeometryPointSet->getVerticesData();
OdGePoint3dArray aVertexes = pVerticesData->getVertices();
OdUInt32Array aColors = pVerticesData->getColors();

// Text
OdGePoint3d lefPoint = pGeometrText->getLeftPoint();
OdGePoint3d rightPoint = pGeometrText->getRightPoint();
OdGeMatrix3d textTransform = pGeometrText->getTextTransform();
OdString text = pGeometrText->getText();
OdNwObjectId textStyleId = pGeometrText->getTextStyleId();
if (textStyleId)
{
  OdNwTextStylePtr textStyle = textStyleId.openObject();
  OdString typeFace = textStyle->getTypeFace();
  bool isItalic = textStyle->getStyle();
  double textSize = textStyle->getFontHeight();
}

// Cylinder
double radius = pGeometryCyl->getRadius();
OdGePoint3d topCenter = pGeometryCyl->getTopCenter();
OdGePoint3d bottomCenter = pGeometryCyl->getBottomCenter();
OdGeVector3d xAxis = pGeometryCyl->getXAxis();
OdGeVector3d yAxis = pGeometryCyl->getYAxis();

 

ジオメトリコンポーネントのマテリアルを抽出する

ジオメトリコンポーネントのマテリアルを抽出するには、OdNwComponent::getMaterialId() メソッドを使用します。マテリアルについては、アンビエント、ディフューズ、スペキュラ、エミッシブカラー、透明度、光沢の値などの属性を取得できます。

OdNwObjectId materilId = pComp->getMaterialId();
OdNwMaterialPtr pMaterial = materilId.safeOpenObject();
OdNwColor diffuse = pMaterial->getDiffuse();
OdNwColor ambient = pMaterial->getAmbient();
OdNwColor specular = pMaterial->getSpecular();
OdNwColor emissive = pMaterial->getEmissive();
float transparency = pMaterial->getTransparency();
float shininess = pMaterial->getShininess();

マテリアルにテクスチャが適用されている場合、テクスチャに関する追加情報を取得できます。

  • 色合いと透過色
  • 拡散、鏡面反射、および反射強度値
  • 埋め込みテクスチャ用のビットマップファイル
  • テクスチャマッパーからのデータ: バンプ、拡散、不透明度、パターン

次のコードは、マテリアルに適用されたテクスチャのデータを取得する方法を示しています。

OdNwTexturePtr pTextureMaterial = pMaterial;
  pTextureMaterial->getTint(tempColor);
  pTextureMaterial->getTransmitColor(tempColor);
  double diffuseIntensity = pTextureMaterial->getDiffuseIntensity();
  double specularIntensity = pTextureMaterial->getSpecularIntensity();
  double reflectIntensity = pTextureMaterial->getReflectIntensity();
  if (pTextureMaterial->isHaveBitmap())
    OdGiRasterImagePtr pRasterImg = pTextureMaterial->getBitmap();

次のコードは、テクスチャマッパーのデータを取得する方法を示しています。

OdString diffusePath = pTextureMaterial->getStringValue(NwTextureValueType::diffuse_path);
double diffuseScaleXValue = pTextureMaterial->getDoubleValue(NwTextureValueType::diffuse_scale_x_value);
NwModelUnits::Enum diffuseScaleXUnit = pTextureMaterial->getUnitValue(NwTextureValueType::diffuse_scale_x_unit);
double diffuseScaleYValue = pTextureMaterial->getDoubleValue(NwTextureValueType::diffuse_scale_y_value);
NwModelUnits::Enum diffuseScaleYUnit = pTextureMaterial->getUnitValue(NwTextureValueType::diffuse_scale_y_unit);
double diffuseOffsetXValue = pTextureMaterial->getDoubleValue(NwTextureValueType::diffuse_offset_x_value);
NwModelUnits::Enum diffuseOffsetXUnit = pTextureMaterial->getUnitValue(NwTextureValueType::diffuse_offset_x_unit);
double diffuseOffsetYValue = pTextureMaterial->getDoubleValue(NwTextureValueType::diffuse_offset_y_value);
NwModelUnits::Enum diffuseOffsetYUnit = pTextureMaterial->getUnitValue(NwTextureValueType::diffuse_offset_y_unit);
OdGiRasterImagePtr pDiffuseRasterImg = pTextureMaterial->getRasterImageValue(NwTextureValueType::diffuse_raster_image);
  

シーンパラメータの抽出

ジオメトリデータに加えて、.nwd (.nwc) ファイルデータベースからシーンのパラメータを抽出することもできます。

次のコードは、データベースからシーンの背景色を取得する方法を示しています。

OdNwObjectId bgId = pNwDb->getBackgroundElementId();
OdNwBackgroundElementPtr pBackGround = bgId.safeOpenObject();
switch (pBackGround->getBackgroundType())
{
  case NwBackgroundType::PLAIN:
  {
    OdNwColor cPlain;
    pBackGround->getPlainColor(cPlain);
    break;
  }
  case NwBackgroundType::GRADUATED:
  {
    OdNwColor cTop, cBottom;
    pBackGround->getGraduatedColor(cTop, cBottom);
    break;
  }
  case NwBackgroundType::HORIZON:
  {
    OdNwColor cSkyColor, cHorizonSkyColor, cHorionGround, cGround;
    pBackGround->getHorizonColor(cSkyColor, cHorizonSkyColor, cHorionGround, cGround);
    break;
  }
  default:
    break;
}

次のコードは、現在の視点の設定(ワールドアップベクトル、カメラパラメータ(位置、回転、焦点距離、角速度、線速度など)、視点名、投影タイプ、照明タイプなど)を取得する方法を示しています。

OdNwObjectId curViewId = pNwDb->getCurrentViewId();
OdNwViewpointPtr pCurView = curViewId.safeOpenObject();
OdGePoint3d position = pCurView->getPosition();
OdGeQuaternion rotate = pCurView->getRotation();
 
if (pCurView->hasFocalDistance())
  double focalDistance = pCurView->getFocalDistance();
 
if (pCurView->hasWorldUpVector())
  OdGeVector3d worldUpVector = pCurView->getWorldUpVector();
 
NwViewType::Enum projection = pCurView->getProjection();
 
if (pCurView->hasAngularSpeed())
  double angularSpeed = pCurView->getAngularSpeed();
 
double nearDistance = pCurView->getNearDistance();
double farDistance = pCurView->getFarDistance();
 
if (pCurView->hasLighting())
  NwLightType::Enum lighting = pCurView->getLighting();
 
if (pCurView->hasLinearSpeed())
  double linearSpeed = pCurView->getLinearSpeed();
 
if (pCurView->hasRenderStyle())
  NwModeType::Enum renderStyle = pCurView->getRenderStyle();
 
double heightField = pCurView->getHeightField();
double horizontalScale = pCurView->getHorizontalScale();
OdString avatar = pCurView->getAvatar();
NwCameraMode::Enum viewerCamerMode = pCurView->getViewerCameraMode();

ODA BimNv SDKライブラリの初期化解除

抽出ルーチンが完了したら、BimNv SDKライブラリを初期化解除します。

::odrxDynamicLinker()->unloadUnreferenced();
::odrxUninitialize();

今すぐ始める

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

無料で試す