本文介绍了从 .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 对象并读取该文件:
//从 szSource 路径读取文件 OdNwDatabasePtr pNwDb = svcs.readFile(szSource); - .nwd (.nwc) 文件数据库仅包含一个模型的场景图。为确保创建的 OdNwDatabase 对象包含 .nwd 或 .nwc 数据,请使用 OdNwDatabase::isComposite() 方法。如果 OdNwDatabase 对象是复合对象并包含多个模型(.nwf 文件),则此方法返回 true,否则返回 false(对于 .nwd 或 .nwc 数据)。检查数据库是否仅包含一个模型:
if (pNwDb->isComposite()) { // .nwd (.nwc) 数据提取例程 }
现在 .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();