IFC转MESH和BREPIfcOpenShell

本文介绍如何利用IfcOpenShell读取IFC文件中的几何数据并生成网格或BREP。

一、IfcOpenShell简介

IfcOpenShell 是一个用于处理 IFC 数据的库,采用 LGPL 3.0(自由和开源)许可。

IfcOpenShell的功能包括:

一些使用 IfcOpenShell 的项目包括:

在本文中,我们将使用一个从 ifc 实体生成网格体的函数,在我们的例子中是 IfcWall,看看我们可以得到什么结果。

二、获取原始IFC文件

首先使用 FreeCAD 创建一个简单墙并导出为 .ifc 文件:

先决条件:已安装 IfcOpenShell。 此处使用的版本:0.6.0a1

三、IFC转网格体

首先我们需要引入 ifcopenshell 并打开 ifc 文件:

import ifcopenshell
from ifcopenshell import geom


def read_geom(ifc_path):

    ifc_file = ifcopenshell.open(ifc_path)

    settings = geom.settings()

geom.settings 用于设置转换选项。 默认情况下,ifcopenshell 生成具有顶点、边和面的网格。

ifc_file.by_type("IfcClass")是获取所选类(包括子类)的所有元素的一种非常方便的方法。 因此,如果使用 IfcBuildingElement,它还将包括 IfcWall、IfcWindow、IfcSlab、IfcBeam 等……

geom.create_shape(settings, ifc_entity) 是将 ifc 实体转换为网格的函数。 我们可以观察到顶点存储在单个元组中,而不是 xyz 三元组。 边和面也一样。

    for ifc_entity in ifc_file.by_type("IfcWall"):
        shape = geom.create_shape(settings, ifc_entity)
        # ios stands for IfcOpenShell
        ios_vertices = shape.geometry.verts
        ios_edges = shape.geometry.edges
        ios_faces = shape.geometry.faces

        # IfcOpenShell store vertices in a single tuple, same for edges and faces
        print(ios_vertices)
        print(ios_edges)
        print(ios_faces)
        """ Above will result in :
(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(ios_edges))
        print(set(ios_faces))
        """ Above will result in :
{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个面定义。 边和面值都是顶点索引。

        # Let's parse it and prepare it for FreeCAD import
        vertices = [
            FreeCAD.Vector(ios_vertices[i : i + 3])
            for i in range(0, len(ios_vertices), 3)
        ]
        edges = [ios_edges[i : i + 2] for i in range(0, len(ios_edges), 2)]
        faces = [tuple(ios_faces[i : i + 3]) for i in range(0, len(ios_faces), 3)]

        print(
            f"This {ifc_entity.is_a()} has been defined by {len(vertices)} vertices, {len(edges)} edges and {len(faces)} faces"
        )
        print(vertices)
        print(edges)
        print(faces)
        """ Above will result in :
This IfcWall has been defined by 8 vertices, 24 edges and 12 faces
[(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 ,但让我们使用自己的网格来生成几何图形:

import FreeCAD
import FreeCADGui
import Mesh

if __name__ == "__main__":
    mesh_values = read_geom(
        "/home/cyril/git/pythoncvc.net/IfcOpenShellSamples/Wall.ifc"
    )

    # Create a FreeCAD geometry. A FreeCAD can take vertices and faces as input
    mesh = Mesh.Mesh((mesh_values["vertices"], mesh_values["faces"]))
    # Ifc lenght internal unit : meter. FreeCAD internal unit : mm.
    scale_factor = 1000
    matrix = FreeCAD.Matrix()
    matrix.scale(scale_factor, scale_factor, scale_factor)
    mesh.transform(matrix)

    # Allow you to embed FreeCAD in python https://www.freecadweb.org/wiki/Embedding_FreeCAD
    FreeCADGui.showMainWindow()
    doc = FreeCAD.newDocument()

    # Add geometry to FreeCAD scenegraph (Coin)
    fc_mesh = doc.addObject("Mesh::Feature", "IfcMesh")
    fc_mesh.Mesh = mesh

    # Set Draw Style to display mesh edges. Orient view and fit to wall
    FreeCADGui.runCommand("Std_DrawStyle",1) 
    FreeCADGui.Selection.addSelection(fc_mesh)
    FreeCADGui.activeView().viewIsometric()
    FreeCADGui.SendMsgToActiveView("ViewSelection")
    
    FreeCADGui.exec_loop()

上图是在 FreeCAD 中生成的几何图形,网格可以快速显示,但它通常不是你想要在 BIM 创作软件中使用的内容。 所以下次我们将看到如何生成边界表示。

完整的源代码可在此处获得。

四、IFC转BREP

前面我们使用 IfcOpenShell (IOS) 的标准设置来读取正在生成网格的 ifc 几何体。 要生成其他内容,让我们看一下可用的设置。

如果你的 IDE 提供了良好的自动完成功能,你将能够看到有哪些选项,但看不到它们的含义。 通过使用其中一个选项作为关键字在 IOS 存储库中进行快速搜索,可以很快找到一个名为 IfcGeomIteratorSettings.h 的头文件,其中包含所有定义:

/// Specifies whether to use the Open Cascade BREP format for representation
/// items rather than to create triangle meshes. This is useful is IfcOpenShell
/// is used as a library in an application that is also built on Open Cascade.
USE_BREP_DATA = 1 << 3,

BREP 代表边界表示,这可能是你在对参数化风管或管道及其相关组件建模时想要使用的。 在 python 中定义设置如下:

    # Define settings
    settings = geom.settings()
    settings.set(settings.USE_BREP_DATA, True)

如果将生成的 brep 数据写入文件,你将看到它实际上是设置说明中建议的OpenCascade BREP 格式。

    shape = geom.create_shape(settings, ifc_entity)
    # occ stands for OpenCascade 
    occ_shape = shape.geometry.brep_data

    # IfcOpenShell generate an Open Cascade BREP 
    with open("IfcOpenShellSamples/brep_data", "w") as file:
        file.write(occ_shape)

幸运的是,被视为 FreeCAD 核心组件的 Part 模块也基于 Open Cascade,这使得将几何体导入 FreeCAD 变得如此简单:

    # Create FreeCAD shape from Open Cascade BREP
    fc_shape = Part.Shape()
    fc_shape.importBrepFromString(occ_shape)
    
    # Ifc lenght internal unit : meter. FreeCAD internal unit : mm.
    fc_shape.scale(1000)
    
    # Add geometry to FreeCAD scenegraph (Coin)
    fc_part = doc.addObject("Part::Feature", "IfcPart")
    fc_part.Shape = fc_shape

不要忘记在文件顶部导入Part而不是Mesh。

如果我们使用此处提供的完整代码为之前文章中的墙生成几何图形,将获得相同的实体,但这次不是网格(没有三角形):

上面只导入了 IfcWall 实体,现在让我们从 wikilab.ifc 的 wikihouse 项目导入 IfcElement 实体,得到以下几何图形:

当然 FreeCAD 仍然有更好的导入方式,但如果你激活着色模式,会得到更好的效果:


原文链接:http://www.bimant.com/blog/ifc-to-mesh-and-brep/

展开阅读全文

页面更新:2024-04-21

标签:角形   几何体   几何图形   网格   顶点   边界   实体   选项   定义   文件

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top