Turn Any IFC File Into CSV, OBJ in Seconds
IFC2StructuredData is now open-source. One command flattens an IFC model into spreadsheet-friendly tables and per-element meshes — ready for Excel, pandas, Blender, or three.js.
IFC2StructuredData turns an IFC model into files every tool already speaks — CSV for attributes and relationships, OBJ for per-element geometry. It's now open-source under MIT.
What it does
IFC2StructuredData flattens an IFC model into three formats that every language and every tool already speaks — CSV for attributes, CSV for relationships, and OBJ for per-element geometry. Downstream, you never need to touch IFC again.
One command, one folder out:
pip install -r requirements.txt
python ifc2structureddata.py model.ifc output/
You get back:
attribute.csv— one row per element, every property set flattened into columnsrelationships.csv— the IFC relationship graph as GUID pairs plus a typegeometry/*.obj+*.mtl— per-element meshes in world coordinates (meters)meta.json— run metadata (timing, counts, file sizes)
The numbers below come from a real run on a 96 MB Revit-exported office building.
Why this exists
This is the tool that sits underneath our own work.
Every tabular comparison in our earlier post BIMdiff: Object-Level Change Detection for BIM Models — every per-element attribute diff, every relationship delta — reads from CSVs produced by IFC2StructuredData. We wrote it first because BIMdiff could not exist without it. It is also what feeds our clash-filtering models at SiloLink: the attribute tables go straight into pandas, the relationship tables go straight into a graph.
We kept using it. Eventually it felt selfish not to open-source it.
What you actually get
attribute.csv — one row per IFC element, with every property set already flattened into columns. Opens in Excel. Loads in pandas in a single line.
| GlobalId | type | Name | has_geometry |
|---|---|---|---|
| 2Tt7$hRrHBKvoaUIFPAzmj | IfcWall | Interior 138mm Partition (1-hr):145023 | True |
| 2UMN_OQKrAshZl3dHPujxF | IfcWall | Interior 138mm Partition (1-hr):157695 | True |
| 2UMN_OQKrAshZl3dHPuj6v | IfcWall | Interior 138mm Partition (1-hr):157833 | True |
In total, 5,929 rows × 61 columns for the office model — every quantity, every property set, every Revit parameter as its own column. Every element gets a row; the 86 extra rows beyond the OBJ count are non-geometric elements like spaces and groups.
relationships.csv — the IFC relationship graph as two columns of GUIDs plus a type. No traversal logic required. Feeds a graph neural network as-is.
| Relating Type | Relating GUID | Related Type | Related GUID | Relationship |
|---|---|---|---|---|
| IfcSpace | 1wJoqPkIP4J8fINgm5A1mL | IfcFurnishingElement | 2IM_LUiyz5JQKX9W84fx$T | IfcRelContainedInSpatialStructure |
| IfcSpace | 1wJoqPkIP4J8fINgm5A1mL | IfcFurnishingElement | 2IM_LUiyz5JQKX9W84fx$U | IfcRelContainedInSpatialStructure |
On this model the table has 12,767 edges covering containment, aggregation, material associations, voids, and fills — everything you normally have to walk the IFC entity graph to collect.
geometry/*.obj — one OBJ + MTL pair per element, vertices already in world coordinates in meters. No transforms, no unit conversion, no parent-frame hierarchy to resolve. Open any file in Blender, load it in three.js, or feed it to trimesh.
Add --glb and you get a single viewable model.glb for the whole building:

Supports BIMdiff and more
IFC2StructuredData is already in production as the first stage of BIMdiff, our object-level BIM change detection pipeline. Every diff BIMdiff reports — every attribute change, every geometry delta — starts from the CSVs this tool produces.
Once BIM data is in tabular form, the same representation opens the door to everything downstream that expects tables or graphs: machine learning training sets, graph-based analysis, dashboards, custom QA rules. BIMdiff is the first thing we built on top; it won't be the last.
Available now
MIT licensed, and built on the shoulders of IfcOpenShell — without their excellent work this project wouldn't exist. Clone the repo, point it at an IFC file, open the CSVs.