Fix bug where you couldn't bulk copy non-geometric elements to other spatial containers

This commit is contained in:
Dion Moult
2021-10-20 18:47:55 +11:00
parent 871ad1ab7f
commit 503f0399ff
13 changed files with 234 additions and 80 deletions
@@ -28,3 +28,15 @@ Scenario: Assign container
And the variable "site" is "tool.Ifc.get().by_type('IfcSite')[0].id()"
When I press "bim.assign_container(structure={site})"
Then the object "IfcWall/Cube" is in the collection "IfcSite/My Site"
Scenario: Copy to 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"
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"
+7 -7
View File
@@ -49,13 +49,6 @@ def collector():
prophet.verify()
@pytest.fixture
def container():
prophet = Prophecy(blenderbim.core.tool.Container)
yield prophet
prophet.verify()
@pytest.fixture
def context():
prophet = Prophecy(blenderbim.core.tool.Context)
@@ -105,6 +98,13 @@ def selector():
prophet.verify()
@pytest.fixture
def spatial():
prophet = Prophecy(blenderbim.core.tool.Spatial)
yield prophet
prophet.verify()
@pytest.fixture
def style():
prophet = Prophecy(blenderbim.core.tool.Style)
+48 -17
View File
@@ -17,44 +17,42 @@
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.spatial as subject
from test.core.bootstrap import ifc, collector, container
from test.core.bootstrap import ifc, collector, spatial
class TestAssignContainer:
def test_run(self, ifc, collector, container):
container.can_contain("structure_obj", "element_obj").should_be_called().will_return(True)
def test_run(self, ifc, collector, spatial):
spatial.can_contain("structure_obj", "element_obj").should_be_called().will_return(True)
ifc.get_entity("structure_obj").should_be_called().will_return("structure")
ifc.get_entity("element_obj").should_be_called().will_return("element")
ifc.run(
"spatial.assign_container", product="element", relating_structure="structure"
).should_be_called().will_return("rel")
container.disable_editing("element_obj").should_be_called()
spatial.disable_editing("element_obj").should_be_called()
collector.assign("element_obj").should_be_called()
assert (
subject.assign_container(
ifc, collector, container, structure_obj="structure_obj", element_obj="element_obj"
)
subject.assign_container(ifc, collector, spatial, structure_obj="structure_obj", element_obj="element_obj")
== "rel"
)
class TestEnableEditingContainer:
def test_run(self, container):
container.enable_editing("obj").should_be_called()
container.import_containers().should_be_called()
subject.enable_editing_container(container, obj="obj")
def test_run(self, spatial):
spatial.enable_editing("obj").should_be_called()
spatial.import_containers().should_be_called()
subject.enable_editing_container(spatial, obj="obj")
class TestDisableEditingContainer:
def test_run(self, container):
container.disable_editing("obj").should_be_called()
subject.disable_editing_container(container, obj="obj")
def test_run(self, spatial):
spatial.disable_editing("obj").should_be_called()
subject.disable_editing_container(spatial, obj="obj")
class TestChangeSpatialLevel:
def test_run(self, container):
container.import_containers(parent="parent").should_be_called()
subject.change_spatial_level(container, parent="parent")
def test_run(self, spatial):
spatial.import_containers(parent="parent").should_be_called()
subject.change_spatial_level(spatial, parent="parent")
class TestRemoveContainer:
@@ -63,3 +61,36 @@ class TestRemoveContainer:
ifc.run("spatial.remove_container", product="element").should_be_called()
collector.assign("obj").should_be_called()
subject.remove_container(ifc, collector, obj="obj")
class TestCopyToContainer:
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.get_relative_object_matrix("obj", "container_obj").should_be_called().will_return("matrix")
ifc.get_object("to_container").should_be_called().will_return("to_container_obj")
spatial.duplicate_object_and_data("obj").should_be_called().will_return("new_obj")
spatial.set_relative_object_matrix("new_obj", "to_container_obj", "matrix").should_be_called()
spatial.run_root_copy_class(obj="new_obj").should_be_called()
spatial.run_spatial_assign_container(structure_obj="to_container_obj", element_obj="new_obj").should_be_called()
spatial.disable_editing("obj").should_be_called()
subject.copy_to_container(ifc, spatial, obj="obj", containers=["to_container"])
def test_using_an_absolute_matrix_if_there_is_no_from_container(self, ifc, spatial):
ifc.get_entity("obj").should_be_called().will_return("element")
spatial.get_container("element").should_be_called().will_return(None)
spatial.get_object_matrix("obj").should_be_called().will_return("matrix")
ifc.get_object("to_container").should_be_called().will_return("to_container_obj")
spatial.duplicate_object_and_data("obj").should_be_called().will_return("new_obj")
spatial.set_relative_object_matrix("new_obj", "to_container_obj", "matrix").should_be_called()
spatial.run_root_copy_class(obj="new_obj").should_be_called()
spatial.run_spatial_assign_container(structure_obj="to_container_obj", element_obj="new_obj").should_be_called()
spatial.disable_editing("obj").should_be_called()
subject.copy_to_container(ifc, spatial, obj="obj", containers=["to_container"])
@@ -20,13 +20,14 @@ import bpy
import ifcopenshell
import blenderbim.core.tool
import blenderbim.tool as tool
from blenderbim.tool.container import Container as subject
from blenderbim.tool.spatial import Spatial as subject
from test.bim.bootstrap import NewFile
from mathutils import Matrix
class TestImplementsTool(NewFile):
def test_run(self):
assert isinstance(subject(), blenderbim.core.tool.Container)
assert isinstance(subject(), blenderbim.core.tool.Spatial)
class TestCanContain(NewFile):
@@ -80,6 +81,26 @@ class TestCanContain(NewFile):
assert subject.can_contain(structure_obj, element_obj) is False
class TestDisableEditing(NewFile):
def test_run(self):
obj = bpy.data.objects.new("Object", None)
subject.enable_editing(obj)
subject.disable_editing(obj)
assert obj.BIMObjectSpatialProperties.is_editing is False
class TestDuplicateObjectAndData(NewFile):
def test_run(self):
obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh"))
new_obj = subject.duplicate_object_and_data(obj)
assert new_obj != obj
assert new_obj.data != obj.data
obj = bpy.data.objects.new("Object", None)
new_obj = subject.duplicate_object_and_data(obj)
assert new_obj != obj
assert new_obj.data is None
class TestEnableEditing(NewFile):
def test_run(self):
obj = bpy.data.objects.new("Object", None)
@@ -87,12 +108,27 @@ class TestEnableEditing(NewFile):
assert obj.BIMObjectSpatialProperties.is_editing is True
class TestDisableEditing(NewFile):
class TestGetContainer(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_container(wall) == site
class TestGetObjectMatrix(NewFile):
def test_run(self):
obj = bpy.data.objects.new("Object", None)
subject.enable_editing(obj)
subject.disable_editing(obj)
assert obj.BIMObjectSpatialProperties.is_editing is False
assert subject.get_object_matrix(obj) == obj.matrix_world
class TestGetRelativeObjectMatrix(NewFile):
def test_run(self):
obj = bpy.data.objects.new("Object", None)
relative_obj = bpy.data.objects.new("Object", None)
relative_obj.matrix_world[0][3] = 1
assert subject.get_relative_object_matrix(obj, relative_obj)[0][3] == -1
class TestImportContainers(NewFile):
@@ -133,3 +169,24 @@ class TestImportContainers(NewFile):
assert len(props.containers) == 2
assert props.containers[0].name == "Lower"
assert props.containers[1].name == "Higher"
class TestRunRootCopyClass(NewFile):
def test_nothing(self):
pass
class TestRunSpatialAssignContainer(NewFile):
def test_nothing(self):
pass
class TestSetRelativeObjectMatrix(NewFile):
def test_run(self):
obj = bpy.data.objects.new("Object", None)
relative_obj = bpy.data.objects.new("Object", None)
relative_obj.matrix_world[0][3] = 1
matrix = Matrix()
matrix[0][3] = 1
subject.set_relative_object_matrix(obj, relative_obj, matrix)
assert obj.matrix_world[0][3] == 2