この記事では、.nwd (.nwc) ファイルから以下のデータを抽出する手順について説明します。
- ジオメトリ オブジェクト
- マテリアル
- シーンのパラメータ
この手順は OdSimpleLoader サンプルアプリケーションに基づいており、以下の主要なステップが含まれています。
- ODA BimNv SDK ライブラリを初期化します。
- .nwd (.nwc) ファイルをロードします。
- ジオメトリ データを抽出します。
- シーン パラメータを抽出します。
- ODA BimNv SDK ライブラリを初期化解除します。
ODA BimNv SDK ライブラリの初期化
BimNv SDK の機能を使用する前に、ライブラリを初期化する必要があります。
odrxInitialize(&svcs);
::odrxDynamicLinker()->loadModule(sNwDbModuleName, false);
.nwd (.nwc) ファイルをロードする
- .nwd (.nwc) ファイルのテクスチャを含むフォルダがある場合は、ファイルをロードする前に OdNwHostAppServices::setTextureDirectoryPath() メソッドを使用してフォルダパスを指定します。
void OdNwHostAppServices::setTextureDirectoryPath(const OdString& path, bool rename_path); - .nwd (.nwc) ファイルをロードするには、OdNwDatabase オブジェクトを作成し、ファイルを読み込みます。
//read file by path from szSource OdNwDatabasePtr pNwDb = svcs.readFile(szSource); - .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();
- OdNwDatabase::getModels(OdNwObjectIdArray&) メソッドを使用してデータベースのモデルを取得します。
OdNwObjectIdArray aModels;
pNwDb->getModels(aModels);
OdNwModelPtr pModel = aModels[0].openObject(); -
OdNwModel::getModelItemRootId() を使用して、モデル階層のルートノードを取得します。
OdNwObjectId modelItemRootId = pModel->getRootItem();
if (!modelItemRootId.isNull())
OdNwModelItemPtr pModelItemRoot = modelItemRootId.safeOpenObject(); -
特定のノードの祖先、子孫、子、および親を、それぞれ 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<OdNwModelItemPtr>::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();