mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 06:58:56 +00:00
nest.assign_object to support ifc2x3
This commit is contained in:
@@ -106,9 +106,14 @@ class Usecase:
|
|||||||
if not self.settings["related_objects"]:
|
if not self.settings["related_objects"]:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
ifc2x3 = self.file.schema == "IFC2X3"
|
||||||
|
|
||||||
related_objects = set(self.settings["related_objects"])
|
related_objects = set(self.settings["related_objects"])
|
||||||
relating_object = self.settings["relating_object"]
|
relating_object = self.settings["relating_object"]
|
||||||
is_nested_by = next((i for i in relating_object.IsNestedBy), None)
|
if ifc2x3:
|
||||||
|
is_nested_by = next((i for i in relating_object.IsDecomposedBy if i.is_a("IfcRelNests")), None)
|
||||||
|
else:
|
||||||
|
is_nested_by = next((i for i in relating_object.IsNestedBy), None)
|
||||||
|
|
||||||
previous_nests_rels: set[ifcopenshell.entity_instance] = set()
|
previous_nests_rels: set[ifcopenshell.entity_instance] = set()
|
||||||
objects_without_nests: list[ifcopenshell.entity_instance] = []
|
objects_without_nests: list[ifcopenshell.entity_instance] = []
|
||||||
@@ -116,7 +121,10 @@ class Usecase:
|
|||||||
|
|
||||||
# check if there is anything to change
|
# check if there is anything to change
|
||||||
for object in related_objects:
|
for object in related_objects:
|
||||||
object_rel = next(iter(object.Nests), None)
|
if ifc2x3:
|
||||||
|
object_rel = next((i for i in object.Decomposes if i.is_a("IfcRelNests")), None)
|
||||||
|
else:
|
||||||
|
object_rel = next(iter(object.Nests), None)
|
||||||
|
|
||||||
if object_rel is None:
|
if object_rel is None:
|
||||||
objects_without_nests.append(object)
|
objects_without_nests.append(object)
|
||||||
@@ -134,7 +142,7 @@ class Usecase:
|
|||||||
if not objects_to_change:
|
if not objects_to_change:
|
||||||
return is_nested_by
|
return is_nested_by
|
||||||
|
|
||||||
# NOTE: An object can both be nested and assigned to a container or aggregate.
|
# NOTE: An object can both be nested and assigned to a container or an aggregate.
|
||||||
|
|
||||||
# unassign elements from previous nests
|
# unassign elements from previous nests
|
||||||
for nests in previous_nests_rels:
|
for nests in previous_nests_rels:
|
||||||
|
|||||||
@@ -55,7 +55,15 @@ class Usecase:
|
|||||||
|
|
||||||
def execute(self) -> None:
|
def execute(self) -> None:
|
||||||
related_objects = set(self.settings["related_objects"])
|
related_objects = set(self.settings["related_objects"])
|
||||||
rels = set(rel for object in related_objects if (rel := next((rel for rel in object.Nests), None)))
|
ifc2x3 = self.file.schema == "IFC2X3"
|
||||||
|
if ifc2x3:
|
||||||
|
rels = set(
|
||||||
|
rel
|
||||||
|
for object in related_objects
|
||||||
|
if (rel := next((rel for rel in object.Decomposes if rel.is_a("IfcRelNests")), None))
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
rels = set(rel for object in related_objects if (rel := next((rel for rel in object.Nests), None)))
|
||||||
|
|
||||||
for rel in rels:
|
for rel in rels:
|
||||||
related_objects = set(rel.RelatedObjects) - related_objects
|
related_objects = set(rel.RelatedObjects) - related_objects
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ import ifcopenshell.util.placement
|
|||||||
|
|
||||||
class TestAssignObject(test.bootstrap.IFC4):
|
class TestAssignObject(test.bootstrap.IFC4):
|
||||||
def test_assigning_a_nesting(self):
|
def test_assigning_a_nesting(self):
|
||||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSanitaryTerminal")
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcTask")
|
||||||
subelement1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcValve")
|
subelement1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcTask")
|
||||||
subelement2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcValve")
|
subelement2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcTask")
|
||||||
rel = ifcopenshell.api.run(
|
rel = ifcopenshell.api.run(
|
||||||
"nest.assign_object", self.file, related_objects=[subelement1, subelement2], relating_object=element
|
"nest.assign_object", self.file, related_objects=[subelement1, subelement2], relating_object=element
|
||||||
)
|
)
|
||||||
@@ -36,32 +36,36 @@ class TestAssignObject(test.bootstrap.IFC4):
|
|||||||
assert rel.is_a("IfcRelNests")
|
assert rel.is_a("IfcRelNests")
|
||||||
|
|
||||||
def test_doing_nothing_if_the_nesting_is_already_assigned(self):
|
def test_doing_nothing_if_the_nesting_is_already_assigned(self):
|
||||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSanitaryTerminal")
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcTask")
|
||||||
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcValve")
|
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcTask")
|
||||||
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement], relating_object=element)
|
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement], relating_object=element)
|
||||||
total_elements = len([e for e in self.file])
|
total_elements = len([e for e in self.file])
|
||||||
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement], relating_object=element)
|
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement], relating_object=element)
|
||||||
assert len([e for e in self.file]) == total_elements
|
assert len([e for e in self.file]) == total_elements
|
||||||
|
|
||||||
def test_that_old_nesting_relationships_are_updated_if_they_still_have_elements(self):
|
def test_that_old_nesting_relationships_are_updated_if_they_still_have_elements(self):
|
||||||
element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSanitaryTerminal")
|
element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcTask")
|
||||||
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSanitaryTerminal")
|
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcTask")
|
||||||
subelement1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcValve")
|
subelement1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcTask")
|
||||||
subelement2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcValve")
|
subelement2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcTask")
|
||||||
ifcopenshell.api.run(
|
ifcopenshell.api.run(
|
||||||
"nest.assign_object", self.file, related_objects=[subelement1, subelement2], relating_object=element1
|
"nest.assign_object", self.file, related_objects=[subelement1, subelement2], relating_object=element1
|
||||||
)
|
)
|
||||||
rel = subelement1.Nests[0]
|
rel = subelement1.Decomposes[0] if self.file.schema == "IFC2X3" else subelement1.Nests[0]
|
||||||
assert len(rel.RelatedObjects) == 2
|
assert len(rel.RelatedObjects) == 2
|
||||||
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement1], relating_object=element2)
|
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement1], relating_object=element2)
|
||||||
assert len(rel.RelatedObjects) == 1
|
assert len(rel.RelatedObjects) == 1
|
||||||
|
|
||||||
def test_that_old_nesting_relationships_are_purged_if_no_more_elements_are_nested(self):
|
def test_that_old_nesting_relationships_are_purged_if_no_more_elements_are_nested(self):
|
||||||
element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSanitaryTerminal")
|
element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcTask")
|
||||||
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSanitaryTerminal")
|
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcTask")
|
||||||
subelement1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcValve")
|
subelement1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcTask")
|
||||||
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement1], relating_object=element1)
|
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement1], relating_object=element1)
|
||||||
rel_id = subelement1.Nests[0].id()
|
rel_id = (subelement1.Decomposes[0] if self.file.schema == "IFC2X3" else subelement1.Nests[0]).id()
|
||||||
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement1], relating_object=element2)
|
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement1], relating_object=element2)
|
||||||
with pytest.raises(RuntimeError):
|
with pytest.raises(RuntimeError):
|
||||||
self.file.by_id(rel_id)
|
self.file.by_id(rel_id)
|
||||||
|
|
||||||
|
|
||||||
|
class TestAssignObjectIFC2X3(test.bootstrap.IFC2X3, TestAssignObject):
|
||||||
|
pass
|
||||||
|
|||||||
@@ -49,3 +49,6 @@ class TestUnassignObject(test.bootstrap.IFC4):
|
|||||||
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement], relating_object=element)
|
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement], relating_object=element)
|
||||||
ifcopenshell.api.run("nest.unassign_object", self.file, related_objects=[subelement])
|
ifcopenshell.api.run("nest.unassign_object", self.file, related_objects=[subelement])
|
||||||
assert len(self.file.by_type("IfcRelNests")) == 0
|
assert len(self.file.by_type("IfcRelNests")) == 0
|
||||||
|
|
||||||
|
class TestUnassignObjectIFC2X3(test.bootstrap.IFC2X3, TestUnassignObject):
|
||||||
|
pass
|
||||||
|
|||||||
@@ -775,6 +775,10 @@ class TestGetNestIFC4(test.bootstrap.IFC4):
|
|||||||
assert subject.get_nest(subelement) == element
|
assert subject.get_nest(subelement) == element
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetNestIFC2X3(test.bootstrap.IFC2X3, TestGetNestIFC4):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TestReplaceAttributeIFC4(test.bootstrap.IFC4):
|
class TestReplaceAttributeIFC4(test.bootstrap.IFC4):
|
||||||
def test_replacing_an_elements_attribute(self):
|
def test_replacing_an_elements_attribute(self):
|
||||||
element = self.file.createIfcWall("foo")
|
element = self.file.createIfcWall("foo")
|
||||||
|
|||||||
Reference in New Issue
Block a user