Option to select only immediate children in Spatial Decomposition panel

This commit is contained in:
Ryan Schultz
2025-06-28 15:00:23 -05:00
parent 553003e664
commit d300454118
2 changed files with 35 additions and 14 deletions
@@ -322,7 +322,7 @@ class SelectSimilarContainer(bpy.types.Operator):
obj=context.active_object,
is_recursive=self.is_recursive,
)
self.is_recursive = True # <-- forcibly reset
self.is_recursive = True # <-- forcibly reset
return {"FINISHED"}
@@ -445,18 +445,36 @@ class SelectDecomposedElements(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"}
should_filter: bpy.props.BoolProperty(name="Should Filter", default=True, options={"SKIP_SAVE"})
container: bpy.props.IntProperty()
is_recursive: bpy.props.BoolProperty(default=True, options={"SKIP_SAVE"})
@classmethod
def description(cls, context, operator):
return "Select the active item" + "\nALT+CLICK to select all listed elements"
return (
"Select the active item"
+ "\nALT+CLICK to select all listed elements.\nCTRL + CLICK to select only one level deep"
)
def invoke(self, context, event):
if event.type == "LEFTMOUSE" and event.alt:
self.should_filter = False
if event.type == "LEFTMOUSE":
if event.alt:
self.should_filter = False
if event.ctrl:
self.is_recursive = False
return self.execute(context)
def execute(self, context):
tool.Spatial.select_products(tool.Spatial.get_filtered_elements(self.should_filter))
tool.Spatial.select_products(tool.Spatial.get_filtered_elements(self.should_filter, self.is_recursive))
# Make selected active element in list, the active object
props = tool.Spatial.get_spatial_props()
active_element = props.active_element
if active_element and active_element.type == "OCCURRENCE":
ifc_file = tool.Ifc.get()
ifc_entity = ifc_file.by_id(active_element.ifc_definition_id)
obj = tool.Ifc.get_object(ifc_entity)
if obj:
context.view_layer.objects.active = obj
obj.select_set(True)
return {"FINISHED"}
+12 -9
View File
@@ -1304,8 +1304,9 @@ class Spatial(bonsai.core.tool.Spatial):
props = cls.get_object_spatial_props(obj)
props.container_obj = container_obj
@classmethod
def get_filtered_elements(cls, should_filter: bool = True) -> Iterable[ifcopenshell.entity_instance]:
def get_filtered_elements(cls, should_filter: bool = True, is_recursive: bool = True) -> Iterable[ifcopenshell.entity_instance]:
ifc_file = tool.Ifc.get()
props = cls.get_spatial_props()
container = ifc_file.by_id(props.active_container.ifc_definition_id)
@@ -1314,7 +1315,7 @@ class Spatial(bonsai.core.tool.Spatial):
if not should_filter:
if props.should_include_children:
elements = ifcopenshell.util.element.get_decomposition(container, is_recursive=True)
elements = ifcopenshell.util.element.get_decomposition(container, is_recursive=is_recursive)
else:
queue = list(set(ifcopenshell.util.element.get_contained(container)))
elements = set()
@@ -1386,15 +1387,16 @@ class Spatial(bonsai.core.tool.Spatial):
relating_type = ifc_file.by_id(ifc_id)
if props.should_include_children:
elements = ifcopenshell.util.element.get_decomposition(container, is_recursive=True)
elements = ifcopenshell.util.element.get_decomposition(container, is_recursive=is_recursive)
else:
elements = set(ifcopenshell.util.element.get_contained(container))
for e in elements:
elements.update(ifcopenshell.util.element.get_decomposition(e))
if is_recursive:
for e in list(elements):
elements.update(ifcopenshell.util.element.get_decomposition(e))
return cls.filter_elements(elements, ifc_class, relating_type, is_untyped, element_filter)
elif props.element_mode == "DECOMPOSITION":
occurrence = ifc_file.by_id(active_element.ifc_definition_id)
elements = ifcopenshell.util.element.get_decomposition(occurrence, is_recursive=True)
elements = ifcopenshell.util.element.get_decomposition(occurrence, is_recursive=is_recursive)
elements.add(occurrence)
return elements
elif props.element_mode == "CLASSIFICATION":
@@ -1404,11 +1406,12 @@ class Spatial(bonsai.core.tool.Spatial):
if active_element.type == "CLASSIFICATION":
identification = active_element.identification
if props.should_include_children:
elements = ifcopenshell.util.element.get_decomposition(container, is_recursive=True)
elements = ifcopenshell.util.element.get_decomposition(container, is_recursive=is_recursive)
else:
elements = set(ifcopenshell.util.element.get_contained(container))
for e in elements:
elements.update(ifcopenshell.util.element.get_decomposition(e))
if is_recursive:
for e in list(elements):
elements.update(ifcopenshell.util.element.get_decomposition(e))
def filter_element(element: ifcopenshell.entity_instance) -> bool:
references = ifcopenshell.util.classification.get_references(element)