LoginSignup
9
8

More than 3 years have passed since last update.

IfcOpenShell pythonバインディングのことはじめ

Last updated at Posted at 2019-11-03

やりたいこと

表題の通りですが、IfcOpenShellというのはIFCを解析できるオープンソースライブラリで、もともとC++で書かれているけれど、Pythonバインディングも出ています。IfcOpenShellのツール群の中には、IfcConvertというものがあって、IFCのジオメトリ抽出が可能になっている。OBJ、IGES、DAE、STLなど様々なフォーマット変換が可能であり、GUIDや名前で特定の形状のみ抽出することもできます。一般的にはこれで十分なのですが、IFCの属性情報と形状を使って、色々なことをしようとすると、どうしても直接ジオメトリやトポロジといった3Dデータをいじりたくなります(ふつうはならないけどね)。

その場合は、OpenCASCADEと呼ばれるライブラリ(CADカーネル)を使うのが一般的で、実際ライブラリにも含まれています。このライブラリは、FreeCADなどに用いられる老舗のオープンソースライブラリで、パラメトリックな3Dモデラー機能を提供してくれるようです。

ちなみにIFCの解析ライブラリというのは、オープンソースだとIFC++xBIM Toolkit、有料だとIFC Engineapstex IFC Framework(一部は無料)などがあります。

IfcOpenShellによるIFCの分析とpythonOCCによる描画

準備

ライブラリの関係もあって、Python3.5の環境を用意します。私の場合はインストールしてあるAnacondaで、condaを使って必要ライブラリをインストールしました。対応しているPythonは3.5までのようだったので、環境としてはそれを使い、対応したバージョンのOpenCASCADEのPython-bindingであるpythonoccをインストールします。ネットワーク環境の要因なのか、結構失敗するのでソースコードからビルドしたほうが良いかもしれません。

conda install -c conda-forge -c oce -c dlr-sc -c ifcopenshell ifcopenshell
conda install -c conda-forge -c dlr-sc -c pythonocc -c oce pythonocc-core==0.17.3

あと、適当なIFCファイルを準備します。ifcOpenHouseなどでよいでしょう。

※Python3.6にも対応になったようです(2020/2/15)

IFCからの形状取得

IFCのジオメトリは、複雑なIfcRepresentationItemに分解されています。具体的にはSurface Model(Tessellatiobなど), SolidModel(CGS,B-reps,sweepなど)などの形状表現やスタイル、テクスチャ表現などです。IfcOpenShellはこの複雑さを隠し、すべての統一された境界表現(B-reps)に変換します。加えて、レンダリングのためのMESH生成も行ってくれます。

ちなみに、実際のBIMでの形状モデリングは「カーネル」と呼ばれるものに依存しているようで、例えばASICやParadsolidといったものです。カットアウトや開口のような複雑な表現も容易にモデリングできます。

MESHの取得

以下が一番単純なサンプルになります。

import ifcopenshell
from ifcopenshell import geom

def read_geom(ifc_path):
    ifc_file = ifcopenshell.open(ifc_path)
    settings = geom.settings()

    for ifc_entity in ifc_file.by_type("IfcWall"):
        shape = geom.create_shape(settings, ifc_entity)
        # メッシュの取得
        ios_vertices = shape.geometry.verts
        ios_edges = shape.geometry.edges
        ios_faces = shape.geometry.faces

        # 普通にPrintしてみる
        print(ios_vertices)
        print(ios_edges)
        print(ios_faces)

geom.setting()というのは変換のためのオプションで、デフォルトでは頂点(Vetices)、稜線(Edge)、面(Face)のメッシュを生成します。geom.create_shape(settings, ifc_entry)で、ifc_entryで示されたIFC要素の形状を取得することができます。頂点は、x,y,zからなるトリプレットであり、稜線はそれらを結ぶもの、そして面は3つの頂点と稜線から構成されます。

B-repsを直接扱う。

上記では直接レンダリング可能なメッシュ表現を取得しましたが、境界表現であるB-reps(Boundary representation )を直接取得することもできます。geom.setting()に以下のパラメータを指定します。以下ではついでにファイルに保存を試みています。

settings = geom.settings()
settings.set(settings.USE_BREP_DATA, True)
occ_shape = shape.geometry.brep_data

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

出力したフォーマットは、Open Cascade BREP Formatというものらしいです。

pythonOCCを使って描画するのは以下のようにします。色が変な気がしますが、まずはこんなもんかな。

import ifcopenshell
from ifcopenshell import geom

# Specify to return pythonOCC shapes from ifcopenshell.geom.create_shape()
settings = geom.settings()
settings.set(settings.USE_PYTHON_OPENCASCADE, True)

# Initialize a graphical display window
occ_display = geom.utils.initialize_display()
ifc_file = ifcopenshell.open("ifcOpenHouse.ifc")


products = ifc_file.by_type("IfcProduct")
for product in products:
    if product.is_a("IfcOpeningElement"): continue
    if product.Representation:
        shape = geom.create_shape(settings, product).geometry
        display_shape = geom.utils.display_shape(shape)
        if product.is_a("IfcPlate"):
            # Plates are the transparent parts of the window assembly
            # in the IfcOpenHouse model
            geom.utils.set_shape_transparency(display_shape, 0.8)

# すぐ消えるので、ここでループさせる
ifcopenshell.geom.utils.main_loop()

image.png

参考

  1. Using IfcOpenShell to parse IFC files with Python
  2. IfcOpenShell – Read geom as mesh
  3. IfcOpenShell – Read geom as brep
9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8