diff --git a/src/blenderbim/blenderbim/bim/ifc.py b/src/blenderbim/blenderbim/bim/ifc.py index 5739cc3805..9942c7059c 100644 --- a/src/blenderbim/blenderbim/bim/ifc.py +++ b/src/blenderbim/blenderbim/bim/ifc.py @@ -237,7 +237,6 @@ class IfcStore: is_top_level_operator = not bool(IfcStore.current_transaction) if is_top_level_operator: - active_object = context.active_object IfcStore.begin_transaction(operator) IfcStore.get_file().begin_transaction() # This empty transaction ensures that each operator has at least one transaction @@ -253,11 +252,6 @@ class IfcStore: operator, rollback=lambda d: IfcStore.get_file().undo(), commit=lambda d: IfcStore.get_file().redo() ) IfcStore.end_transaction(operator) - try: - active_object.name - context.view_layer.objects.active = active_object - except: - pass return result diff --git a/src/blenderbim/blenderbim/bim/module/spatial/__init__.py b/src/blenderbim/blenderbim/bim/module/spatial/__init__.py index ba0f1b3426..0ab51ed853 100644 --- a/src/blenderbim/blenderbim/bim/module/spatial/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/spatial/__init__.py @@ -21,11 +21,12 @@ from . import ui, prop, operator classes = ( operator.AssignContainer, - operator.RemoveContainer, - operator.EnableEditingContainer, - operator.DisableEditingContainer, operator.ChangeSpatialLevel, operator.CopyToContainer, + operator.DisableEditingContainer, + operator.EnableEditingContainer, + operator.RemoveContainer, + operator.SelectContainer, prop.SpatialElement, prop.BIMSpatialProperties, prop.BIMObjectSpatialProperties, diff --git a/src/blenderbim/blenderbim/bim/module/spatial/operator.py b/src/blenderbim/blenderbim/bim/module/spatial/operator.py index 4f60148f68..2a40024cff 100644 --- a/src/blenderbim/blenderbim/bim/module/spatial/operator.py +++ b/src/blenderbim/blenderbim/bim/module/spatial/operator.py @@ -103,3 +103,12 @@ class CopyToContainer(bpy.types.Operator, Operator): for obj in context.selected_objects: core.copy_to_container(tool.Ifc, tool.Spatial, obj=obj, containers=containers) blenderbim.bim.handler.purge_module_data() + + +class SelectContainer(bpy.types.Operator, Operator): + bl_idname = "bim.select_container" + bl_label = "Select Container" + bl_options = {"REGISTER", "UNDO"} + + def _execute(self, context): + core.select_container(tool.Ifc, tool.Spatial, obj=context.active_object) diff --git a/src/blenderbim/blenderbim/bim/module/spatial/ui.py b/src/blenderbim/blenderbim/bim/module/spatial/ui.py index fbe92372c6..09cd98a199 100644 --- a/src/blenderbim/blenderbim/bim/module/spatial/ui.py +++ b/src/blenderbim/blenderbim/bim/module/spatial/ui.py @@ -62,6 +62,7 @@ class BIM_PT_spatial(Panel): row = self.layout.row(align=True) if SpatialData.data["is_contained"]: row.label(text=SpatialData.data["label"]) + row.operator("bim.select_container", icon="TRACKER", text="") row.operator("bim.enable_editing_container", icon="GREASEPENCIL", text="") if SpatialData.data["is_directly_contained"]: row.operator("bim.remove_container", icon="X", text="") diff --git a/src/blenderbim/blenderbim/core/spatial.py b/src/blenderbim/blenderbim/core/spatial.py index 8f8b538924..67259a5ae2 100644 --- a/src/blenderbim/blenderbim/core/spatial.py +++ b/src/blenderbim/blenderbim/core/spatial.py @@ -66,3 +66,10 @@ def copy_to_container(ifc, spatial, obj=None, containers=None): spatial.run_root_copy_class(obj=copied_obj) spatial.run_spatial_assign_container(structure_obj=to_container_obj, element_obj=copied_obj) spatial.disable_editing(obj) + + +def select_container(ifc, spatial, obj=None): + element = ifc.get_entity(obj) + if not element: + return + spatial.set_active_object(ifc.get_object(spatial.get_container(element))) diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index f9d7b38de8..6d6a9bbf6e 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -196,6 +196,7 @@ class Spatial: def import_containers(cls, parent=None): pass def run_root_copy_class(cls, obj=None): pass def run_spatial_assign_container(cls, structure_obj=None, element_obj=None): pass + def set_active_object(cls, obj): pass def set_relative_object_matrix(cls, target_obj, relative_to_obj, matrix): pass diff --git a/src/blenderbim/blenderbim/tool/spatial.py b/src/blenderbim/blenderbim/tool/spatial.py index b1f5389492..8e495f9209 100644 --- a/src/blenderbim/blenderbim/tool/spatial.py +++ b/src/blenderbim/blenderbim/tool/spatial.py @@ -101,6 +101,11 @@ class Spatial(blenderbim.core.tool.Spatial): tool.Ifc, tool.Collector, tool.Spatial, structure_obj=structure_obj, element_obj=element_obj ) + @classmethod + def set_active_object(cls, obj): + bpy.context.view_layer.objects.active = obj + obj.select_set(True) + @classmethod def set_relative_object_matrix(cls, target_obj, relative_to_obj, matrix): target_obj.matrix_world = relative_to_obj.matrix_world @ matrix diff --git a/src/blenderbim/test/bim/feature/spatial.feature b/src/blenderbim/test/bim/feature/spatial.feature index 31e200c128..dee421803f 100644 --- a/src/blenderbim/test/bim/feature/spatial.feature +++ b/src/blenderbim/test/bim/feature/spatial.feature @@ -40,3 +40,16 @@ Scenario: Copy to container When I set "scene.BIMSpatialProperties.containers[0].is_selected" to "True" And I press "bim.copy_to_container" Then the object "IfcWall/Cube.001" is in the collection "IfcSite/My Site" + +Scenario: Select container + Given an empty IFC project + And I add a cube + And the object "Cube" is selected + And I set "scene.BIMRootProperties.ifc_class" to "IfcWall" + And I press "bim.assign_class" + And the object "IfcWall/Cube" is selected + And I press "bim.enable_editing_container" + And the variable "site" is "tool.Ifc.get().by_type('IfcSite')[0].id()" + And I press "bim.assign_container(structure={site})" + When I press "bim.select_container" + Then nothing happens diff --git a/src/blenderbim/test/core/test_spatial.py b/src/blenderbim/test/core/test_spatial.py index 1b835428e1..7ac5a16248 100644 --- a/src/blenderbim/test/core/test_spatial.py +++ b/src/blenderbim/test/core/test_spatial.py @@ -94,3 +94,12 @@ class TestCopyToContainer: spatial.disable_editing("obj").should_be_called() subject.copy_to_container(ifc, spatial, obj="obj", containers=["to_container"]) + + +class TestSelectContainer: + def test_run(self, ifc, spatial): + ifc.get_entity("obj").should_be_called().will_return("element") + spatial.get_container("element").should_be_called().will_return("container") + ifc.get_object("container").should_be_called().will_return("container_obj") + spatial.set_active_object("container_obj").should_be_called() + subject.select_container(ifc, spatial, obj="obj") diff --git a/src/blenderbim/test/tool/test_spatial.py b/src/blenderbim/test/tool/test_spatial.py index 84d50ef787..cba51c6ed8 100644 --- a/src/blenderbim/test/tool/test_spatial.py +++ b/src/blenderbim/test/tool/test_spatial.py @@ -192,6 +192,15 @@ class TestRunSpatialAssignContainer(NewFile): pass +class TestSetActiveObject(NewFile): + def test_run(self): + obj = bpy.data.objects.new("Object", None) + bpy.context.scene.collection.objects.link(obj) + subject.set_active_object(obj) + assert bpy.context.view_layer.objects.active == obj + assert obj in bpy.context.selected_objects + + class TestSetRelativeObjectMatrix(NewFile): def test_run(self): obj = bpy.data.objects.new("Object", None)