mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-12 06:32:09 +00:00
Assigning aggregations now protects against various invalid aggregation combinations
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
@aggregate
|
||||
Feature: Aggregate
|
||||
Covers element and spatial aggregation
|
||||
|
||||
Scenario: Enable editing aggregate
|
||||
Given an empty IFC project
|
||||
And the object "IfcSite/My Site" is selected
|
||||
When I press "bim.enable_editing_aggregate"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Disable editing aggregate
|
||||
Given an empty IFC project
|
||||
And the object "IfcSite/My Site" is selected
|
||||
And I press "bim.enable_editing_aggregate"
|
||||
When I press "bim.disable_editing_aggregate"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Assign object
|
||||
Given an empty IFC project
|
||||
And the object "IfcSite/My Site" is selected
|
||||
And I press "bim.enable_editing_aggregate"
|
||||
And the variable "relating_object" is "tool.Ifc.get().by_type('IfcSite')[0].id()"
|
||||
And the variable "related_object" is "tool.Ifc.get().by_type('IfcBuildingStorey')[0].id()"
|
||||
When I press "bim.assign_object(relating_object={relating_object}, related_object={related_object})"
|
||||
Then the object "IfcSite/My Site" is in the collection "IfcSite/My Site"
|
||||
Then the object "IfcBuildingStorey/My Storey" is in the collection "IfcBuildingStorey/My Storey"
|
||||
Then the collection "IfcBuildingStorey/My Storey" is in the collection "IfcSite/My Site"
|
||||
|
||||
@@ -262,3 +262,8 @@ def prop_is_value(prop, value):
|
||||
@then(parsers.parse('the object "{name}" is in the collection "{collection}"'))
|
||||
def the_object_name_is_in_the_collection_collection(name, collection):
|
||||
assert collection in [c.name for c in the_object_name_exists(name).users_collection]
|
||||
|
||||
|
||||
@then(parsers.parse('the collection "{name1}" is in the collection "{name2}"'))
|
||||
def the_collection_name1_is_in_the_collection_name2(name1, name2):
|
||||
assert bpy.data.collections.get(name2).children.get(name1)
|
||||
|
||||
@@ -35,6 +35,13 @@ def blender():
|
||||
prophet.verify()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def aggregator():
|
||||
prophet = Prophecy(blenderbim.core.tool.Aggregator)
|
||||
yield prophet
|
||||
prophet.verify()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def person_editor():
|
||||
prophet = Prophecy(blenderbim.core.tool.PersonEditor)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import blenderbim.core.aggregate as subject
|
||||
from test.core.bootstrap import ifc, aggregator, collector
|
||||
|
||||
|
||||
class TestEnableEditingAggregate:
|
||||
def test_run(self, aggregator):
|
||||
aggregator.enable_editing("obj").should_be_called()
|
||||
subject.enable_editing_aggregate(aggregator, obj="obj")
|
||||
|
||||
|
||||
class TestDisableEditingAggregate:
|
||||
def test_run(self, aggregator):
|
||||
aggregator.disable_editing("obj").should_be_called()
|
||||
subject.disable_editing_aggregate(aggregator, obj="obj")
|
||||
|
||||
|
||||
class TestAssignObject:
|
||||
def test_run(self, ifc, aggregator, collector):
|
||||
aggregator.can_aggregate("relating_obj", "related_obj").should_be_called().will_return(True)
|
||||
ifc.get_entity("relating_obj").should_be_called().will_return("relating_object")
|
||||
ifc.get_entity("related_obj").should_be_called().will_return("related_object")
|
||||
ifc.run(
|
||||
"aggregate.assign_object", product="related_object", relating_object="relating_object"
|
||||
).should_be_called().will_return("rel")
|
||||
aggregator.disable_editing("related_obj").should_be_called()
|
||||
collector.assign("relating_obj").should_be_called()
|
||||
collector.assign("related_obj").should_be_called()
|
||||
assert (
|
||||
subject.assign_object(ifc, aggregator, collector, relating_obj="relating_obj", related_obj="related_obj")
|
||||
== "rel"
|
||||
)
|
||||
@@ -0,0 +1,101 @@
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import blenderbim.core.tool
|
||||
import blenderbim.tool as tool
|
||||
from test.bim.bootstrap import NewFile
|
||||
from blenderbim.tool.aggregator import Aggregator as subject
|
||||
|
||||
|
||||
class TestImplementsTool(NewFile):
|
||||
def test_run(self):
|
||||
assert isinstance(subject(), blenderbim.core.tool.Aggregator)
|
||||
|
||||
|
||||
class TestEnableEditing(NewFile):
|
||||
def test_run(self):
|
||||
obj = bpy.data.objects.new("Object", None)
|
||||
subject.enable_editing(obj)
|
||||
assert obj.BIMObjectAggregateProperties.is_editing is True
|
||||
|
||||
|
||||
class TestDisableEditing(NewFile):
|
||||
def test_run(self):
|
||||
obj = bpy.data.objects.new("Object", None)
|
||||
subject.enable_editing(obj)
|
||||
subject.disable_editing(obj)
|
||||
assert obj.BIMObjectAggregateProperties.is_editing is False
|
||||
|
||||
|
||||
class TestCanAggregate(NewFile):
|
||||
def test_elements_can_aggregate(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc.set(ifc)
|
||||
element = ifc.createIfcElementAssembly()
|
||||
element_obj = bpy.data.objects.new("Object", None)
|
||||
tool.Ifc.link(element, element_obj)
|
||||
subelement = ifc.createIfcBeam()
|
||||
subelement_obj = bpy.data.objects.new("Object", None)
|
||||
tool.Ifc.link(subelement, subelement_obj)
|
||||
assert subject.can_aggregate(element_obj, subelement_obj) is True
|
||||
|
||||
def test_spatial_elements_can_aggregate(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc.set(ifc)
|
||||
element = ifc.createIfcSite()
|
||||
element_obj = bpy.data.objects.new("Object", None)
|
||||
tool.Ifc.link(element, element_obj)
|
||||
subelement = ifc.createIfcBuilding()
|
||||
subelement_obj = bpy.data.objects.new("Object", None)
|
||||
tool.Ifc.link(subelement, subelement_obj)
|
||||
assert subject.can_aggregate(element_obj, subelement_obj) is True
|
||||
|
||||
def test_spatial_elements_can_aggregate_2x3(self):
|
||||
ifc = ifcopenshell.file(schema="IFC2X3")
|
||||
tool.Ifc.set(ifc)
|
||||
element = ifc.createIfcSite()
|
||||
element_obj = bpy.data.objects.new("Object", None)
|
||||
tool.Ifc.link(element, element_obj)
|
||||
subelement = ifc.createIfcBuilding()
|
||||
subelement_obj = bpy.data.objects.new("Object", None)
|
||||
tool.Ifc.link(subelement, subelement_obj)
|
||||
assert subject.can_aggregate(element_obj, subelement_obj) is True
|
||||
|
||||
def test_spatial_elements_and_projects_can_aggregate(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc.set(ifc)
|
||||
element = ifc.createIfcProject()
|
||||
element_obj = bpy.data.objects.new("Object", None)
|
||||
tool.Ifc.link(element, element_obj)
|
||||
subelement = ifc.createIfcBuilding()
|
||||
subelement_obj = bpy.data.objects.new("Object", None)
|
||||
tool.Ifc.link(subelement, subelement_obj)
|
||||
assert subject.can_aggregate(element_obj, subelement_obj) is True
|
||||
|
||||
def test_spatial_elements_and_projects_can_aggregate_2x3(self):
|
||||
ifc = ifcopenshell.file(schema="IFC2X3")
|
||||
tool.Ifc.set(ifc)
|
||||
element = ifc.createIfcProject()
|
||||
element_obj = bpy.data.objects.new("Object", None)
|
||||
tool.Ifc.link(element, element_obj)
|
||||
subelement = ifc.createIfcBuilding()
|
||||
subelement_obj = bpy.data.objects.new("Object", None)
|
||||
tool.Ifc.link(subelement, subelement_obj)
|
||||
assert subject.can_aggregate(element_obj, subelement_obj) is True
|
||||
|
||||
def test_unlinked_elements_cannot_aggregate(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc.set(ifc)
|
||||
element_obj = bpy.data.objects.new("Object", None)
|
||||
subelement_obj = bpy.data.objects.new("Object", None)
|
||||
assert subject.can_aggregate(element_obj, subelement_obj) is False
|
||||
|
||||
def test_aggregates_with_meshes_are_invalid(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc.set(ifc)
|
||||
element = ifc.createIfcElementAssembly()
|
||||
element_obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh"))
|
||||
tool.Ifc.link(element, element_obj)
|
||||
subelement = ifc.createIfcBeam()
|
||||
subelement_obj = bpy.data.objects.new("Object", None)
|
||||
tool.Ifc.link(subelement, subelement_obj)
|
||||
assert subject.can_aggregate(element_obj, subelement_obj) is False
|
||||
@@ -55,3 +55,47 @@ class TestAssign(NewFile):
|
||||
subject.assign(wall_obj)
|
||||
assert len(wall_obj.users_collection) == 1
|
||||
assert "IfcProject" in wall_obj.users_collection[0].name
|
||||
|
||||
def test_in_decomposition_mode_spatial_elements_are_placed_in_a_collection_of_the_same_name(self):
|
||||
bpy.ops.bim.create_project()
|
||||
space_obj = bpy.data.objects.new("IfcSpace/Name", None)
|
||||
space_element = tool.Ifc.get().createIfcSpace()
|
||||
tool.Ifc.link(space_element, space_obj)
|
||||
bpy.context.scene.collection.objects.link(space_obj)
|
||||
ifcopenshell.api.run(
|
||||
"aggregate.assign_object",
|
||||
tool.Ifc.get(),
|
||||
relating_object=tool.Ifc.get().by_type("IfcSite")[0],
|
||||
product=space_element,
|
||||
)
|
||||
subject.assign(space_obj)
|
||||
assert len(space_obj.users_collection) == 1
|
||||
assert space_obj.users_collection[0].name == space_obj.name
|
||||
|
||||
def test_in_decomposition_mode_aggregates_are_placed_in_a_collection_of_the_same_name(self):
|
||||
bpy.ops.bim.create_project()
|
||||
element_obj = bpy.data.objects.new("IfcElementAssembly/Name", None)
|
||||
element = tool.Ifc.get().createIfcElementAssembly()
|
||||
subelement_obj = bpy.data.objects.new("IfcBeam/Name", None)
|
||||
subelement = tool.Ifc.get().createIfcBeam()
|
||||
tool.Ifc.link(element, element_obj)
|
||||
bpy.context.scene.collection.objects.link(element_obj)
|
||||
ifcopenshell.api.run(
|
||||
"aggregate.assign_object",
|
||||
tool.Ifc.get(),
|
||||
relating_object=element,
|
||||
product=subelement,
|
||||
)
|
||||
subject.assign(element_obj)
|
||||
assert len(element_obj.users_collection) == 1
|
||||
assert element_obj.users_collection[0].name == element_obj.name
|
||||
|
||||
def test_in_decomposition_mode_projects_are_placed_in_a_collection_of_the_same_name(self):
|
||||
tool.Ifc.set(ifcopenshell.file())
|
||||
element_obj = bpy.data.objects.new("IfcProject/Name", None)
|
||||
element = tool.Ifc.get().createIfcProject()
|
||||
tool.Ifc.link(element, element_obj)
|
||||
bpy.context.scene.collection.objects.link(element_obj)
|
||||
subject.assign(element_obj)
|
||||
assert len(element_obj.users_collection) == 1
|
||||
assert element_obj.users_collection[0].name == element_obj.name
|
||||
|
||||
Reference in New Issue
Block a user