mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
Bonsai: let standalone IfcCurtainWall bound spaces and boundaries
brunopostle reported that a curtain wall used as a standalone room side (not decomposed into IfcMember/IfcPlate children) was invisible to space/boundary generation, since only IfcWall, IfcColumn, IfcMember, IfcVirtualElement, and IfcPlate were treated as bounding classes. CyrilWaechter concretely proposed adding curtain wall to that detection list, while explicitly leaving structural elements (a separate, still-open design question) alone. IfcCurtainWall is not a schema subtype of IfcWall, so it was silently skipped by every class list that checked "is this a wall/column/etc." Three separate lists needed it: - tool.Spatial.is_bounding_class, used by "Generate Space" (cursor cutting-plane detection). - tool.Spatial.get_boundary_elements, used by "Generate Spaces From Walls" (bulk perimeter detection). - AddBoundary.auto_generate_boundaries' building_elements gather, used by "Add Boundary" when auto-detecting nearby elements for a single selected IfcSpace. The separate manual AddBoundary path (selecting an IfcSpace plus one IfcElement directly) was already class-agnostic and did not need a change; verified live that it already creates a boundary against an IfcCurtainWall today. Verified live in headless Blender: a synthetic 4m x 4m room with 3 IfcWalls and one standalone IfcCurtainWall (single object, not aggregated into members/plates) produced 0 spaces via "Generate Spaces From Walls" before this fix, and 1 correctly-bounded space after. The manual "Add Boundary" (IfcSpace + IfcCurtainWall selected) path created an IfcRelSpaceBoundary against the curtain wall both before and after, confirming it needed no change. IfcWindow remains untouched; CyrilWaechter was explicit that whether to auto-detect standalone windows/structural elements is a separate, unresolved design question. Fixes #3995 Generated with the assistance of an AI coding tool.
This commit is contained in:
@@ -682,6 +682,7 @@ class AddBoundary(bpy.types.Operator, tool.Ifc.Operator):
|
||||
tool.Ifc.get().by_type("IfcWall")
|
||||
+ tool.Ifc.get().by_type("IfcSlab")
|
||||
+ tool.Ifc.get().by_type("IfcVirtualElement")
|
||||
+ tool.Ifc.get().by_type("IfcCurtainWall")
|
||||
)
|
||||
|
||||
for building_element in building_elements:
|
||||
|
||||
@@ -755,7 +755,7 @@ class Spatial(bonsai.core.tool.Spatial):
|
||||
|
||||
@classmethod
|
||||
def is_bounding_class(cls, visible_element: ifcopenshell.entity_instance) -> bool:
|
||||
for ifc_class in ["IfcWall", "IfcColumn", "IfcMember", "IfcVirtualElement", "IfcPlate"]:
|
||||
for ifc_class in ["IfcWall", "IfcColumn", "IfcMember", "IfcVirtualElement", "IfcPlate", "IfcCurtainWall"]:
|
||||
if visible_element.is_a(ifc_class):
|
||||
return True
|
||||
return False
|
||||
@@ -936,7 +936,7 @@ class Spatial(bonsai.core.tool.Spatial):
|
||||
boundary_elements = []
|
||||
for obj in selected_objects:
|
||||
subelement = tool.Ifc.get_entity(obj)
|
||||
if subelement.is_a("IfcWall") or subelement.is_a("IfcColumn"):
|
||||
if subelement.is_a("IfcWall") or subelement.is_a("IfcColumn") or subelement.is_a("IfcCurtainWall"):
|
||||
boundary_elements.append(subelement)
|
||||
return boundary_elements
|
||||
|
||||
|
||||
Reference in New Issue
Block a user