| name | ifcos-syntax-util |
| description | Use when extracting data from IFC models using utility functions -- element properties, selector syntax, placement calculations, unit conversion, or cost/schedule data. Prevents the common mistake of manually parsing IFC relationships instead of using ifcopenshell.util helpers. Covers element utilities, selector syntax, placement helpers, date/unit conversion, and shape extraction. Keywords: ifcopenshell.util, selector, placement, unit conversion, element utility, shape extraction, ifcopenshell.util.element, ifcopenshell.util.selector, get element location, filter elements.
|
| license | MIT |
| compatibility | Designed for Claude Code. Requires IfcOpenShell Python library. |
| metadata | {"author":"OpenAEC-Foundation","version":"1.0"} |
IfcOpenShell Utility Modules (ifcopenshell.util.*)
Quick Reference
Decision Tree: Choosing the Right Utility Module
What data do you need from an IFC element?
├── Property sets, types, containers, materials?
│ └── ifcopenshell.util.element
│ ├── get_psets() → all property sets as dict
│ ├── get_pset() → single property set or property
│ ├── get_type() → type element (e.g., IfcWallType)
│ ├── get_container() → spatial container (e.g., IfcBuildingStorey)
│ ├── get_material() → material assignment
│ ├── get_materials() → list of individual materials
│ ├── get_decomposition() → child elements
│ └── get_aggregate() → parent aggregate
│
├── Query/filter elements by criteria?
│ └── ifcopenshell.util.selector
│ └── filter_elements() → CSS-like query syntax
│
├── Position/coordinates?
│ └── ifcopenshell.util.placement
│ ├── get_local_placement() → 4x4 transformation matrix
│ └── get_storey_elevation() → storey Z elevation
│
├── Unit conversion?
│ └── ifcopenshell.util.unit
│ ├── calculate_unit_scale() → scale factor to SI metres
│ ├── convert() → value between unit systems
│ └── get_project_unit() → project's default unit
│
├── Dates, durations, timestamps?
│ └── ifcopenshell.util.date
│ ├── ifc2datetime() → IFC date → Python datetime
│ └── datetime2ifc() → Python datetime → IFC format
│
├── Geometry metrics (area, volume, bbox)?
│ └── ifcopenshell.util.shape (requires processed geometry)
│ ├── get_volume() → element volume
│ ├── get_area() → surface area
│ ├── get_bbox() → bounding box
│ └── get_vertices() → vertex coordinates
│
├── Classification references?
│ └── ifcopenshell.util.classification
│ ├── get_references() → classification refs for element
│ └── get_classification() → parent classification system
│
├── Cost data?
│ └── ifcopenshell.util.cost
│ ├── get_cost_items_for_product() → cost items linked to product
│ └── get_cost_values() → cost item values
│
├── Schedule/sequence data?
│ └── ifcopenshell.util.sequence
│ ├── get_tasks_for_product() → tasks linked to product
│ └── count_working_days() → working days between dates
│
└── Schema introspection (attribute types, enums)?
└── ifcopenshell.util.attribute
├── get_primitive_type() → Python type for IFC attribute
└── get_enum_items() → enum options for attribute
Critical Warnings
- ALWAYS import utility modules explicitly:
import ifcopenshell.util.element, NOT from ifcopenshell.util import *.
- ALWAYS multiply raw coordinate values by
calculate_unit_scale(model) to get SI metres. IFC files store coordinates in project units (millimetres, feet, etc.).
- ALWAYS use
filter_elements() (modern API) for selector queries. NEVER use the deprecated Selector().parse() class.
- NEVER traverse IFC inverse relationships manually when a
ifcopenshell.util.element helper exists. Manual traversal is error-prone and schema-dependent.
- NEVER assume property set names are standardized. Custom property sets vary per project. ALWAYS check for
None returns.
- ALWAYS check
model.schema before using schema-specific property set names (e.g., Pset_WallCommon exists in IFC4 but attribute names differ from IFC2X3).
- NEVER call
ifcopenshell.util.shape functions without first processing geometry via ifcopenshell.geom. Shape utilities operate on processed geometry objects, NOT raw IFC entities.
Essential Patterns
Pattern 1: Extract All Properties from an Element
import ifcopenshell
import ifcopenshell.util.element
model = ifcopenshell.open("model.ifc")
wall = model.by_type("IfcWall")[0]
psets = ifcopenshell.util.element.get_psets(wall)
all_props = ifcopenshell.util.element.get_psets(wall, psets_only=False)
qsets = ifcopenshell.util.element.get_psets(wall, qtos_only=True)
wall_common = ifcopenshell.util.element.get_pset(wall, "Pset_WallCommon")
is_external = ifcopenshell.util.element.get_pset(
wall, "Pset_WallCommon", "IsExternal")
Pattern 2: Navigate Element Relationships
import ifcopenshell
import ifcopenshell.util.element
model = ifcopenshell.open("model.ifc")
wall = model.by_type("IfcWall")[0]
wall_type = ifcopenshell.util.element.get_type(wall)
container = ifcopenshell.util.element.get_container(wall)
material = ifcopenshell.util.element.get_material(wall)
materials = ifcopenshell.util.element.get_materials(wall)
parent = ifcopenshell.util.element.get_aggregate(wall)
building = model.by_type("IfcBuilding")[0]
children = ifcopenshell.util.element.get_decomposition(building)
Pattern 3: Filter Elements with Selector Queries
import ifcopenshell
import ifcopenshell.util.selector
model = ifcopenshell.open("model.ifc")
walls = ifcopenshell.util.selector.filter_elements(model, "IfcWall")
elements = ifcopenshell.util.selector.filter_elements(
model, "IfcWall, IfcSlab")
named = ifcopenshell.util.selector.filter_elements(
model, 'IfcWall, Name="External Wall"')
external = ifcopenshell.util.selector.filter_elements(
model, 'IfcWall, /Pset_WallCommon/.IsExternal = True')
ground = ifcopenshell.util.selector.filter_elements(
model, 'IfcBuildingElement, container="Ground Floor"')
concrete = ifcopenshell.util.selector.filter_elements(
model, 'IfcElement, material="Concrete"')
typed = ifcopenshell.util.selector.filter_elements(
model, 'IfcWall, type="WT01"')
ext_walls = ifcopenshell.util.selector.filter_elements(
model, 'IfcWall, Name *= "EXT"')
non_slabs = ifcopenshell.util.selector.filter_elements(
model, "! IfcSlab")
Pattern 4: Unit Conversion
import ifcopenshell
import ifcopenshell.util.unit
model = ifcopenshell.open("model.ifc")
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(model)
raw_length = 5000.0
length_metres = raw_length * unit_scale
length_unit = ifcopenshell.util.unit.get_project_unit(model, "LENGTHUNIT")
value_mm = ifcopenshell.util.unit.convert(
value=1.0,
from_prefix=None, from_unit="METRE",
to_prefix="MILLI", to_unit="METRE"
)
Pattern 5: Get Element Placement
import ifcopenshell
import ifcopenshell.util.placement
model = ifcopenshell.open("model.ifc")
wall = model.by_type("IfcWall")[0]
matrix = ifcopenshell.util.placement.get_local_placement(
wall.ObjectPlacement)
x, y, z = matrix[0][3], matrix[1][3], matrix[2][3]
rotation = matrix[:3, :3]
storey = model.by_type("IfcBuildingStorey")[0]
elevation = ifcopenshell.util.placement.get_storey_elevation(storey)
Pattern 6: Date Conversion
import ifcopenshell
import ifcopenshell.util.date
from datetime import datetime
model = ifcopenshell.open("model.ifc")
owner = model.by_type("IfcOwnerHistory")[0]
if owner.CreationDate:
dt = ifcopenshell.util.date.ifc2datetime(owner.CreationDate)
py_date = ifcopenshell.util.date.ifc2datetime("2024-06-15")
duration = ifcopenshell.util.date.ifc2datetime("P30D")
ifc_dt = ifcopenshell.util.date.datetime2ifc(
datetime(2024, 6, 15, 10, 30), "IfcDateTime")
ifc_date = ifcopenshell.util.date.datetime2ifc(
datetime(2024, 6, 15), "IfcDate")
Common Operations
Classification Lookup
import ifcopenshell
import ifcopenshell.util.classification
model = ifcopenshell.open("model.ifc")
wall = model.by_type("IfcWall")[0]
refs = ifcopenshell.util.classification.get_references(wall)
for ref in refs:
classification = ifcopenshell.util.classification.get_classification(ref)
print(f"{classification.Name}: {ref.Identification} - {ref.Name}")
Cost Item Lookup
import ifcopenshell
import ifcopenshell.util.cost
model = ifcopenshell.open("model.ifc")
wall = model.by_type("IfcWall")[0]
cost_items = ifcopenshell.util.cost.get_cost_items_for_product(wall)
for item in cost_items:
values = ifcopenshell.util.cost.get_cost_values(item)
schedule = ifcopenshell.util.cost.get_cost_schedule(item)
Schedule Task Lookup
import ifcopenshell
import ifcopenshell.util.sequence
model = ifcopenshell.open("model.ifc")
schedules = model.by_type("IfcWorkSchedule")
for schedule in schedules:
for task in ifcopenshell.util.sequence.get_root_tasks(schedule):
print(f"Task: {task.Name}")
calendar = ifcopenshell.util.sequence.get_calendar(task)
nested = ifcopenshell.util.sequence.get_nested_tasks(task)
Attribute Schema Introspection
import ifcopenshell
import ifcopenshell.util.attribute
schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name("IFC4")
entity_decl = schema.declaration_by_name("IfcWall")
attr = entity_decl.all_attributes()[1]
ptype = ifcopenshell.util.attribute.get_primitive_type(attr)
enum_attr = entity_decl.all_attributes()[7]
items = ifcopenshell.util.attribute.get_enum_items(enum_attr)
Geometry Extraction (Requires Processed Shapes)
import ifcopenshell
import ifcopenshell.geom
import ifcopenshell.util.shape
model = ifcopenshell.open("model.ifc")
settings = ifcopenshell.geom.settings()
settings.set(settings.USE_WORLD_COORDS, True)
wall = model.by_type("IfcWall")[0]
shape = ifcopenshell.geom.create_shape(settings, wall)
volume = ifcopenshell.util.shape.get_volume(shape.geometry)
area = ifcopenshell.util.shape.get_area(shape.geometry)
vertices = ifcopenshell.util.shape.get_vertices(shape.geometry)
bbox = ifcopenshell.util.shape.get_bbox(shape.geometry)
bottom_z = ifcopenshell.util.shape.get_bottom_elevation(shape.geometry)
top_z = ifcopenshell.util.shape.get_top_elevation(shape.geometry)
Copy/Duplicate Elements
import ifcopenshell
import ifcopenshell.util.element
model = ifcopenshell.open("model.ifc")
wall = model.by_type("IfcWall")[0]
new_wall = ifcopenshell.util.element.copy(model, wall)
deep_wall = ifcopenshell.util.element.copy_deep(model, wall)
Selector Query Syntax Reference
| Syntax | Meaning | Example |
|---|
IfcType | Select by IFC class | "IfcWall" |
IfcType, IfcType | Multiple classes | "IfcWall, IfcSlab" |
, Name="X" | Filter by Name equals | 'IfcWall, Name="W01"' |
, Name *= "X" | Name contains | 'IfcWall, Name *= "EXT"' |
, Name != None | Attribute is not null | 'IfcWall, Name != None' |
, /Pset/.Prop = val | Filter by property value | 'IfcWall, /Pset_WallCommon/.IsExternal = True' |
, type="X" | Filter by type name | 'IfcWall, type="WT01"' |
, container="X" | Filter by spatial container | 'IfcElement, container="Level 1"' |
, material="X" | Filter by material | 'IfcElement, material="Concrete"' |
! IfcType | Exclude class | "! IfcSlab" |
Module Summary Table
| Module | Import | Primary Functions | Schema Sensitivity |
|---|
element | ifcopenshell.util.element | get_psets, get_type, get_container, get_material | Low — works across all schemas |
selector | ifcopenshell.util.selector | filter_elements, get_element_value | Low — query syntax is schema-agnostic |
placement | ifcopenshell.util.placement | get_local_placement, get_storey_elevation | Low — placement structure is consistent |
unit | ifcopenshell.util.unit | calculate_unit_scale, convert, get_project_unit | Low — unit types are consistent |
date | ifcopenshell.util.date | ifc2datetime, datetime2ifc | Medium — IfcCalendarDate is IFC2X3 only |
shape | ifcopenshell.util.shape | get_volume, get_area, get_bbox, get_vertices | Low — operates on processed geometry |
classification | ifcopenshell.util.classification | get_references, get_classification | Low |
cost | ifcopenshell.util.cost | get_cost_items_for_product, get_cost_values | High — IFC4+ only |
sequence | ifcopenshell.util.sequence | get_root_tasks, count_working_days |
Version Notes
IFC2X3 Limitations
IfcCalendarDate entity used instead of ISO 8601 date strings. Use ifc2datetime() which handles both.
- Cost scheduling entities (
IfcCostSchedule, IfcCostItem) exist but with fewer attributes.
IfcTask has a different attribute structure (no TaskTime in IFC2X3).
IFC4 vs IFC4X3
- IFC4X3 adds
IfcAlignment and related entities supported by ifcopenshell.util.alignment.
- Property set names are consistent between IFC4 and IFC4X3 for building elements.
IfcOpenShell Version Notes
filter_elements() replaced Selector().parse(). The Selector class is deprecated.
get_pset() (singular) is a convenience wrapper added in recent versions. Falls back to get_psets() if unavailable.
Reference Links