Fix critical bug where duplicate orphaned collections were created in the background.

This commit is contained in:
Dion Moult
2023-02-27 20:12:39 +11:00
parent d9b54c923c
commit b25233a748
6 changed files with 38 additions and 22 deletions
-2
View File
@@ -67,8 +67,6 @@ def assign_class(
obj=obj, context=context, ifc_representation_class=ifc_representation_class, profile_set_usage=None
)
root.set_element_specific_display_settings(obj, element)
collector.sync(obj)
collector.assign(obj)
return element
-1
View File
@@ -547,7 +547,6 @@ class Root:
def link_object_data(cls, source_obj, destination_obj): pass
def recreate_decompositions(cls, relationships, old_to_new): pass
def run_geometry_add_representation(cls, obj=None, context=None, ifc_representation_class=None, profile_set_usage=None): pass
def set_element_specific_display_settings(cls, obj, element): pass
def set_object_name(cls, obj, element): pass
+8 -8
View File
@@ -101,17 +101,17 @@ class Collector(blenderbim.core.tool.Collector):
@classmethod
def _get_own_collection(cls, element, obj):
if element.is_a("IfcProject"):
return bpy.data.collections.get(obj.name, bpy.data.collections.new(obj.name))
return bpy.data.collections.get(obj.name) or bpy.data.collections.new(obj.name)
if tool.Ifc.get_schema() == "IFC2X3":
if element.is_a("IfcSpatialStructureElement"):
return bpy.data.collections.get(obj.name, bpy.data.collections.new(obj.name))
return bpy.data.collections.get(obj.name) or bpy.data.collections.new(obj.name)
else:
if element.is_a("IfcSpatialStructureElement") or element.is_a("IfcExternalSpatialStructureElement"):
return bpy.data.collections.get(obj.name, bpy.data.collections.new(obj.name))
return bpy.data.collections.get(obj.name) or bpy.data.collections.new(obj.name)
if element.is_a("IfcGrid"):
return bpy.data.collections.get(obj.name, bpy.data.collections.new(obj.name))
return bpy.data.collections.get(obj.name) or bpy.data.collections.new(obj.name)
if element.is_a("IfcGridAxis"):
if element.PartOfU:
@@ -135,16 +135,16 @@ class Collector(blenderbim.core.tool.Collector):
for rel in element.HasAssignments or []:
if rel.is_a("IfcRelAssignsToGroup") and rel.RelatingGroup.ObjectType == "DRAWING":
name = "IfcGroup/" + rel.RelatingGroup.Name
return bpy.data.collections.get(name, bpy.data.collections.new(name))
return bpy.data.collections.get(name) or bpy.data.collections.new(name)
if element.is_a("IfcStructuralMember"):
return bpy.data.collections.get("Members", bpy.data.collections.new("Members"))
return bpy.data.collections.get("Members") or bpy.data.collections.new("Members")
if element.is_a("IfcStructuralConnection"):
return bpy.data.collections.get("Connections", bpy.data.collections.new("Connections"))
return bpy.data.collections.get("Connections") or bpy.data.collections.new("Connections")
if getattr(element, "IsDecomposedBy", None):
return bpy.data.collections.get(obj.name, bpy.data.collections.new(obj.name))
return bpy.data.collections.get(obj.name) or bpy.data.collections.new(obj.name)
@classmethod
def _get_collection(cls, element, obj):
-2
View File
@@ -116,7 +116,6 @@ class TestAssignClass:
root.run_geometry_add_representation(
obj="obj", context="context", ifc_representation_class="ifc_representation_class", profile_set_usage=None
).should_be_called()
root.set_element_specific_display_settings("obj", "element").should_be_called()
collector.sync("obj").should_be_called()
collector.assign("obj").should_be_called()
subject.assign_class(
@@ -139,7 +138,6 @@ class TestAssignClass:
).should_be_called().will_return("element")
root.set_object_name("obj", "element").should_be_called()
ifc.link("element", "obj").should_be_called()
root.set_element_specific_display_settings("obj", "element").should_be_called()
collector.sync("obj").should_be_called()
collector.assign("obj").should_be_called()
subject.assign_class(
@@ -72,6 +72,25 @@ class TestAssign(NewFile):
assert len(space_obj.users_collection) == 1
assert space_obj.users_collection[0].name == space_obj.name
def test_in_decomposition_mode_multiple_assigns_do_not_create_duplicate_spatial_structure_collections(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)
subject.assign(space_obj)
assert bpy.data.collections.get("IfcSpace/Name")
assert bpy.data.collections.get("IfcSite/My Site")
assert not bpy.data.collections.get("IfcSpace/Name.001")
assert not bpy.data.collections.get("IfcSite/My Site.001")
def test_in_decomposition_mode_spatial_zone_elements_are_not_placed_in_a_collection_of_the_same_name(self):
bpy.ops.bim.create_project()
space_obj = bpy.data.objects.new("IfcSpaceZone/Name", None)
@@ -116,6 +135,17 @@ class TestAssign(NewFile):
assert len(element_obj.users_collection) == 1
assert element_obj.users_collection[0].name == element_obj.name
def test_in_decomposition_mode_multiple_assigns_do_not_create_duplicate_collections(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)
subject.assign(element_obj)
assert bpy.data.collections.get("IfcProject/Name")
assert not bpy.data.collections.get("IfcProject/Name.001")
def test_in_decomposition_mode_existing_collections_are_reassigned_to_the_correct_place_in_the_hierarchy(self):
bpy.ops.bim.create_project()
space_obj = bpy.data.objects.new("IfcSpace/Name", None)
-9
View File
@@ -154,15 +154,6 @@ class TestRunGeometryAddRepresntation(NewFile):
pass
class TestSetElementSpecificDisplaySettings(NewFile):
def test_opening_elements_display_as_wire(self):
ifc = ifcopenshell.file()
obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh"))
element = ifc.createIfcOpeningElement()
subject.set_element_specific_display_settings(obj, element)
assert obj.display_type == "WIRE"
class TestSetObjectName(NewFile):
def test_run(self):
ifc = ifcopenshell.file()