mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-16 13:46:54 +00:00
nest.assign_object - support batching #4474
This commit is contained in:
@@ -29,7 +29,9 @@ def assign_object(ifc, nest, collector, relating_obj=None, related_obj=None):
|
|||||||
if not nest.can_nest(relating_obj, related_obj):
|
if not nest.can_nest(relating_obj, related_obj):
|
||||||
return
|
return
|
||||||
rel = ifc.run(
|
rel = ifc.run(
|
||||||
"nest.assign_object", related_object=ifc.get_entity(related_obj), relating_object=ifc.get_entity(relating_obj)
|
"nest.assign_object",
|
||||||
|
related_objects=[ifc.get_entity(related_obj)],
|
||||||
|
relating_object=ifc.get_entity(relating_obj),
|
||||||
)
|
)
|
||||||
collector.assign(relating_obj)
|
collector.assign(relating_obj)
|
||||||
collector.assign(related_obj)
|
collector.assign(related_obj)
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class TestAssignObject:
|
|||||||
ifc.get_entity("relating_obj").should_be_called().will_return("relating_object")
|
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.get_entity("related_obj").should_be_called().will_return("related_object")
|
||||||
ifc.run(
|
ifc.run(
|
||||||
"nest.assign_object", related_object="related_object", relating_object="relating_object"
|
"nest.assign_object", related_objects=["related_object"], relating_object="relating_object"
|
||||||
).should_be_called().will_return("rel")
|
).should_be_called().will_return("rel")
|
||||||
nest.disable_editing("related_obj").should_be_called()
|
nest.disable_editing("related_obj").should_be_called()
|
||||||
collector.assign("relating_obj").should_be_called()
|
collector.assign("relating_obj").should_be_called()
|
||||||
|
|||||||
@@ -67,11 +67,15 @@ ARGUMENTS_DEPRECATION = {
|
|||||||
new_argument="products",
|
new_argument="products",
|
||||||
replace_usecase="spatial.unassign_container",
|
replace_usecase="spatial.unassign_container",
|
||||||
),
|
),
|
||||||
|
"nest.assign_object": partial(
|
||||||
|
batching_argument_deprecation, prev_argument="related_object", new_argument="related_objects"
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CACHED_USECASE_CLASSES = dict()
|
CACHED_USECASE_CLASSES = dict()
|
||||||
|
|
||||||
|
|
||||||
def run(
|
def run(
|
||||||
usecase_path: str,
|
usecase_path: str,
|
||||||
ifc_file: Optional[ifcopenshell.file] = None,
|
ifc_file: Optional[ifcopenshell.file] = None,
|
||||||
|
|||||||
@@ -68,6 +68,6 @@ class Usecase:
|
|||||||
)
|
)
|
||||||
elif self.settings["cost_item"]:
|
elif self.settings["cost_item"]:
|
||||||
ifcopenshell.api.run(
|
ifcopenshell.api.run(
|
||||||
"nest.assign_object", self.file, related_object=cost_item, relating_object=self.settings["cost_item"]
|
"nest.assign_object", self.file, related_objects=[cost_item], relating_object=self.settings["cost_item"]
|
||||||
)
|
)
|
||||||
return cost_item
|
return cost_item
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class Usecase:
|
|||||||
rel = ifcopenshell.api.run(
|
rel = ifcopenshell.api.run(
|
||||||
"nest.assign_object",
|
"nest.assign_object",
|
||||||
self.file,
|
self.file,
|
||||||
related_object=cost_item,
|
related_objects=[cost_item],
|
||||||
relating_object=to_element,
|
relating_object=to_element,
|
||||||
)
|
)
|
||||||
# elif inverse.is_a("IfcRelAssignsToProduct"):
|
# elif inverse.is_a("IfcRelAssignsToProduct"):
|
||||||
@@ -104,4 +104,4 @@ class Usecase:
|
|||||||
elif isinstance(value, (tuple, list)) and from_element in value:
|
elif isinstance(value, (tuple, list)) and from_element in value:
|
||||||
new_value = list(value)
|
new_value = list(value)
|
||||||
new_value.append(to_element)
|
new_value.append(to_element)
|
||||||
inverse[i] = new_value
|
inverse[i] = new_value
|
||||||
|
|||||||
@@ -19,11 +19,17 @@
|
|||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.api
|
import ifcopenshell.api
|
||||||
import ifcopenshell.util.element
|
import ifcopenshell.util.element
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, related_object=None, relating_object=None):
|
def __init__(
|
||||||
"""Assigns an object as a nested child to a parent host
|
self,
|
||||||
|
file: ifcopenshell.file,
|
||||||
|
related_objects: list[ifcopenshell.entity_instance],
|
||||||
|
relating_object: ifcopenshell.entity_instance,
|
||||||
|
):
|
||||||
|
"""Assigns objects as nested children to a parent host
|
||||||
|
|
||||||
All physical IFC model elements must be part of a hierarchical tree
|
All physical IFC model elements must be part of a hierarchical tree
|
||||||
called the "spatial decomposition", where large things are made up of
|
called the "spatial decomposition", where large things are made up of
|
||||||
@@ -72,14 +78,15 @@ class Usecase:
|
|||||||
ifcopenshell.api.cost.add_cost_item or
|
ifcopenshell.api.cost.add_cost_item or
|
||||||
ifcopenshell.api.sequence.add_task.
|
ifcopenshell.api.sequence.add_task.
|
||||||
|
|
||||||
:param related_object: The child of the nesting relationship, typically
|
:param related_objects: The list of children of the nesting relationship,
|
||||||
an IfcElement.
|
typically IfcElements.
|
||||||
:type related_object: ifcopenshell.entity_instance.entity_instance
|
:type related_objects: list[ifcopenshell.entity_instance.entity_instance]
|
||||||
:param relating_object: The host parent of the nesting relationship,
|
:param relating_object: The host parent of the nesting relationship,
|
||||||
typically an IfcElement.
|
typically an IfcElement.
|
||||||
:type relating_object: ifcopenshell.entity_instance.entity_instance
|
:type relating_object: ifcopenshell.entity_instance.entity_instance
|
||||||
:return: The IfcRelNests relationship instance
|
:return: The IfcRelNests relationship instance
|
||||||
:rtype: ifcopenshell.entity_instance.entity_instance
|
or `None` if `related_objects` was empty list.
|
||||||
|
:rtype: Union[ifcopenshell.entity_instance.entity_instance, None]
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -90,30 +97,50 @@ class Usecase:
|
|||||||
ifc_class="IfcSanitaryTerminal", predefined_type="SINK")
|
ifc_class="IfcSanitaryTerminal", predefined_type="SINK")
|
||||||
faucet = ifcopenshell.api.run("root.create_entity", model,
|
faucet = ifcopenshell.api.run("root.create_entity", model,
|
||||||
ifc_class="IfcValve", predefined_type="FAUCET")
|
ifc_class="IfcValve", predefined_type="FAUCET")
|
||||||
ifcopenshell.api.run("nest.assign_object", model, related_object=faucet, relating_object=sink)
|
ifcopenshell.api.run("nest.assign_object", model, related_objects=[faucet], relating_object=sink)
|
||||||
"""
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"related_object": related_object, "relating_object": relating_object}
|
self.settings = {"related_objects": related_objects, "relating_object": relating_object}
|
||||||
|
|
||||||
def execute(self):
|
def execute(self) -> Union[ifcopenshell.entity_instance, None]:
|
||||||
nests = None
|
if not self.settings["related_objects"]:
|
||||||
if self.settings["related_object"].Nests:
|
|
||||||
nests = self.settings["related_object"].Nests[0]
|
|
||||||
|
|
||||||
is_nested_by = None
|
|
||||||
for rel in self.settings["relating_object"].IsNestedBy:
|
|
||||||
if rel.is_a("IfcRelNests"):
|
|
||||||
is_nested_by = rel
|
|
||||||
break
|
|
||||||
|
|
||||||
if nests and nests == is_nested_by:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if nests:
|
related_objects = set(self.settings["related_objects"])
|
||||||
related_objects = list(nests.RelatedObjects)
|
relating_object = self.settings["relating_object"]
|
||||||
related_objects.remove(self.settings["related_object"])
|
is_nested_by = next((i for i in relating_object.IsNestedBy), None)
|
||||||
|
|
||||||
|
previous_nests_rels: set[ifcopenshell.entity_instance] = set()
|
||||||
|
objects_without_nests: list[ifcopenshell.entity_instance] = []
|
||||||
|
objects_with_nests: list[ifcopenshell.entity_instance] = []
|
||||||
|
|
||||||
|
# check if there is anything to change
|
||||||
|
for object in related_objects:
|
||||||
|
object_rel = next(iter(object.Nests), None)
|
||||||
|
|
||||||
|
if object_rel is None:
|
||||||
|
objects_without_nests.append(object)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# either is_nested_by is None or product is part of different rel
|
||||||
|
if object_rel != is_nested_by:
|
||||||
|
previous_nests_rels.add(object_rel)
|
||||||
|
objects_with_nests.append(object)
|
||||||
|
|
||||||
|
# products with already assigned nestings will be skipped
|
||||||
|
|
||||||
|
objects_to_change = objects_without_nests + objects_with_nests
|
||||||
|
# nothing to change
|
||||||
|
if not objects_to_change:
|
||||||
|
return is_nested_by
|
||||||
|
|
||||||
|
# NOTE: An object can both be nested and assigned to a container or aggregate.
|
||||||
|
|
||||||
|
# unassign elements from previous nests
|
||||||
|
for nests in previous_nests_rels:
|
||||||
|
related_objects = set(nests.RelatedObjects) - related_objects
|
||||||
if related_objects:
|
if related_objects:
|
||||||
nests.RelatedObjects = related_objects
|
nests.RelatedObjects = list(related_objects)
|
||||||
ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": nests})
|
ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": nests})
|
||||||
else:
|
else:
|
||||||
history = nests.OwnerHistory
|
history = nests.OwnerHistory
|
||||||
@@ -121,10 +148,9 @@ class Usecase:
|
|||||||
if history:
|
if history:
|
||||||
ifcopenshell.util.element.remove_deep2(self.file, history)
|
ifcopenshell.util.element.remove_deep2(self.file, history)
|
||||||
|
|
||||||
|
# assign elements to a new nesting
|
||||||
if is_nested_by:
|
if is_nested_by:
|
||||||
related_objects = list(is_nested_by.RelatedObjects)
|
is_nested_by.RelatedObjects = list(set(is_nested_by.RelatedObjects) | related_objects)
|
||||||
related_objects.append(self.settings["related_object"])
|
|
||||||
is_nested_by.RelatedObjects = related_objects
|
|
||||||
ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": is_nested_by})
|
ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": is_nested_by})
|
||||||
else:
|
else:
|
||||||
is_nested_by = self.file.create_entity(
|
is_nested_by = self.file.create_entity(
|
||||||
@@ -132,8 +158,12 @@ class Usecase:
|
|||||||
**{
|
**{
|
||||||
"GlobalId": ifcopenshell.guid.new(),
|
"GlobalId": ifcopenshell.guid.new(),
|
||||||
"OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", self.file),
|
"OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", self.file),
|
||||||
"RelatedObjects": [self.settings["related_object"]],
|
"RelatedObjects": list(related_objects),
|
||||||
"RelatingObject": self.settings["relating_object"],
|
"RelatingObject": relating_object,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# NOTE: Creating a nesting relationship doesn't localize the object's placement,
|
||||||
|
# unlike assigning it to an aggregate or a container.
|
||||||
|
|
||||||
return is_nested_by
|
return is_nested_by
|
||||||
|
|||||||
@@ -44,6 +44,6 @@ class Usecase:
|
|||||||
ifcopenshell.api.run(
|
ifcopenshell.api.run(
|
||||||
"nest.assign_object",
|
"nest.assign_object",
|
||||||
self.file,
|
self.file,
|
||||||
related_object=self.settings["item"],
|
related_objects=[self.settings["item"]],
|
||||||
relating_object=self.settings["new_parent"],
|
relating_object=self.settings["new_parent"],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ class Usecase:
|
|||||||
task = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcSite")
|
task = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcSite")
|
||||||
subtask1 = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcBuilding")
|
subtask1 = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcBuilding")
|
||||||
subtask2 = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcBuilding")
|
subtask2 = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcBuilding")
|
||||||
ifcopenshell.api.run("nest.assign_object", model, related_object=subtask1, relating_object=task)
|
ifcopenshell.api.run("nest.assign_object", model, related_objects=[subtask1], relating_object=task)
|
||||||
ifcopenshell.api.run("nest.assign_object", model, related_object=subtask2, relating_object=task)
|
ifcopenshell.api.run("nest.assign_object", model, related_objects=[subtask2], relating_object=task)
|
||||||
# The relationship is returned as task still has subtask2
|
# The relationship is returned as task still has subtask2
|
||||||
rel = ifcopenshell.api.run("nest.unassign_object", model, related_object=subtask1)
|
rel = ifcopenshell.api.run("nest.unassign_object", model, related_object=subtask1)
|
||||||
# Nothing is returned, as the relationship has no related objects
|
# Nothing is returned, as the relationship has no related objects
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ class Usecase:
|
|||||||
ifcopenshell.api.run(
|
ifcopenshell.api.run(
|
||||||
"nest.assign_object",
|
"nest.assign_object",
|
||||||
self.file,
|
self.file,
|
||||||
related_object=resource,
|
related_objects=[resource],
|
||||||
relating_object=self.settings["parent_resource"],
|
relating_object=self.settings["parent_resource"],
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ class Usecase:
|
|||||||
rel = ifcopenshell.api.run(
|
rel = ifcopenshell.api.run(
|
||||||
"nest.assign_object",
|
"nest.assign_object",
|
||||||
self.file,
|
self.file,
|
||||||
related_object=task,
|
related_objects=[task],
|
||||||
relating_object=self.settings["parent_task"],
|
relating_object=self.settings["parent_task"],
|
||||||
)
|
)
|
||||||
if self.settings["parent_task"].Identification:
|
if self.settings["parent_task"].Identification:
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# IfcOpenShell - IFC toolkit and geometry engine
|
||||||
|
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||||
|
#
|
||||||
|
# This file is part of IfcOpenShell.
|
||||||
|
#
|
||||||
|
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
# IfcOpenShell - IFC toolkit and geometry engine
|
||||||
|
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||||
|
#
|
||||||
|
# This file is part of IfcOpenShell.
|
||||||
|
#
|
||||||
|
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import test.bootstrap
|
||||||
|
import ifcopenshell.api
|
||||||
|
import ifcopenshell.util.element
|
||||||
|
import ifcopenshell.util.placement
|
||||||
|
|
||||||
|
|
||||||
|
class TestAssignObject(test.bootstrap.IFC4):
|
||||||
|
def test_assigning_a_nesting(self):
|
||||||
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSanitaryTerminal")
|
||||||
|
subelement1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcValve")
|
||||||
|
subelement2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcValve")
|
||||||
|
rel = ifcopenshell.api.run(
|
||||||
|
"nest.assign_object", self.file, related_objects=[subelement1, subelement2], relating_object=element
|
||||||
|
)
|
||||||
|
assert ifcopenshell.util.element.get_nest(subelement1) == element
|
||||||
|
assert ifcopenshell.util.element.get_nest(subelement2) == element
|
||||||
|
assert rel.is_a("IfcRelNests")
|
||||||
|
|
||||||
|
def test_doing_nothing_if_the_nesting_is_already_assigned(self):
|
||||||
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSanitaryTerminal")
|
||||||
|
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcValve")
|
||||||
|
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement], relating_object=element)
|
||||||
|
total_elements = len([e for e in self.file])
|
||||||
|
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement], relating_object=element)
|
||||||
|
assert len([e for e in self.file]) == total_elements
|
||||||
|
|
||||||
|
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")
|
||||||
|
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSanitaryTerminal")
|
||||||
|
subelement1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcValve")
|
||||||
|
subelement2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcValve")
|
||||||
|
ifcopenshell.api.run(
|
||||||
|
"nest.assign_object", self.file, related_objects=[subelement1, subelement2], relating_object=element1
|
||||||
|
)
|
||||||
|
rel = subelement1.Nests[0]
|
||||||
|
assert len(rel.RelatedObjects) == 2
|
||||||
|
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement1], relating_object=element2)
|
||||||
|
assert len(rel.RelatedObjects) == 1
|
||||||
|
|
||||||
|
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")
|
||||||
|
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSanitaryTerminal")
|
||||||
|
subelement1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcValve")
|
||||||
|
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement1], relating_object=element1)
|
||||||
|
rel_id = subelement1.Nests[0].id()
|
||||||
|
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement1], relating_object=element2)
|
||||||
|
with pytest.raises(RuntimeError):
|
||||||
|
self.file.by_id(rel_id)
|
||||||
@@ -190,7 +190,7 @@ class TestRemoveProduct(test.bootstrap.IFC4):
|
|||||||
def test_removing_all_nesting_relationships_of_a_whole(self):
|
def test_removing_all_nesting_relationships_of_a_whole(self):
|
||||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||||
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBeam")
|
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBeam")
|
||||||
ifcopenshell.api.run("nest.assign_object", self.file, related_object=subelement, relating_object=element)
|
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement], relating_object=element)
|
||||||
total_entities = len(list(self.file))
|
total_entities = len(list(self.file))
|
||||||
ifcopenshell.api.run("root.remove_product", self.file, product=element)
|
ifcopenshell.api.run("root.remove_product", self.file, product=element)
|
||||||
assert len(list(self.file)) == total_entities - 2
|
assert len(list(self.file)) == total_entities - 2
|
||||||
@@ -201,7 +201,7 @@ class TestRemoveProduct(test.bootstrap.IFC4):
|
|||||||
def test_removing_all_nesting_relationships_of_a_part(self):
|
def test_removing_all_nesting_relationships_of_a_part(self):
|
||||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||||
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBeam")
|
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBeam")
|
||||||
ifcopenshell.api.run("nest.assign_object", self.file, related_object=subelement, relating_object=element)
|
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement], relating_object=element)
|
||||||
total_entities = len(list(self.file))
|
total_entities = len(list(self.file))
|
||||||
ifcopenshell.api.run("root.remove_product", self.file, product=subelement)
|
ifcopenshell.api.run("root.remove_product", self.file, product=subelement)
|
||||||
assert len(list(self.file)) == total_entities - 2
|
assert len(list(self.file)) == total_entities - 2
|
||||||
|
|||||||
@@ -107,3 +107,11 @@ class TestTemporarySupportForDeprecatedAPIArguments(test.bootstrap.IFC4):
|
|||||||
ifcopenshell.api.run("spatial.assign_container", self.file, products=[subelement], relating_structure=element)
|
ifcopenshell.api.run("spatial.assign_container", self.file, products=[subelement], relating_structure=element)
|
||||||
ifcopenshell.api.run("spatial.remove_container", self.file, product=subelement)
|
ifcopenshell.api.run("spatial.remove_container", self.file, product=subelement)
|
||||||
assert ifcopenshell.util.element.get_container(subelement) is None
|
assert ifcopenshell.util.element.get_container(subelement) is None
|
||||||
|
|
||||||
|
@deprecation_check
|
||||||
|
def test_assigning_a_nesting(self):
|
||||||
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSanitaryTerminal")
|
||||||
|
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcValve")
|
||||||
|
rel = ifcopenshell.api.run("nest.assign_object", self.file, related_object=subelement, relating_object=element)
|
||||||
|
assert ifcopenshell.util.element.get_nest(subelement) == element
|
||||||
|
assert rel.is_a("IfcRelNests")
|
||||||
|
|||||||
@@ -1526,7 +1526,7 @@ class TestPartOf:
|
|||||||
ifc = ifcopenshell.file()
|
ifc = ifcopenshell.file()
|
||||||
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcFurniture")
|
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcFurniture")
|
||||||
subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcDiscreteAccessory")
|
subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcDiscreteAccessory")
|
||||||
ifcopenshell.api.run("nest.assign_object", ifc, related_object=subelement, relating_object=element)
|
ifcopenshell.api.run("nest.assign_object", ifc, related_objects=[subelement], relating_object=element)
|
||||||
facet = PartOf(name="IFCFURNITURE", relation="IFCRELNESTS")
|
facet = PartOf(name="IFCFURNITURE", relation="IFCRELNESTS")
|
||||||
run("Any nested part passes a nest relationship", facet=facet, inst=subelement, expected=True)
|
run("Any nested part passes a nest relationship", facet=facet, inst=subelement, expected=True)
|
||||||
run("Any nested whole fails a nest relationship", facet=facet, inst=element, expected=False)
|
run("Any nested whole fails a nest relationship", facet=facet, inst=element, expected=False)
|
||||||
@@ -1534,7 +1534,7 @@ class TestPartOf:
|
|||||||
ifc = ifcopenshell.file()
|
ifc = ifcopenshell.file()
|
||||||
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcFurniture")
|
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcFurniture")
|
||||||
subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcDiscreteAccessory")
|
subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcDiscreteAccessory")
|
||||||
ifcopenshell.api.run("nest.assign_object", ifc, related_object=subelement, relating_object=element)
|
ifcopenshell.api.run("nest.assign_object", ifc, related_objects=[subelement], relating_object=element)
|
||||||
facet = PartOf(relation="IFCRELNESTS", name="IFCBEAM")
|
facet = PartOf(relation="IFCRELNESTS", name="IFCBEAM")
|
||||||
run("The nest entity must match exactly 1/2", facet=facet, inst=subelement, expected=False)
|
run("The nest entity must match exactly 1/2", facet=facet, inst=subelement, expected=False)
|
||||||
facet = PartOf(relation="IFCRELNESTS", name="IFCFURNITURE")
|
facet = PartOf(relation="IFCRELNESTS", name="IFCFURNITURE")
|
||||||
@@ -1551,8 +1551,8 @@ class TestPartOf:
|
|||||||
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcFurniture")
|
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcFurniture")
|
||||||
subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcDiscreteAccessory")
|
subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcDiscreteAccessory")
|
||||||
subsubelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcMechanicalFastener")
|
subsubelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcMechanicalFastener")
|
||||||
ifcopenshell.api.run("nest.assign_object", ifc, related_object=subelement, relating_object=element)
|
ifcopenshell.api.run("nest.assign_object", ifc, related_objects=[subelement], relating_object=element)
|
||||||
ifcopenshell.api.run("nest.assign_object", ifc, related_object=subsubelement, relating_object=subelement)
|
ifcopenshell.api.run("nest.assign_object", ifc, related_objects=[subsubelement], relating_object=subelement)
|
||||||
facet = PartOf(relation="IFCRELNESTS", name="IFCFURNITURE")
|
facet = PartOf(relation="IFCRELNESTS", name="IFCFURNITURE")
|
||||||
run("Nesting may be indirect", facet=facet, inst=subsubelement, expected=True)
|
run("Nesting may be indirect", facet=facet, inst=subsubelement, expected=True)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user