| name | ifc-impl-geometry-extraction |
| description | Use when extracting the geometry of an IFC element from an existing file in order to render it, mesh it, or measure it: resolving IfcProduct.Representation to its shape items, picking the right representation, walking the IfcLocalPlacement chain to a world transformation matrix, and decoding each RepresentationType (SweptSolid, Brep, Tessellation, CSG/Clipping, MappedRepresentation). Prevents every extracted element piling up at the origin because the placement chain was skipped, a blocky model because the Box representation was read instead of Body, scrambled meshes from treating IFC indices as zero-based, empty geometry because IfcMappedItem instances were not resolved, and wrong volumes from treating a tessellated approximation as an exact solid. Covers the product-to-shape resolution path, RepresentationIdentifier and RepresentationType, the placement-to-matrix computation, mapped-item transforms, and the IFC2x3 versus IFC4 versus IFC4.3 differences. Keywords: extract IFC geometry, IfcShapeRepresentation, RepresentationType, RepresentationIdentifier, Body, IfcLocalPlacement, world transformation matrix, IfcExtrudedAreaSolid, IfcFacetedBrep, IfcTriangulatedFaceSet, IfcMappedItem, IfcRepresentationMap, IfcCartesianTransformationOperator, tessellation, swept solid, mesh, render IFC, elements at origin, everything stacked at zero, model is blocky, geometry is empty, how do I get the geometry out of an IFC file, how do I render an IFC model.
|
| license | MIT |
| compatibility | Designed for Claude Code. Requires IFC IFC2x3, IFC4, IFC4.3. |
| metadata | {"author":"OpenAEC-Foundation","version":"1.0"} |
Extracting Geometry from an IFC File
An IFC element keeps its shape and its position apart. The geometry
items sit in a LOCAL coordinate system; the element's place in the world
is carried separately by ObjectPlacement. Extracting usable geometry
means doing two things ALWAYS together: decoding the shape items, and
resolving the placement chain to a world transformation matrix.
Verified against the buildingSMART IFC4.3 specification, with IFC4 ADD2
TC1 and IFC2x3 TC1 deltas noted. See references/methods.md for full
entity signatures, references/examples.md for worked STEP snippets and
matrix computation, and references/anti-patterns.md for the extraction
mistakes that produce wrong or empty geometry.
Quick Reference
The resolution path
IfcProduct.Representation
-> IfcProductDefinitionShape.Representations (a list)
-> IfcShapeRepresentation (pick by RepresentationIdentifier)
-> Items (the geometry primitives)
-> IfcExtrudedAreaSolid / IfcFacetedBrep / IfcTriangulatedFaceSet / ...
In parallel, ALWAYS resolve placement:
IfcProduct.ObjectPlacement
-> IfcLocalPlacement.PlacementRelTo (walk up to the root)
-> compose each RelativePlacement into one world matrix
World geometry = world matrix applied to the local geometry items.
NEVER render or measure the raw items without applying the placement.
RepresentationIdentifier: which representation kind
| Identifier | Holds | Use for |
|---|
Body | 3D solid / surface geometry | rendering, meshing, volume |
Axis | 2D/3D axis line | wall/beam centreline analysis |
FootPrint | 2D ground projection | plan drawings, site layout |
Box | bounding box solid | fast culling, spatial queries |
Profile | 3D profile outline | section display |
Surface | analytical surface | structural analysis |
Reference | non-Body reference geometry | opening reference shapes |
CoG | centre-of-gravity point | mass properties |
ALWAYS read the Body representation for solid rendering or quantity
work. NEVER take whichever representation appears first: a product can
carry Box, Axis, and Body at once.
RepresentationType: which geometry encoding
| Type | Decode by | Versions |
|---|
SweptSolid | sweep a profile (IfcExtrudedAreaSolid, IfcRevolvedAreaSolid) | all |
Clipping | Boolean DIFFERENCE (IfcBooleanClippingResult) | all |
CSG | Boolean tree (IfcBooleanResult) | all |
Brep | read explicit faces/shells (IfcFacetedBrep) | all |
AdvancedBrep | B-spline faces (IfcAdvancedBrep) | IFC4+ |
AdvancedSweptSolid | sweep along directrix, swept-disk | IFC4+ |
Tessellation | indexed face set (IfcTriangulatedFaceSet) | IFC4+ |
MappedRepresentation | resolve IfcMappedItem + transform | all |
SurfaceModel | face/shell surface set | all |
BoundingBox | simple box | all |
Tessellation, AdvancedBrep, and AdvancedSweptSolid do NOT exist in
IFC2x3. An IFC2x3 file delivers solid shape as SweptSolid, Clipping,
Brep, CSG, or SurfaceModel.
IFC indices are 1-based
Every index list in IFC (CoordIndex, PnIndex, IfcIndexedPolygonalFace)
is 1-based. The first coordinate is index 1, not 0. ALWAYS subtract 1
before indexing a zero-based array.
Decision Trees
Which representation to extract
What is the geometry needed for?
├── Rendering / display
│ Is a Tessellation Body representation present?
│ ├── YES -> use it directly; it is render-ready triangles.
│ └── NO -> decode the Body SweptSolid / Brep / Clipping items.
├── Exact quantity (volume, area, exact dimensions)
│ NEVER use Tessellation: it is a faceted approximation.
│ Use the Body parametric solid (SweptSolid / Brep / CSG).
│ If Body is only Tessellation, report the result as approximate.
├── 2D plan output
│ Use the FootPrint representation; fall back to Body projected.
└── Fast spatial query / culling
Use the Box representation if present; else the Body bounding box.
How to decode one IfcShapeRepresentation
Read RepresentationType of the IfcShapeRepresentation.
├── SweptSolid / AdvancedSweptSolid
│ For each item: sweep SweptArea profile along the swept geometry,
│ then apply the item Position.
├── Clipping / CSG
│ Item is an IfcBooleanResult tree. Recurse into FirstOperand and
│ SecondOperand; apply Operator (DIFFERENCE for Clipping).
│ A geometry kernel is required to evaluate the Boolean.
├── Brep / AdvancedBrep / SurfaceModel
│ Geometry is already explicit: read shells -> faces -> loops ->
│ IfcCartesianPoint. No sweeping needed.
├── Tessellation
│ Read Coordinates pool and CoordIndex; build triangles directly.
└── MappedRepresentation
Each item is an IfcMappedItem. Resolve MappingSource
(IfcRepresentationMap.MappedRepresentation) and recurse, then apply
MappingTarget (an IfcCartesianTransformationOperator).
Patterns
Pattern 1: resolve a product to its Body items
shape = product.Representation # IfcProductDefinitionShape
reps = shape.Representations # list of IfcShapeRepresentation
body = first rep where rep.RepresentationIdentifier == 'Body'
items = body.Items # geometry primitives
If product.Representation is $ the product has no geometry (common
for spatial elements such as IfcBuildingStorey). ALWAYS handle that.
Pattern 2: the placement chain to a world matrix
Each IfcAxis2Placement3D yields a 4x4 matrix: Location is the
translation, Axis is the local Z, RefDirection is the approximate
local X. The Y axis is Z cross X; RefDirection is re-orthogonalised
against Axis.
M = identity
p = product.ObjectPlacement # IfcLocalPlacement
chain = []
while p is not null:
chain.prepend( matrix_of(p.RelativePlacement) )
p = p.PlacementRelTo
for m in chain: # root first, element last
M = M * m
world_point = M * local_point
NEVER skip the chain and NEVER reverse the multiplication order: both put
elements in the wrong place. See references/examples.md for the full
matrix formula.
Pattern 3: SweptSolid
item = IfcExtrudedAreaSolid
profile = item.SweptArea # e.g. IfcRectangleProfileDef
solid = extrude(profile, item.ExtrudedDirection, item.Depth)
solid = apply(item.Position, solid) # item-local placement
IfcRevolvedAreaSolid revolves SweptArea around Axis by Angle
instead of extruding.
Pattern 4: Tessellation
coords = item.Coordinates.CoordList # IfcCartesianPointList3D
for tri in item.CoordIndex: # each row has 3 indices
a = coords[ tri[0] - 1 ] # 1-based -> 0-based
b = coords[ tri[1] - 1 ]
c = coords[ tri[2] - 1 ]
If item.PnIndex is present, a CoordIndex value i resolves as
coords[ PnIndex[i-1] - 1 ]. IfcPolygonalFaceSet is the same idea with
variable-length faces in Faces (IfcIndexedPolygonalFace).
Pattern 5: Brep
brep = IfcFacetedBrep
shell = brep.Outer # IfcClosedShell
for face in shell.CfsFaces: # IfcFace
for bound in face.Bounds: # IfcFaceOuterBound / IfcFaceBound
loop = bound.Bound # IfcPolyLoop
polygon = loop.Polygon # list of IfcCartesianPoint
Brep geometry is already explicit: read it, do not sweep. ALWAYS respect
IfcFaceOuterBound versus IfcFaceBound so holes are not filled in.
Pattern 6: MappedRepresentation
mapped = IfcMappedItem
source = mapped.MappingSource # IfcRepresentationMap
geom = decode( source.MappedRepresentation ) # recurse
geom = apply( source.MappingOrigin, geom )
geom = apply( mapped.MappingTarget, geom ) # per-instance transform
Typed families (doors, furniture) carry geometry once on the type and
reuse it through IfcMappedItem. NEVER skip the resolve step: the
element appears empty otherwise.
Reference Links
references/methods.md: full attribute signatures for the
representation, placement, solid, Brep, tessellation, and mapping
entities, per version.
references/examples.md: worked STEP snippets per RepresentationType
and the complete placement-to-matrix formula.
references/anti-patterns.md: the extraction mistakes that produce
elements at the origin, blocky models, scrambled meshes, or empty
geometry.
Related skills
ifc-syntax-geometry-representations: the representation framework
syntax, IfcShapeRepresentation, and the identifier/type catalogue.
ifc-syntax-geometry-placement: the placement tree syntax and the
right-handed axis derivation.
ifc-impl-reading-parsing: the two-pass parse and #id reference
resolution that geometry extraction depends on.
Official sources