Deleting a slab that was connected to a wall via IfcRelConnectsElements(TOP)
left the wall holding orphan IfcBooleanResult items + a stale BBIM_Boolean
pset. The disconnect operator already runs the right cleanup; element delete
just never invoked it.
Extract the per-kind cleanup into core.connection.disconnect_rel so the
operator (bim.disconnect_elements) and a new cascade in
tool.Geometry.delete_ifc_object share one dispatch table. Adding a future
rel kind to tool.Connection.find_rels now flows into both call sites
automatically; an AST forward-compat guard enforces coverage.
Other adjustments:
- regenerate_wall_to_underside zero-slab branch now removes stale clip
booleans instead of silently skipping, so disconnecting the last TOP
slab also reverts the wall correctly.
- duplicate_ifc_objects (Shift+D) calls strip_underside_booleans on copied
walls so the duplicate doesn't carry over the source's slab trim, then
reloads the body representation when something was stripped so the
viewport reflects the change without waiting on Shift+G.
- batch_being_deleted_ids threads through OverrideDelete so the cascade
can suppress partner-side regenerate when both endpoints are queued for
deletion in the same batch.
This file was generated with the assistance of an AI coding tool.
Single generic dispatcher replaces UnjoinWallPathConnection +
DisconnectWallSlab. Takes two GlobalIds, looks up every supported
rel between them via tool.Connection.find_rels, dispatches the right
cleanup by rel kind:
- path (IfcRelConnectsPathElements): remove_connection on every rel
in both orientations + recreate both walls + resync drafts.
- element-top (IfcRelConnectsElements with Description=="TOP"):
disconnect_element + regenerate_wall_to_underside on the wall side
via orient_element_top to recover which input is wall vs slab.
- element (other IfcRelConnectsElements): plain disconnect_element.
tool.Connection lands as a new tool module with two helpers:
- find_rels(a, b): every supported rel between two elements, walking
both ConnectedTo + ConnectedFrom (catches both authoring
orientations and dedups by id).
- find_rel(a, b): first-match convenience.
- orient_element_top(rel, a, b): recovers (wall, slab) from a TOP
rel regardless of which input came first.
Updates GizmoWallUnjoinSingle to target bim.disconnect_elements with
both element_a_guid + element_b_guid pre-filled per icon. Adds the
single registration in tool/__init__.py and the classes-tuple entry
in bim/module/model/__init__.py. Drops the two retired classes.
Tests cover both cleanup branches (path + element-top), missing
endpoints, no-rel-found, and registration smoke.
Generated with the assistance of an AI coding tool.