IfcOpenShell로 IFC 파일 파싱하기 — Python으로 요소 조회와 속성 추출

파이썬으로 IFC 건물 모델과 속성 데이터를 분석하는 화면

IfcOpenShell은 IFC 파일을 코드로 직접 다루는 오픈소스 파이썬 라이브러리다. Revit이나 ArchiCAD를 띄우지 않고도 요소 조회와 속성 추출이 되므로, 납품 전 물량 검토나 데이터 품질 점검 스크립트를 짜기에 알맞다. 이 글에서는 IFC 스키마가 어떻게 생겼는지 개념을 먼저 잡고, 파일을 열어 요소를 조회하고 속성을 추출한 뒤, 건물의 공간 구조(대지-건물-층-공간)를 순회하는 데까지 실제 코드로 이어간다.

■ IFC 스키마의 뼈대 — IfcProduct와 PropertySet

IFC의 거의 모든 물리적 요소는 IfcProduct를 상속한다. 벽(IfcWall), 슬래브(IfcSlab), 문(IfcDoor), 기둥(IfcColumn)이 모두 여기 속한다. 각 요소는 세 가지 축으로 정보를 갖는다.

구분 담는 것 접근 관계
속성(PropertySet) 재질, 방화등급, 외벽 여부 등 비형상 정보 IsDefinedBy → IfcRelDefinesByProperties
수량(QuantitySet) 길이·면적·부피 등 수치 IsDefinedBy → IfcElementQuantity
형상(Geometry) 3D 표현 Representation

속성은 IfcPropertySet이라는 묶음에 담겨 있고, 표준 속성세트는 Pset_ 접두사를 쓴다. 예를 들어 벽의 공통 속성은 Pset_WallCommon이고, 그 안에 외벽 여부인 IsExternal, 내력벽 여부인 LoadBearing, 방화등급인 FireRating 같은 값이 들어간다. 저작도구가 만든 사용자 정의 속성세트는 이 접두사 없이 임의 이름을 갖는다.

■ 파일 열기와 요소 조회

시작은 세 줄이면 된다. open()으로 모델을 읽고 by_type()으로 종류별 요소를 받는다.

import ifcopenshell

model = ifcopenshell.open("sample.ifc")
print("스키마:", model.schema)      # IFC2X3 / IFC4 / IFC4X3

walls = model.by_type("IfcWall")
print("벽 개수:", len(walls))

# 개별 요소를 바로 집기
one = model.by_id(walls[0].id())     # STEP 라인 번호로
same = model.by_guid(walls[0].GlobalId)   # GlobalId(GUID)로

by_type()은 상속을 포함한다. model.by_type("IfcElement")를 부르면 벽·슬래브·문을 모두 한꺼번에 받을 수 있어, 전체 요소를 훑을 때 유용하다.

벽 문 창이 데이터 노드로 추출되는 IFC 시각화

■ 속성 추출 — get_psets

속성 관계를 손으로 따라가는 대신, ifcopenshell.util.element 모듈의 get_psets()를 쓰면 모든 속성세트와 수량세트를 딕셔너리로 한 번에 받는다. psets_only=True로 속성만, qtos_only=True로 수량만 걸러낼 수 있다.

import ifcopenshell.util.element as ue

w = walls[0]
psets = ue.get_psets(w, psets_only=True)
# {'Pset_WallCommon': {'IsExternal': True, 'LoadBearing': False,
#                      'FireRating': 'F60', ...}}

is_external = ue.get_pset(w, "Pset_WallCommon", "IsExternal")
print("외벽 여부:", is_external)

# 타입 요소로부터 상속되는 속성까지 합쳐 받기
all_psets = ue.get_psets(w)          # 인스턴스 + 타입 속성 병합

같은 모듈의 get_type()은 요소의 타입 정의(IfcWallType 등)를, get_container()는 소속 층을, get_decomposition()은 하위 구성요소를 돌려준다. 이 네 함수만으로 실무 조회의 대부분이 해결된다.

■ 공간 구조 순회 — IfcSpatialStructure

IFC 모델은 대지(IfcSite) → 건물(IfcBuilding) → 층(IfcBuildingStorey) → 공간(IfcSpace)으로 이어지는 공간 위계를 갖는다. 이 트리를 따라가면 “3층에 있는 벽만” 같은 질의를 할 수 있다. 트리는 IsDecomposedBy 관계로 연결되고, 층에 실제로 배치된 요소는 ContainsElements 관계로 붙는다.

import ifcopenshell.util.element as ue

project = model.by_type("IfcProject")[0]

def walk(element, depth=0):
    print("  " * depth + f"{element.is_a()}: {element.Name}")
    # 하위 공간 구조(대지→건물→층)
    for rel in getattr(element, "IsDecomposedBy", []) or []:
        for child in rel.RelatedObjects:
            walk(child, depth + 1)
    # 이 공간에 배치된 실제 요소
    for rel in getattr(element, "ContainsElements", []) or []:
        for e in rel.RelatedElements:
            print("  " * (depth + 1) + f"- {e.is_a()}: {e.Name}")

walk(project)

이 재귀 순회의 출력은 곧 IFC 파일의 목차와 같다. 각 층에 어떤 요소가 몇 개 배치돼 있는지 한눈에 파악되므로, 모델 구조를 검수하거나 층별 집계를 만들 때 기본 틀이 된다.

개발 워크스테이션에서 3D BIM 모델과 코드를 함께 보는 모습

■ 형상까지 필요할 때

좌표나 부피 같은 형상 기반 값이 필요하면 ifcopenshell.geomcreate_shape()로 삼각망을 만든다. 요소가 많을 때는 단건 호출보다 멀티스레드 iterator가 훨씬 빠르다.

import ifcopenshell.geom
import multiprocessing

settings = ifcopenshell.geom.settings()
it = ifcopenshell.geom.iterator(
    settings, model, multiprocessing.cpu_count())

if it.initialize():
    while True:
        shape = it.get()
        verts = shape.geometry.verts    # 정점 좌표 배열
        # ... 좌표 처리 ...
        if not it.next():
            break

■ 눈여겨볼 것

같은 정보라도 파일마다 담긴 위치가 다를 수 있다. 어떤 저작도구는 방화등급을 Pset_WallCommon.FireRating에 넣지만, 다른 도구는 사용자 정의 속성세트에 넣는다. 그래서 실무 스크립트는 특정 키 하나에 의존하지 말고, 모든 속성세트를 훑어 원하는 키를 찾는 방어적 방식이 안전하다. 또 IFC2X3와 IFC4는 클래스 이름과 속성 구조가 조금씩 다르므로, 스크립트 첫머리에서 model.schema를 확인해 분기하는 습관을 들이는 것이 좋다.

■ 이런 분께 도움이 됩니다

  • BIM 데이터 품질 점검 담당자 — 필수 속성 누락, 잘못된 방화등급 같은 오류를 파일만으로 일괄 점검하는 스크립트를 짤 수 있다
  • 파이썬을 익힌 건축·구조 엔지니어 — 상용 라이선스 없이 대량 모델의 속성을 조회·가공할 수 있다
  • 개방형 BIM 연구자 — IFC를 데이터로 다루는 연구에서 가장 표준적인 도구다

■ 참고

API 상세는 docs.ifcopenshell.org의 util.element 문서에서 확인할 수 있다. GlobalId는 22자리 압축 형식이므로, 사람이 읽는 GUID와 비교할 때는 ifcopenshell.guid 모듈로 변환한다. 대용량 파일은 열기만 해도 메모리를 많이 쓰므로, 한 번 연 모델을 재사용하고 반복적인 by_type() 호출을 피하는 것이 성능의 관건이다.


공식 참고 자료 및 적용 범위

이 글은 Python과 IfcOpenShell로 IFC 요소·속성을 조회하는 기본 흐름을 설명합니다. 모델 파싱과 속성값은 IFC 스키마, 작성 도구, IfcOpenShell 버전과 데이터 품질에 따라 달라질 수 있습니다.

아래 자료는 확인일 기준의 제조사·표준기구 또는 공공기관 공식 문서입니다. 제품 기능·표준·정책은 개정될 수 있으므로 실제 프로젝트 적용 전에는 사용 중인 버전의 최신 원문과 프로젝트 기준을 확인하세요.

확인일: 2026-08-15