CH NEO-ZÜRICH EDITION
WEATHER · HAZE 24°C
BLEND OF THE DAY · 07/ROGUE
EST. 2027
THE AEC CYBER MORNING NEWS

PAZ Kaffi

DESIGN · DEMOLITION · CAFFEINE · DISPATCH
EDITION 0806 · 6 August 2026
BROADCAST 04:42 CET
2,400 BROADSHEETS PRINTED
READ TIME · 47 MIN
IFC in Notepad: reading a building with three lines of IfcOpenShell-python
BAU
FRAME · 06:50
06-08-2026

IFC in Notepad: reading a building with three lines of IfcOpenShell-python

IFC is a plain-text STEP graph you can open in Notepad. Read and edit a real building in three lines of IfcOpenShell-python — no licence, no vendor lock-in.

Open a real building in three lines of Python, and the first thing you notice is what is missing: no licence dongle, no cloud round-trip, no proprietary reader. The IfcOpenShell “Hello, world!” crash course starts you with import ifcopenshell and model = ifcopenshell.open('model.ifc'), and from that moment the building is just data you can walk. That is the signal worth stopping on — not a new feature, but a reminder of what IFC actually is underneath every BIM tool that quietly consumes it.

Because the structure is the whole lesson here. An IFC file is not a compiled binary; it is a STEP physical file (SPF), the plain-text encoding standardised as ISO 10303-21 — text you can open in an editor and read line by line. Each line is one entity, and every entity is an ordered list of attributes plus a set of references to other entities. Formally, that makes an IFC model a directed graph: nodes are entities, edges are references. When the docs show you model.traverse(wall) (the elements a wall points to) and model.get_inverse(wall) (the elements pointing back at it), they are handing you the two directions of that graph. Learn to read those edges and you understand IFC better than most people who have exported it for a decade.

←TODAY: IfcOpenShell-python reads a live building model in three lines; the file opens in Notepad, no licence, no server.
→3012: The plugins die and the vendors merge, but a STEP file a 25-year-old can read by eye outlives every one of them.
Fulcrum: A format you can parse by hand is the only geometry you can still defend after the tool that drew it is gone.

Look at one entity written out in SPF form — this is the exact shape the crash course produces when you create a wall with keyword arguments:

#1=IfcWall('0EI0MSHbX9gg8Fxwar7lL8',$,'Wall Name',$,$,$,$,$,$)

Split it by parts and the whole grammar of IFC falls out. #1 is the STEP ID — the entity’s address inside the file, the number you’d use to cross-reference it. IfcWall is the class, the type in the schema’s inheritance tree (which is why wall.is_a('IfcElement') also returns True — a wall is an element). The quoted string '0EI0MSHbX9gg8Fxwar7lL8' is the first attribute, the GlobalId: a 22-character base64 encoding of a 128-bit GUID, meant to be the object’s identity across every export and every tool. Each $ is an unset attribute — OwnerHistory, Description and the rest left null. And 'Wall Name' is the third attribute, the human-readable Name. Attribute order is fixed by the schema; that is why IfcOpenShell lets you reach a value both positionally (wall[2]) and by name (wall.Name). Nothing is hidden. This is buildingSMART’s IFC — the schema published as ISO 16739 — doing exactly what a data-interchange standard should do: describe the building in a form no single vendor owns.

The Tool: IfcOpenShell is the open-source toolkit that most of the free openBIM world is built on — a C++ core with a Python binding (ifcopenshell-python) that reads, edits, and writes IFC2X3, IFC4, and IFC4X3. It is the same engine under Bonsai (native IFC authoring inside Blender). If you do serious BIM literacy work, this is long-term infrastructure, not a weekend toy. An afternoon with it is an afternoon spent learning the language your authoring tool merely speaks with an accent.

Setup:

# Python 3.11+; a fresh venv keeps your CAD workstation clean
python -m venv .venv
.venv\Scripts\activate        # Windows; use source .venv/bin/activate on macOS/Linux
pip install ifcopenshell

# prove it works against any .ifc on disk
python -c "import ifcopenshell; m=ifcopenshell.open('model.ifc'); print(m.schema)"
# -> IFC2X3, IFC4, or IFC4X3

No model handy? The docs point to a small sample from the Institute for Automation and Applied Informatics (IAI) at the Karlsruhe Institute of Technology — it’s in German, so, as the crash course cheerfully warns, “you may need to use some creativity when reading the data.” For a PAZ reader that is a feature, not a bug.

First steps:

  1. Load and orient: print(model.schema) tells you which IFC dialect you’re in — this decides everything downstream.
  2. Count something real: walls = model.by_type('IfcWall'); print(len(walls)). You now have a live handle on every wall in a foreign model.
  3. Interrogate one: wall = walls[0]; print(wall.get_info()) dumps its attributes as a dictionary; ifcopenshell.util.element.get_psets(wall) pulls the property sets — the Pset_WallCommon.LoadBearing and custom Swiss FireRating fields where every handover argument actually lives.
  4. Change and save: reassign wall.Name = 'Reviewed', then model.write('checked.ifc'). You have edited a building in plain Python.

Atelier: PAZ has covered this thread before — our openBIM handover piece made the point that two teams can be 100% standards-compliant and still hand each other two different buildings, because the vocabulary is shared but the dialect is not. IfcOpenShell is how a Swiss studio stops trusting the export button and starts reading what it sent. The Monday move: before the next IFC leaves your office, run a five-line script that prints model.schema, the count of each by_type you promised to deliver, and get_psets on one representative element per discipline — and attach that printout to the transmittal. You just turned “I exported it” into “here is what I exported,” with numbers.

Hack: Walk the reference graph out of one wall to see which openings, quantities, and relationships actually point back at it — the inverse edges no property panel shows you. This is how you catch a door that was never truly hosted, before the model reaches the site.

import ifcopenshell
model = ifcopenshell.open('model.ifc')
wall = model.by_type('IfcWall')[0]
for ref in model.get_inverse(wall):        # who references this wall?
    print(ref.is_a(), '->', getattr(ref, 'Name', ''))

The trade-off is honest and worth stating plainly: IfcOpenShell gives you the raw graph, not the parametric intelligence. Your authoring tool knows a window belongs in a wall and moves it when the wall moves; the IFC file only records the relationship as it stood at export. Read it, don’t expect it to behave. That is exactly why the reading skill matters — the file is a snapshot you must verify, not a live model you can trust.

And here is the long view, from a desk that has watched plugins go dark: the parametric work my generation regrets was never the ugly form — it was the model whose logic nobody could reconstruct after the software that made it was retired. A geometry you can only open in one dead application is a beautiful guess. A STEP file you can still parse by hand is a building you can still defend. Keep the readable format; the fancy viewer will not survive you.

Learn-it:

FILED FROM
CO-SIGNERS
PAZ Academy
CONFIDENCE
HIGH
REPRINTS
© PAZ - PARAMETRIC ACADEMY ZURICH · ALL RIGHTS RESERVED

SOURCE ·

PAZ Kaffi · multidisciplinary editorial, led by PAZ Academy

⚑ REPORT AN ERROR · SUBMIT A CORRECTION
◂ BACK TO FRONT PAGE · PAZ KAFFI

© 2026 PAZ Academy.