[ブログに戻る](/ja/blog) # .nwd (.nwc) ファイルからデータを抽出する

Vadim Asandiy 2月 11, 2022 [\#BimNv](/ja/blog/tag/bimnv) [\#getting started](/ja/blog/tag/getting-started)

<a class="a2a_button_facebook"></a><a class="a2a_button_twitter"></a><a class="a2a_button_linkedin"></a>

この記事では、.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&amp;) メソッドを使用してデータベースのモデルを取得します。  

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

     OdNwObjectId modelItemRootId = pModel-&gt;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;
    }
    ```

     `<odnwmodelitemptr></odnwmodelitemptr>`

ジオメトリノードの配列を取得したら、それぞれのジオメトリコンポーネントを取得できます。ジオメトリコンポーネントは、ジオメトリフラグメント (ジオメトリオブジェクト自体を含む) と、コンポーネントに適用されるマテリアルおよび透明度を含む 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日間無料でお試しください。  
リスクなし、クレジットカード不要。**

[無料で試す](https://www.opendesign.com/ja/free-trial)
