mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 06:58:56 +00:00
New feature to select all objects in same container
This commit is contained in:
@@ -27,6 +27,7 @@ classes = (
|
|||||||
operator.EnableEditingContainer,
|
operator.EnableEditingContainer,
|
||||||
operator.RemoveContainer,
|
operator.RemoveContainer,
|
||||||
operator.SelectContainer,
|
operator.SelectContainer,
|
||||||
|
operator.SelectSimilarContainer,
|
||||||
prop.SpatialElement,
|
prop.SpatialElement,
|
||||||
prop.BIMSpatialProperties,
|
prop.BIMSpatialProperties,
|
||||||
prop.BIMObjectSpatialProperties,
|
prop.BIMObjectSpatialProperties,
|
||||||
|
|||||||
@@ -112,3 +112,12 @@ class SelectContainer(bpy.types.Operator, Operator):
|
|||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
core.select_container(tool.Ifc, tool.Spatial, obj=context.active_object)
|
core.select_container(tool.Ifc, tool.Spatial, obj=context.active_object)
|
||||||
|
|
||||||
|
|
||||||
|
class SelectSimilarContainer(bpy.types.Operator, Operator):
|
||||||
|
bl_idname = "bim.select_similar_container"
|
||||||
|
bl_label = "Select Similar Container"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def _execute(self, context):
|
||||||
|
core.select_similar_container(tool.Ifc, tool.Spatial, obj=context.active_object)
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ class BIM_PT_spatial(Panel):
|
|||||||
if SpatialData.data["is_contained"]:
|
if SpatialData.data["is_contained"]:
|
||||||
row.label(text=SpatialData.data["label"])
|
row.label(text=SpatialData.data["label"])
|
||||||
row.operator("bim.select_container", icon="TRACKER", text="")
|
row.operator("bim.select_container", icon="TRACKER", text="")
|
||||||
|
row.operator("bim.select_similar_container", icon="RESTRICT_SELECT_OFF", text="")
|
||||||
row.operator("bim.enable_editing_container", icon="GREASEPENCIL", text="")
|
row.operator("bim.enable_editing_container", icon="GREASEPENCIL", text="")
|
||||||
if SpatialData.data["is_directly_contained"]:
|
if SpatialData.data["is_directly_contained"]:
|
||||||
row.operator("bim.remove_container", icon="X", text="")
|
row.operator("bim.remove_container", icon="X", text="")
|
||||||
|
|||||||
@@ -73,3 +73,13 @@ def select_container(ifc, spatial, obj=None):
|
|||||||
if not element:
|
if not element:
|
||||||
return
|
return
|
||||||
spatial.set_active_object(ifc.get_object(spatial.get_container(element)))
|
spatial.set_active_object(ifc.get_object(spatial.get_container(element)))
|
||||||
|
|
||||||
|
|
||||||
|
def select_similar_container(ifc, spatial, obj=None):
|
||||||
|
element = ifc.get_entity(obj)
|
||||||
|
if not element:
|
||||||
|
return
|
||||||
|
for subelement in spatial.get_decomposed_elements(spatial.get_container(element)):
|
||||||
|
obj = ifc.get_object(subelement)
|
||||||
|
if obj:
|
||||||
|
spatial.select_object(obj)
|
||||||
|
|||||||
@@ -191,11 +191,13 @@ class Spatial:
|
|||||||
def duplicate_object_and_data(cls, obj): pass
|
def duplicate_object_and_data(cls, obj): pass
|
||||||
def enable_editing(cls, obj): pass
|
def enable_editing(cls, obj): pass
|
||||||
def get_container(cls, element): pass
|
def get_container(cls, element): pass
|
||||||
|
def get_decomposed_elements(cls, container): pass
|
||||||
def get_object_matrix(cls, obj): pass
|
def get_object_matrix(cls, obj): pass
|
||||||
def get_relative_object_matrix(cls, target_obj, relative_to_obj): pass
|
def get_relative_object_matrix(cls, target_obj, relative_to_obj): pass
|
||||||
def import_containers(cls, parent=None): pass
|
def import_containers(cls, parent=None): pass
|
||||||
def run_root_copy_class(cls, obj=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 run_spatial_assign_container(cls, structure_obj=None, element_obj=None): pass
|
||||||
|
def select_object(cls, obj): pass
|
||||||
def set_active_object(cls, obj): pass
|
def set_active_object(cls, obj): pass
|
||||||
def set_relative_object_matrix(cls, target_obj, relative_to_obj, matrix): pass
|
def set_relative_object_matrix(cls, target_obj, relative_to_obj, matrix): pass
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,10 @@ class Spatial(blenderbim.core.tool.Spatial):
|
|||||||
def get_container(cls, element):
|
def get_container(cls, element):
|
||||||
return ifcopenshell.util.element.get_container(element)
|
return ifcopenshell.util.element.get_container(element)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_decomposed_elements(cls, container):
|
||||||
|
return ifcopenshell.util.element.get_decomposition(container)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_object_matrix(cls, obj):
|
def get_object_matrix(cls, obj):
|
||||||
return obj.matrix_world
|
return obj.matrix_world
|
||||||
@@ -101,6 +105,10 @@ class Spatial(blenderbim.core.tool.Spatial):
|
|||||||
tool.Ifc, tool.Collector, tool.Spatial, structure_obj=structure_obj, element_obj=element_obj
|
tool.Ifc, tool.Collector, tool.Spatial, structure_obj=structure_obj, element_obj=element_obj
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def select_object(cls, obj):
|
||||||
|
obj.select_set(True)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def set_active_object(cls, obj):
|
def set_active_object(cls, obj):
|
||||||
bpy.context.view_layer.objects.active = obj
|
bpy.context.view_layer.objects.active = obj
|
||||||
|
|||||||
@@ -53,3 +53,16 @@ Scenario: Select container
|
|||||||
And I press "bim.assign_container(structure={site})"
|
And I press "bim.assign_container(structure={site})"
|
||||||
When I press "bim.select_container"
|
When I press "bim.select_container"
|
||||||
Then nothing happens
|
Then nothing happens
|
||||||
|
|
||||||
|
Scenario: Select similar 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_similar_container"
|
||||||
|
Then nothing happens
|
||||||
|
|||||||
@@ -103,3 +103,13 @@ class TestSelectContainer:
|
|||||||
ifc.get_object("container").should_be_called().will_return("container_obj")
|
ifc.get_object("container").should_be_called().will_return("container_obj")
|
||||||
spatial.set_active_object("container_obj").should_be_called()
|
spatial.set_active_object("container_obj").should_be_called()
|
||||||
subject.select_container(ifc, spatial, obj="obj")
|
subject.select_container(ifc, spatial, obj="obj")
|
||||||
|
|
||||||
|
|
||||||
|
class TestSelectSimilarContainer:
|
||||||
|
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")
|
||||||
|
spatial.get_decomposed_elements("container").should_be_called().will_return(["contained_element"])
|
||||||
|
ifc.get_object("contained_element").should_be_called().will_return("contained_obj")
|
||||||
|
spatial.select_object("contained_obj").should_be_called()
|
||||||
|
subject.select_similar_container(ifc, spatial, obj="obj")
|
||||||
|
|||||||
@@ -128,6 +128,15 @@ class TestGetContainer(NewFile):
|
|||||||
assert subject.get_container(wall) == site
|
assert subject.get_container(wall) == site
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetDecomposedElements(NewFile):
|
||||||
|
def test_run(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
site = ifc.createIfcSite()
|
||||||
|
wall = ifc.createIfcWall()
|
||||||
|
ifcopenshell.api.run("spatial.assign_container", ifc, product=wall, relating_structure=site)
|
||||||
|
assert subject.get_decomposed_elements(site) == [wall]
|
||||||
|
|
||||||
|
|
||||||
class TestGetObjectMatrix(NewFile):
|
class TestGetObjectMatrix(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
obj = bpy.data.objects.new("Object", None)
|
obj = bpy.data.objects.new("Object", None)
|
||||||
@@ -192,6 +201,14 @@ class TestRunSpatialAssignContainer(NewFile):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestSelectObject(NewFile):
|
||||||
|
def test_run(self):
|
||||||
|
obj = bpy.data.objects.new("Object", None)
|
||||||
|
bpy.context.scene.collection.objects.link(obj)
|
||||||
|
subject.select_object(obj)
|
||||||
|
assert obj in bpy.context.selected_objects
|
||||||
|
|
||||||
|
|
||||||
class TestSetActiveObject(NewFile):
|
class TestSetActiveObject(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
obj = bpy.data.objects.new("Object", None)
|
obj = bpy.data.objects.new("Object", None)
|
||||||
|
|||||||
Reference in New Issue
Block a user