本文介绍如何利用IfcOpenShell读取IFC文件中的几何数据并生成网格或BREP。 一、IfcOpenShell简介 IfcOpenShell是一个用于处理IFC数据的库,采用LGPL3。0(自由和开源)许可。 IfcOpenShell的功能包括:解析ifc从ifc表示创建几何体使用pythonOCC显示几何体提供Blender的Ifc导入器提供3dsMax的Ifc导入器将几何体转换为多种格式 一些使用IfcOpenShell的项目包括:FreeCAD:参数化CAD建模器,包括BIM工作台BIMserver:多用户自托管BIM平台,带有插件生态系统以查看、分析、合并等 在本文中,我们将使用一个从ifc实体生成网格体的函数,在我们的例子中是IfcWall,看看我们可以得到什么结果。二、获取原始IFC文件 首先使用FreeCAD创建一个简单墙并导出为。ifc文件: 先决条件:已安装IfcOpenShell。此处使用的版本:0。6。0a1三、IFC转网格体 首先我们需要引入ifcopenshell并打开ifc文件:importifcopenshellfromifcopenshellimportgeomdefreadgeom(ifcpath):ifcfileifcopenshell。open(ifcpath)settingsgeom。settings() geom。settings用于设置转换选项。默认情况下,ifcopenshell生成具有顶点、边和面的网格。 ifcfile。bytype(IfcClass)是获取所选类(包括子类)的所有元素的一种非常方便的方法。因此,如果使用IfcBuildingElement,它还将包括IfcWall、IfcWindow、IfcSlab、IfcBeam等 geom。createshape(settings,ifcentity)是将ifc实体转换为网格的函数。我们可以观察到顶点存储在单个元组中,而不是xyz三元组。边和面也一样。forifcentityinifcfile。bytype(IfcWall):shapegeom。createshape(settings,ifcentity)iosstandsforIfcOpenShelliosverticesshape。geometry。vertsiosedgesshape。geometry。edgesiosfacesshape。geometry。facesIfcOpenShellstoreverticesinasingletuple,sameforedgesandfacesprint(iosvertices)print(iosedges)print(iosfaces)Abovewillresultin:(0。0,0。0,0。0,0。0,0。0,3。0,10。0,0。0,0。0,10。0,0。0,3。0,10。0,0。2,0。0,10。0,0。2,3。0,0。0,0。2,0。0,0。0,0。2,3。0)(0,1,1,3,0,2,2,3,2,3,2,4,3,5,4,5,4,5,5,7,4,6,6,7,6,7,0,6,1,7,0,1,0,6,0,2,4,6,2,4,1,7,1,3,5,7,3,5)(1,0,3,3,0,2,3,2,4,5,3,4,5,4,7,7,4,6,7,6,0,1,7,0,0,6,2,2,6,4,3,7,1,5,7,3) 很明显,顶点是x,y,z一个接一个的三元组。但是如何定义边和面呢?边是由2个顶点包围的线,但我们看到的值不是顶点。网格中的面是由3个顶点和3条边界定的三角形表面。如果我们制作一组边和面值,我们会得到一组长度为8的值。print(set(iosedges))print(set(iosfaces))Abovewillresultin:{0,1,2,3,4,5,6,7}{0,1,2,3,4,5,6,7} 如果我们按3个值(x,y,z)对顶点进行分组,按2个值(vertex1,vertex2)对边进行分组,按3个值对面进行分组(3个顶点或3条边),我们会看到我们的墙几何体由8个顶点、24条边和12个面定义。边和面值都是顶点索引。LetsparseitandprepareitforFreeCADimportvertices〔FreeCAD。Vector(iosvertices〔i:i3〕)foriinrange(0,len(iosvertices),3)〕edges〔iosedges〔i:i2〕foriinrange(0,len(iosedges),2)〕faces〔tuple(iosfaces〔i:i3〕)foriinrange(0,len(iosfaces),3)〕print(fThis{ifcentity。isa()}hasbeendefinedby{len(vertices)}vertices,{len(edges)}edgesand{len(faces)}faces)print(vertices)print(edges)print(faces)Abovewillresultin:ThisIfcWallhasbeendefinedby8vertices,24edgesand12faces〔(0。0,0。0,0。0),(0。0,0。0,3。0),(10。0,0。0,0。0),(10。0,0。0,3。0),(10。0,0。2,0。0),(10。0,0。2,3。0),(0。0,0。2,0。0),(0。0,0。2,3。0)〕〔(0,1),(1,3),(0,2),(2,3),(2,3),(2,4),(3,5),(4,5),(4,5),(5,7),(4,6),(6,7),(6,7),(0,6),(1,7),(0,1),(0,6),(0,2),(4,6),(2,4),(1,7),(1,3),(5,7),(3,5)〕〔(1,0,3),(3,0,2),(3,2,4),(5,3,4),(5,4,7),(7,4,6),(7,6,0),(1,7,0),(0,6,2),(2,6,4),(3,7,1),(5,7,3)〕return{vertices:vertices,edges:edges,faces:faces} 当然FreeCAD已经有更好的方法来导入IfcWall,但让我们使用自己的网格来生成几何图形:importFreeCADimportFreeCADGuiimportMeshifnamemain:meshvaluesreadgeom(homecyrilgitpythoncvc。netIfcOpenShellSamplesWall。ifc)CreateaFreeCADgeometry。AFreeCADcantakeverticesandfacesasinputmeshMesh。Mesh((meshvalues〔vertices〕,meshvalues〔faces〕))Ifclenghtinternalunit:meter。FreeCADinternalunit:mm。scalefactor1000matrixFreeCAD。Matrix()matrix。scale(scalefactor,scalefactor,scalefactor)mesh。transform(matrix)AllowyoutoembedFreeCADinpythonhttps:www。freecadweb。orgwikiEmbeddingFreeCADFreeCADGui。showMainWindow()docFreeCAD。newDocument()AddgeometrytoFreeCADscenegraph(Coin)fcmeshdoc。addObject(Mesh::Feature,IfcMesh)fcmesh。MeshmeshSetDrawStyletodisplaymeshedges。OrientviewandfittowallFreeCADGui。runCommand(StdDrawStyle,1)FreeCADGui。Selection。addSelection(fcmesh)FreeCADGui。activeView()。viewIsometric()FreeCADGui。SendMsgToActiveView(ViewSelection)FreeCADGui。execloop() 上图是在FreeCAD中生成的几何图形,网格可以快速显示,但它通常不是你想要在BIM创作软件中使用的内容。所以下次我们将看到如何生成边界表示。 完整的源代码可在此处获得。四、IFC转BREP 前面我们使用IfcOpenShell(IOS)的标准设置来读取正在生成网格的ifc几何体。要生成其他内容,让我们看一下可用的设置。 如果你的IDE提供了良好的自动完成功能,你将能够看到有哪些选项,但看不到它们的含义。通过使用其中一个选项作为关键字在IOS存储库中进行快速搜索,可以很快找到一个名为IfcGeomIteratorSettings。h的头文件,其中包含所有定义:SpecifieswhethertousetheOpenCascadeBREPformatforrepresentationitemsratherthantocreatetrianglemeshes。ThisisusefulisIfcOpenShellisusedasalibraryinanapplicationthatisalsobuiltonOpenCascade。USEBREPDATA13, BREP代表边界表示,这可能是你在对参数化风管或管道及其相关组件建模时想要使用的。在python中定义设置如下:Definesettingssettingsgeom。settings()settings。set(settings。USEBREPDATA,True) 如果将生成的brep数据写入文件,你将看到它实际上是设置说明中建议的OpenCascadeBREP格式。shapegeom。createshape(settings,ifcentity)occstandsforOpenCascadeoccshapeshape。geometry。brepdataIfcOpenShellgenerateanOpenCascadeBREPwithopen(IfcOpenShellSamplesbrepdata,w)asfile:file。write(occshape) 幸运的是,被视为FreeCAD核心组件的Part模块也基于OpenCascade,这使得将几何体导入FreeCAD变得如此简单:CreateFreeCADshapefromOpenCascadeBREPfcshapePart。Shape()fcshape。importBrepFromString(occshape)Ifclenghtinternalunit:meter。FreeCADinternalunit:mm。fcshape。scale(1000)AddgeometrytoFreeCADscenegraph(Coin)fcpartdoc。addObject(Part::Feature,IfcPart)fcpart。Shapefcshape 不要忘记在文件顶部导入Part而不是Mesh。 如果我们使用此处提供的完整代码为之前文章中的墙生成几何图形,将获得相同的实体,但这次不是网格(没有三角形): 上面只导入了IfcWall实体,现在让我们从wikilab。ifc的wikihouse项目导入IfcElement实体,得到以下几何图形: 当然FreeCAD仍然有更好的导入方式,但如果你激活着色模式,会得到更好的效果: 原文链接:http:www。bimant。comblogifctomeshandbrep