Schema-illegal IfcDoor->IfcWallType pairings parse cleanly but propagate
into operators that fan out by type and eventually crash the wrapper.
Block the pairing at its source: API guard in ifcopenshell.api.type.
assign_type, per-object partition in BIM_OT_assign_type + DuplicateType,
new tool.Type.is_relating_type_compatible helper, AST forward-compat
guard. Files in the wild are still loaded unchanged.
Generated with the assistance of an AI coding tool.
Adds the IFC-library primitives the ifcpatch Migrate recipe needs for a
defensive IFC4 / IFC4X3 -> IFC2X3 downgrade without each caller
reinventing the wheel.
In ifcopenshell.util.schema:
- Migrator(fallback_element_to_proxy=False) opt-in: when True, IFC4-only
IfcElement subclasses (IfcLamp, IfcPipeSegment, IfcGeographicElement,
...) migrate to IfcBuildingElementProxy instead of raising. Default
preserves the strict failure-on-unmappable contract for existing
callers (classification API, etc.).
- geometry_classes_introduced_after(target, source) derives the
IfcRepresentationItem subclasses present in `source` but absent in
`target` directly from the loaded schemas. Cached per pair. Replaces
hand-curated class lists that drift with each IFC update.
ifc4_only_geometry_classes() retained as an alias.
- generate_default_value synthesises a unit IfcAxis2Placement2D /
IfcAxis2Placement3D when downgrading entities whose Position became
required in the target schema (IfcIShapeProfileDef and friends in
IFC2X3).
- Enum-mismatch detection upgraded from string-matched RuntimeError to a
structural check via ifcopenshell.util.attribute.get_enum_items so
upgrade paths still surface real bugs loudly.
In ifcopenshell.util.shape_builder:
- polygonal_face_set_to_faceted_brep converts IfcPolygonalFaceSet /
IfcTriangulatedFaceSet (IFC4-only) directly to IfcFacetedBrep,
preserving topology including IfcIndexedPolygonalFaceWithVoids inner
bounds. Validates inputs at the boundary.
- arc_to_polyline_points approximates a circular arc through three
points with a chord polyline of configurable subdivisions. Tolerates
floating-point noise on planar Z. Raises on non-planar or invalid
inputs.
Test coverage: 47 unit tests across schema + shape_builder lanes
covering each helper directly (no transitive-only coverage), including
regression pins for the IFC4X3-prefix ordering invariant in
get_fallback_schema and the strict-default Migrator contract.
Generated with the assistance of an AI coding tool.
add_railing_representation now factors into two parts:
* compute_wall_mounted_handrail_geometry returns a pure-geometry
WallMountedHandrailGeometry dataclass (handrail polyline + support
list + terminal caps), no IFC mutation.
* add_railing_representation wraps that dataclass into an
IfcShapeRepresentation as before.
Downstream consumers that want the same math without round-tripping
through an IFC file (Blender gizmo previews, viewport drafts) now
drive compute_X directly. Future add_X_representation work in the
geometry API is encouraged to follow the same shape — a sibling
compute_X function + thin IFC wrapper.
The railing_type parameter is dropped from the signature — only
WALL_MOUNTED_HANDRAIL was ever supported, so the kwarg was dead.
The Bonsai railing-modifier caller is updated in the same commit
to stop passing it; without that update Bonsai's
finish_editing_railing_path raises TypeError on the first edit.
RailingSupport and WallMountedHandrailGeometry use @dataclass(slots=True)
— they're constructed N-per-cap during arc sampling, so the per-instance
overhead matters.
Public symbols (RailingSupport, TERMINAL_TYPE,
WallMountedHandrailGeometry, compute_wall_mounted_handrail_geometry,
add_railing_representation) re-exported from ifcopenshell.api.geometry.
New test/api/geometry/test_add_railing_representation.py covers the
compute/wrap contract.
Generated with the assistance of an AI coding tool.
Centralises the millimetre-to-metre conversion shortcut that
add_door_representation and add_window_representation each defined
locally. Subsequent commits in this PR switch both call sites to
import this from util.unit, removing the duplicate definitions.
Generated with the assistance of an AI coding tool.
IfcRelConnectsPathElements has an optional ConnectionGeometry attribute for
recording the geometric cut-plane between adjacent elements, but there was
no way to set it via the API.
Generated with the assistance of an AI coding tool.
assign_product creates IfcRelAssignsToProduct linking a structural member to
a physical building element. assign_to_building creates IfcRelServicesBuildings
linking a structural analysis model to a building. add_topology_representation
creates IfcTopologyRepresentation for structural elements, inferring the
representation type from the item class.
Generated with the assistance of an AI coding tool.
Both attributes are required by the IFC schema but were not settable via
the API function. Add physical_or_virtual and internal_or_external parameters
with "NOTDEFINED" defaults for backward compatibility. Update Bonsai boundary
panel to expose both fields in the editor.
Generated with the assistance of an AI coding tool.
If a file had an IfcProjectedCRS without an IfcCoordinateOperation (or
vice versa), add_georeferencing would return early without creating the
missing entity. This caused edit_georeferencing to crash with IndexError.
Now detects the inconsistent state, cleans up, and recreates both.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add geometry.clip_solid API
* Add geometry.clip_solid_bounded API
* Add geometry.copy_representation API
Deep-copies the named representation from a source element to a target
element.
Generated with the assistance of an AI coding tool.
The nest assign_object API now removes existing spatial containment and
aggregate relationships before creating the nest, matching the behavior
documented in its docstring and consistent with aggregate.assign_object.
Fix#7248
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
add_boolean was removing second operands from ALL IfcShapeRepresentations
that referenced them, which could corrupt unrelated shapes and leave
representations with empty Items (bug #7803).
The API no longer modifies Items — callers manage this explicitly.
validate_type and Bonsai's AddBoolean operator now handle their own
item removal scoped to the correct representation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
remove_deep is deprecated and can silently delete elements still in use.
remove_deep2 requires zero inverses before removal, making it safer.
Also fixes a double-removal bug in remove_grid_axis and prevents
removing the last prop template from a pset template.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously, sort, reverse list, and join functionality was implemented
as special cases in Bonsai itself. Given that it has usecases
(especially in material lists, but any sort of list applies) I've moved
this function into the IOS formatting language.
The IOS formatting language previously wasn't capable of this, but the
awesome addition by @falken10vdl made the formatting language accept
queries inline, so that means it can handle lists. I also added tests
for all the new functions and expression syntax (+-*/ operators).
I simplified the code that gets the evaluated text literal - previously
it seems to call format() multiple times.