Reimplement feature to reassign inherited containers if you select a child element

This reimplements @theoryshaw 's commit 9adbd4 but has a few upgrades:

 - Considers all parent / child relationships, not just aggregates
 - Puts business logic in core where it belongs and tool code in tool
 - Uses existing utils where possible like get_decomposition
 - Does not use name based collection checking which is fragile
 - Reuses tool.Collector
 - Makes container assignment handle the API's capability to do things
in bulk instead of one by one in a loop, so it's faster
 - Tests
This commit is contained in:
Dion Moult
2026-01-28 18:00:04 +11:00
parent 79fa47fc2f
commit ff35666ad9
10 changed files with 70 additions and 78 deletions
+6 -23
View File
@@ -43,9 +43,7 @@ class TestCanContain(NewFile):
structure_obj = bpy.data.objects.new("Object", None)
tool.Ifc.link(structure, structure_obj)
element = ifc.createIfcWall()
element_obj = bpy.data.objects.new("Object", None)
tool.Ifc.link(element, element_obj)
assert subject.can_contain(structure, element_obj) is True
assert subject.can_contain(structure, element) is True
def test_a_spatial_structure_element_can_contain_an_element_ifc2x3(self):
ifc = ifcopenshell.file(schema="IFC2X3")
@@ -54,9 +52,7 @@ class TestCanContain(NewFile):
structure_obj = bpy.data.objects.new("Object", None)
tool.Ifc.link(structure, structure_obj)
element = ifc.createIfcWall()
element_obj = bpy.data.objects.new("Object", None)
tool.Ifc.link(element, element_obj)
assert subject.can_contain(structure, element_obj) is True
assert subject.can_contain(structure, element) is True
def test_a_spatial_zone_element_cannot_contain_an_element(self):
ifc = ifcopenshell.file()
@@ -65,14 +61,7 @@ class TestCanContain(NewFile):
structure_obj = bpy.data.objects.new("Object", None)
tool.Ifc.link(structure, structure_obj)
element = ifc.createIfcWall()
element_obj = bpy.data.objects.new("Object", None)
tool.Ifc.link(element, element_obj)
assert subject.can_contain(structure, element_obj) is False
def test_unlinked_elements_cannot_contain_anything(self):
structure_obj = bpy.data.objects.new("Object", None)
element_obj = bpy.data.objects.new("Object", None)
assert subject.can_contain(structure_obj, element_obj) is False
assert subject.can_contain(structure, element) is False
def test_a_non_spatial_element_cannot_contain_anything(self):
ifc = ifcopenshell.file()
@@ -81,9 +70,7 @@ class TestCanContain(NewFile):
structure_obj = bpy.data.objects.new("Object", None)
tool.Ifc.link(structure, structure_obj)
element = ifc.createIfcWall()
element_obj = bpy.data.objects.new("Object", None)
tool.Ifc.link(element, element_obj)
assert subject.can_contain(structure, element_obj) is False
assert subject.can_contain(structure, element) is False
def test_a_non_element_cannot_be_contained(self):
ifc = ifcopenshell.file()
@@ -92,9 +79,7 @@ class TestCanContain(NewFile):
structure_obj = bpy.data.objects.new("Object", None)
tool.Ifc.link(structure, structure_obj)
element = ifc.createIfcTask()
element_obj = bpy.data.objects.new("Object", None)
tool.Ifc.link(element, element_obj)
assert subject.can_contain(structure, element_obj) is False
assert subject.can_contain(structure, element) is False
def test_other_non_elements_that_have_a_contained_in_structure_attribute_can_be_contained(self):
ifc = ifcopenshell.file()
@@ -103,9 +88,7 @@ class TestCanContain(NewFile):
structure_obj = bpy.data.objects.new("Object", None)
tool.Ifc.link(structure, structure_obj)
element = ifc.createIfcGrid()
element_obj = bpy.data.objects.new("Object", None)
tool.Ifc.link(element, element_obj)
assert subject.can_contain(structure, element_obj) is True
assert subject.can_contain(structure, element) is True
class TestCanReference(NewFile):