업데이트 2026년 10월 15일읽는 시간 약 6분

파이썬으로 IFC 건물 모델과 속성 데이터를 분석하는 화면
파이썬으로 IFC 건물 모델과 속성 데이터를 분석하는 화면 — AI로 만든 예시 이미지

IfcOpenShell은 IFC 파일을 코드로 직접 다루는 오픈소스 파이썬 라이브러리다. Revit이나 ArchiCAD를 띄우지 않고도 요소 조회와 속성 추출이 되므로, 납품 전 물량 검토나 데이터 품질 점검 스크립트를 짜기에 알맞다.

IFC에서 필요한 속성을 꺼내는 순서
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 시각화
벽 문 창이 데이터 노드로 추출되는 IFC 시각화 — AI로 만든 예시 이미지

■ 속성 추출 — 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 모델과 코드를 함께 보는 모습
개발 워크스테이션에서 3D BIM 모델과 코드를 함께 보는 모습 — AI로 만든 예시 이미지

■ 형상까지 필요할 때

좌표나 부피 같은 형상 기반 값이 필요하면 ifcopenshell.geom의 create_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를 확인해 분기한다.

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


참고 문헌

자주 묻는 질문

IfcOpenShell은 무엇에 쓰는 도구인가요?

IFC 파일을 코드로 직접 다루는 오픈소스 파이썬 라이브러리입니다. Revit이나 ArchiCAD를 띄우지 않고도 요소 조회와 속성 추출이 되므로, 납품 전 물량 검토나 데이터 품질 점검 스크립트를 짜기에 알맞습니다.

IFC 파일에서 벽만 골라내려면 어떻게 하나요?

open()으로 모델을 읽은 뒤 by_type()에 IfcWall을 넘기면 됩니다. by_type()은 상속을 포함하므로 IfcElement를 넘기면 벽·슬래브·문을 모두 한꺼번에 받을 수 있어 전체 요소를 훑을 때 유용합니다.

Pset_WallCommon에는 어떤 정보가 들어 있나요?

벽의 공통 속성이 들어 있습니다. 외벽 여부인 IsExternal, 내력벽 여부인 LoadBearing, 방화등급인 FireRating 같은 값이 담기며, Pset_ 접두사는 표준 속성세트에 쓰입니다.

방화등급을 뽑을 때 속성세트 하나만 조회해도 되나요?

그렇게 하지 않는 편이 안전합니다. 어떤 저작도구는 Pset_WallCommon.FireRating에 넣고 다른 도구는 사용자 정의 속성세트에 넣기 때문에, 특정 키 하나에 의존하지 말고 모든 속성세트를 훑어 원하는 키를 찾도록 스크립트를 짜야 합니다.

같은 주제의 글