减少导出IFC文件的开销,使用已有Body模型直接转出IFC对象。首先遇到Revit对IFC版本支持问题。Revit2023之前对IFC2.4支持不全,选择IFC2x3。IFC2x3类支持两种转换方式,一种OdDb3dSolid遍历mesh转出IFC对象,例子中有源码。另一种AdvancedBrep,无源码。通过反向解析Revit导出的IFC2x3文件,确定IFC文件中Brep节点,结合IfcModelGeometryFiller的接口形成Body转IFC2x3函数。
bool ConvertBody(FacetModeler::Body& body, OdIfc::OdIfcEntityPtr& pEnt, OdIfcModelPtr pModel)
{
OdSharedPtr<IfcModelGeometryFiller> pGemetryFiller = new IfcModelGeometryFiller(pModel);
IfcRepresentationBuilderPtr builder = IfcRepresentationBuilder::createObject(pGemetryFiller, pEnt);
OdIfc::OdIfcEntityPtr pGeoRepresntionModel = ifcCreator.GetFiller()->getGeometricRepresentationContext("Model");
if (pGeoRepresntionModel.isNull())
{
ASSERT(FALSE);
return false;
}
struct Point3dToDAIObjectId
{
Point3dToDAIObjectId(OdGePoint3d vpt, OdDAIObjectId vid) { pt = vpt; id = vid; }
OdGePoint3d pt;
OdDAIObjectId id;
};
typedef std::vector<Point3dToDAIObjectId> VecEdgePts;
VecEdgePts vecEdgePts;
auto FindCartesianPoint = [&](const OdGePoint3d& pt)->OdDAIObjectId {
for (auto it = vecEdgePts.begin(); it != vecEdgePts.end(); it++)
{
if (it->pt.isEqualTo(pt))
return it->id;
}
OdDAIObjectId id = OdDAIObjectId(ifcCreator.GetFiller()->createCartesianPoint3D(pt)->id());
Point3dToDAIObjectId ptPair(pt, id);
vecEdgePts.push_back(ptPair);
return id;
};
OdDAIObjectIds idFaces;
GeMesh::OdGeTrMesh mesh;
body.generateMesh(mesh);
OdInt32Array faceArray;
faceArray.reserve(mesh.m_aTr.logicalLength() * 4);
for (unsigned int n = 0; n < mesh.m_aTr.logicalLength(); ++n)
{
OdDAIObjectIds ids;
const GeMesh::OdGeTr& tr = mesh.m_aTr[n];
OdDAIObjectId id = FindCartesianPoint(mesh.m_aVx[tr.tr[0]]);
ids.push_back(id);
id = FindCartesianPoint(mesh.m_aVx[tr.tr[1]]);
ids.push_back(id);
id = FindCartesianPoint(mesh.m_aVx[tr.tr[2]]);
ids.push_back(id);
OdIfc::OdIfcEntityPtr pLoop = pGemetryFiller->createPolyLoop(ids);
OdIfc::OdIfcEntityPtr pOuterBound = pGemetryFiller->createFaceOuterBound(OdDAIObjectId(pLoop->id()), TRUE);
OdDAIObjectIds idBounds;
idBounds.push_back(OdDAIObjectId(pOuterBound->id()));
OdIfc::OdIfcEntityPtr pIfcFace = pGemetryFiller->createFace(idBounds);
idFaces.push_back(OdDAIObjectId(pIfcFace->id()));
}
OdIfc::OdIfcEntityPtr pClosedShell = pGemetryFiller->createClosedShell(idFaces);
OdIfc::OdIfcEntityPtr pFacetedBrep = pGemetryFiller->createFacetedBrep(OdDAIObjectId(pClosedShell->id()));
OdIfc::OdIfcEntityPtr pShapeRepresentation = builder->appendRepresentation(pFacetedBrep, pGeoRepresntionModel, OdAnsiString("Body"), OdAnsiString("Brep"));
return true;
}