diff --git a/src/bonsai/bonsai/bim/module/spatial/operator.py b/src/bonsai/bonsai/bim/module/spatial/operator.py index 33e1b23595..a59e3598e6 100644 --- a/src/bonsai/bonsai/bim/module/spatial/operator.py +++ b/src/bonsai/bonsai/bim/module/spatial/operator.py @@ -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"} diff --git a/src/bonsai/bonsai/tool/spatial.py b/src/bonsai/bonsai/tool/spatial.py index 851560c969..b8e2645016 100644 --- a/src/bonsai/bonsai/tool/spatial.py +++ b/src/bonsai/bonsai/tool/spatial.py @@ -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)