本文解释了如何将基于 B-Rep(例如 OdDb3dSolid、OdDbRegion 等)的 OdDb 实体和 SAT 数据转换为 BimRv DirectShape 实体。
与任何其他转换一样,此转换使用 OdBrepBuilderFiller 执行。然而,OdDb 实体拓扑与 DirectShape 实体非常不同。DirectShape 不允许周期性面和边,因此像完整球体或完整圆这样的实体是不可能的。此外,OdDb 拓扑可以有分离循环,因此没有接缝边,需要复杂的修复。转换通过中间转换为 ODA Solid Modeler 的 OdMdBody 来执行。OdMdBody 在 OdDb 和 DirectShape 之间存在限制;虽然它允许周期性面和边,但它禁止分离循环并要求接缝边。
颜色和材质转换
DirectShape 没有颜色,而是使用材质。OdDb 面材质目前不支持,但面颜色支持 RGB 和颜色索引。要转换它们,请将 OdBaseMaterialAndColorHelper 的实例传递给 OdBrepBuilderFiller。您可以使用 OdDb2BmMaterialAndColorHelper 将实体从 .dwg 文件转换为 OdMdBody,并从 OdMdBody 转换为 DirectShape。如果您使用 SAT 数据,可以使用 OdSat2MdForBmMaterialAndColorHelper 和 OdMd2BmFromSatMaterialAndColorHelper 分别将 SAT 转换为 OdMdBody,以及将 OdMdBody 转换为 DirectShape。面颜色会原样转换为 OdMdBody。DirectShape 会创建一个带有此颜色的新材质。输入实体颜色直接传递给 DirectShape,绕过 OdMdBody。
算法
以下部分包含一个转换为 DirectShape 的示例。
- 从输入文件获取 OdBrBrep。
对于 .dwg 文件,使用 brep() 方法:
对于 SAT 文件,使用 acisIn() 方法获取 OdDbEntity 或使用 ISATConverter:OdDbDatabasePtr pDwgDb = pHostApp->readFile(fileName); OdDbBlockTableRecordPtr pMs = pDwgDb->getModelSpaceId().safeOpenObject(OdDb::kForWrite); for (OdDbObjectIteratorPtr pObjIt = pMs->newIterator(); !pObjIt->done(); pObjIt->step()) { OdDbEntityPtr inputEntity = pObjIt->entity(); if (!inputEntity.isNull()) { OdBrBrep brep; BrepType bType = kOpenShell; if (inputEntity->isA() == OdDbRegion::desc()) { OdDbRegionPtr pBody = inputEntity; pBody->brep(brep); } /*other geometry types of OdDbEntity*/ /*conversion*/ } }for (unsigned idx = 0; idx < out.size(); ++idx) { OdBrBrep brep; ISATConverter* pIS = out[idx]; brep.set(pIS->getIBr()); /*conversion*/ } - 使用 OdBrepBuilderFiller 将 OdBrBrep 转换为 OdMdBody:
OdBrepBuilder mdBrepBuilder; std::unique_ptr attribSetter(createDwgAttribSetter()); initMDBrepBuilder(mdBrepBuilder, bType, attribSetter.get()); OdGeMatrix3d mx; bool hasTransform = brep.getTransformation(mx); OdBrepBuilderFiller BBFiller; BBFiller.params().setupFor(OdBrepBuilderFillerParams::kBrepAcisDwg, OdBrepBuilderFillerParams::kBrepMd); OdResult res = BBFiller.initFrom(mdBrepBuilder, brep); if (res == eOk) { mdBrepBuilder.enableValidator(false); OdMdBodyResultPtr pMdBody; try { pMdBody = OdMdBodyResult::cast(mdBrepBuilder.finish()); } catch (...) { res = eGeneralModelingFailure; } } - 将 OdMdBody 中的拓扑更改为 BimRv 格式并获取新的 OdBrBrep:
OdBrBrep mdBrep; if (eOk == res && !pMdBody.isNull()) { if (hasTransform) res = transformMdBody(pMdBody, mx); if (eOk == res) { res = convertToBimRvFormat(pMdBody); if (eOk == res) { res = getBrepFromMdBody(pMdBody, mdBrep); } } } - 将 OdBrBrep 转换为 DirectShape 并将其添加到 BimRv 数据库:
OdBrepBuilder bmBrepBuilder; res = pBmDb->appServices()->brepBuilder(bmBrepBuilder, bType); if (res == eOk) { BBFiller.params().setupFor(OdBrepBuilderFillerParams::kBrepAcisDwg, pDwgDb, pBmDb); res = BBFiller.initFrom(bmBrepBuilder, mdBrep, bmMaterialHelper); if (res == eOk) { try { OdBmGeometryPtr resultGeometry = OdBmGeometry::cast(bmBrepBuilder.finish()); if (!resultGeometry.isNull()) { OdArray aFaces; resultGeometry->getFaces(aFaces); OdArray aEdges; resultGeometry->getEdges(aEdges); if (aFaces.size() != 0 || aEdges.size() != 0) { ODBM_TRANSACTION_BEGIN(t, pBmDb) t.start(); OdBmGNodePtrArray nodes; nodes.append(resultGeometry); OdBmDirectShapePtr pDirectShape = OdBmDirectShape::createObject(); OdBmObjectId retId = pBmDb->addElement(pDirectShape); pDirectShape->setOwningElementId(pBmDb->getOwnerFamilyId()); res = pDirectShape->setShape(nodes); t.commit(); ODBM_TRANSACTION_END() } } } catch (...) { res = eGeneralModelingFailure; } } }
示例
您可以在 DwgDirectShapeImportEx 和 SatDirectShapeImportEx 示例中找到示例,这些示例随存档提供,可在 CommonApplications/BimRv 目录中找到。这些示例包含将基于 .dwg 文件中的 B-Rep 实体或 SAT 文件中的 SAT 数据的 OdDb 实体转换为 RVT 或 RFA 文件中的 DirectShape 的代码。它们需要一个空的 RFA 或 RVT 文件来获取 BimRv 的输入数据库。