3 KiB
Space extraction and object modifications
Extracting a space
The space command extracts an IfcSpace and all elements contained within it
(furniture, walls, etc.) using the ifcopenshell location filter.
# by Name (room code)
uv run ifccommit.py space input.ifc out.ifc A102
# by LongName (human label)
uv run ifccommit.py space input.ifc out.ifc "Living Room" --by longname
Internally the query is:
IfcElement, location = "A102"
The location filter follows IfcRelContainedInSpatialStructure links — it
returns the IfcSpace itself plus every element directly contained in it.
Known limitation — aggregated spaces
Some IFC files place spaces via IfcRelAggregates instead of
IfcRelContainedInSpatialStructure. The location filter only follows the
latter, so those spaces appear empty. This is a data modelling choice in the
source file, not a bug in ifcbus.
Multi-match with --by longname
When a LongName matches several spaces (e.g. "Bathroom 1" → A104 and B104),
the command writes one output file per space:
dist/out_A104.ifc
dist/out_B104.ifc
The stem of the user-provided output path is reused; the space Name is
appended as a suffix.
Moving objects
IFC element positions are stored in a 4×4 transformation matrix inside
IfcLocalPlacement → IfcAxis2Placement3D. The last column holds the
translation in the file's length unit (metres for duplex.ifc).
[[ r00 r01 r02 X ],
[ r10 r11 r12 Y ],
[ r20 r21 r22 Z ],
[ 0 0 0 1 ]]
Reading and writing placement
import ifcopenshell
import ifcopenshell.util.placement
import ifcopenshell.api
model = ifcopenshell.open("input.ifc")
el = model.by_id(17902) # entity id (not GlobalId)
matrix = ifcopenshell.util.placement.get_local_placement(el.ObjectPlacement)
# translate +2 m on world X axis ("right")
matrix[0, 3] += 2.0
ifcopenshell.api.run(
"geometry.edit_object_placement",
model,
product=el,
matrix=matrix,
)
model.write("output.ifc")
Finding an element by name
Entity ids are file-specific and unstable. Prefer searching by name:
results = [
e for e in model.by_type("IfcFurnishingElement")
if "168381" in (e.Name or "")
]
el = results[0]
Or use ifcopenshell.util.selector.filter_elements for richer queries.
Axis convention
"Right" is ambiguous without a viewport. In duplex.ifc the world X axis is used as the reference. Verify with the placement matrix before committing to a direction — a 180° rotated element has its local X pointing in the opposite direction to world X.
move command
uv run ifccommit.py move input.ifc output.ifc <entity_id> --x 2 --y 0 --z 0
Offsets are in the file's length unit (metres for duplex.ifc). Example:
uv run ifccommit.py move samples/duplex.ifc dist/duplex_moved_table.ifc 17902 --x 2
# Element : #17902 M_Table-Coffee:0915 x 1830 x 0457mm:...
# Before : X=2.6192 Y=-15.3432 Z=0.0000
# After : X=4.6192 Y=-15.3432 Z=0.0000