mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 01:11:40 +00:00
Add extend/regenerate walls to multiple undersides
extend_walls_to_underside now accepts multiple slab/roof objects in a single operation — all selected non-LAYER2 IFC elements are treated as clip targets, all LAYER2 elements as walls. Placement sync is done once upfront; each wall is then clipped against every selected slab before reloading. Also adds bim.regenerate_wall_to_underside (Shift+G): after moving a slab, re-clips connected walls using the existing IfcRelConnectsElements(TOP) relationship. Old booleans are removed via remove_representation_item before re-clipping. Generated with the assistance of an AI coding tool.
This commit is contained in:
@@ -300,20 +300,21 @@ class ExtendWallsToUnderside(bpy.types.Operator, tool.Ifc.Operator):
|
||||
# of the selected walls has an in-progress parametric draft, commit it before
|
||||
# extending, so the slab clip operates on the just-finalised IFC state.
|
||||
_commit_pending_wall_edits_for_selection(context)
|
||||
slab = None
|
||||
slabs: list[bpy.types.Object] = []
|
||||
walls: list[bpy.types.Object] = []
|
||||
if (obj := tool.Blender.get_active_object(is_selected=True)) and (element := tool.Ifc.get_entity(obj)):
|
||||
slab = obj
|
||||
for obj in tool.Blender.get_selected_objects(include_active=False):
|
||||
for obj in tool.Blender.get_selected_objects():
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
usage = tool.Model.get_usage_type(element) if element else None
|
||||
if element and usage == "LAYER2":
|
||||
if not element:
|
||||
continue
|
||||
if tool.Model.get_usage_type(element) == "LAYER2":
|
||||
walls.append(obj)
|
||||
if slab and walls:
|
||||
core.extend_wall_to_slab(tool.Ifc, tool.Geometry, tool.Model, slab, walls)
|
||||
else:
|
||||
slabs.append(obj)
|
||||
if slabs and walls:
|
||||
core.extend_wall_to_slab(tool.Ifc, tool.Geometry, tool.Model, slabs, walls)
|
||||
_resync_walls_after_mutation(walls)
|
||||
else:
|
||||
self.report({"ERROR"}, "Please select at least one LAYER2 element and an active element")
|
||||
self.report({"ERROR"}, "Please select at least one LAYER2 element and at least one other IFC element")
|
||||
|
||||
|
||||
class RegenerateWallToUnderside(bpy.types.Operator, tool.Ifc.Operator):
|
||||
|
||||
@@ -190,20 +190,26 @@ def extend_wall_to_slab(
|
||||
ifc: type[tool.Ifc],
|
||||
geometry: type[tool.Geometry],
|
||||
model: type[tool.Model],
|
||||
slab_obj: bpy.types.Object,
|
||||
slab_objs: list[bpy.types.Object],
|
||||
wall_objs: list[bpy.types.Object],
|
||||
) -> None:
|
||||
clip = model.get_slab_clipping_bmesh(slab_obj)
|
||||
if not clip:
|
||||
return
|
||||
slab = ifc.get_entity(slab_obj)
|
||||
for obj in wall_objs:
|
||||
if ifc.is_moved(obj):
|
||||
geometry.run_edit_object_placement(obj=obj)
|
||||
wall = ifc.get_entity(obj)
|
||||
model.clip_wall_to_slab(wall, clip)
|
||||
model.connect_wall_to_slab(wall, slab)
|
||||
model.reload_body_representation(wall_objs)
|
||||
clipped_walls = []
|
||||
for slab_obj in slab_objs:
|
||||
clip = model.get_slab_clipping_bmesh(slab_obj)
|
||||
if not clip:
|
||||
continue
|
||||
slab = ifc.get_entity(slab_obj)
|
||||
for obj in wall_objs:
|
||||
wall = ifc.get_entity(obj)
|
||||
model.clip_wall_to_slab(wall, clip)
|
||||
model.connect_wall_to_slab(wall, slab)
|
||||
if obj not in clipped_walls:
|
||||
clipped_walls.append(obj)
|
||||
if clipped_walls:
|
||||
model.reload_body_representation(clipped_walls)
|
||||
|
||||
|
||||
class RequireTwoWallsError(Exception):
|
||||
|
||||
Reference in New Issue
Block a user