control.unassign_control to support batching

This commit is contained in:
Andrej730
2025-09-09 14:40:42 +05:00
parent abfb56350d
commit a9c0c1f4ba
8 changed files with 32 additions and 28 deletions
@@ -19,21 +19,19 @@
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.util.element
from typing import Union
def unassign_control(
file: ifcopenshell.file,
relating_control: ifcopenshell.entity_instance,
related_object: ifcopenshell.entity_instance,
) -> Union[ifcopenshell.entity_instance, None]:
related_objects: list[ifcopenshell.entity_instance],
) -> None:
"""Unassigns a planning control or constraint to an object
:param relating_control: The IfcControl entity that is creating the
control or constraint
:param related_object: The IfcObjectDefinition that is being controlled
:return: If the control still is related to other objects, the
IfcRelAssignsToControl is returned, otherwise None.
:param related_objects: The list IfcObjectDefinitions that is being controlled
:return: None
Example:
@@ -49,19 +47,19 @@ def unassign_control(
# And now let's change our mind
ifcopenshell.api.control.unassign_control(model,
relating_control=cost_item, related_object=wall)
relating_control=cost_item, related_objects=[wall])
"""
for rel in related_object.HasAssignments or []:
if not rel.is_a("IfcRelAssignsToControl") or rel.RelatingControl != relating_control:
continue
if len(rel.RelatedObjects) == 1:
related_objects_set = set(related_objects)
control_assignments = set(relating_control.Controls)
rels = set(rel for obj in related_objects_set for rel in obj.HasAssignments if rel in control_assignments)
for rel in rels:
related_objects_new = set(rel.RelatedObjects) - related_objects_set
if related_objects_new:
rel.RelatedObjects = list(related_objects_new)
ifcopenshell.api.owner.update_owner_history(file, element=rel)
else:
history = rel.OwnerHistory
file.remove(rel)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
return
related_objects = list(rel.RelatedObjects)
related_objects.remove(related_object)
rel.RelatedObjects = related_objects
ifcopenshell.api.owner.update_owner_history(file, element=rel)
return rel
@@ -86,7 +86,7 @@ class Usecase:
for product in products:
ifcopenshell.api.control.unassign_control(
self.file,
related_object=product,
related_objects=[product],
relating_control=cost_item,
)
self.update_cost_item_count(cost_item)
@@ -54,7 +54,7 @@ def remove_work_calendar(file: ifcopenshell.file, work_calendar: ifcopenshell.en
ifcopenshell.api.control.unassign_control(
file,
relating_control=work_calendar,
related_object=related_object,
related_objects=[related_object],
)
# Currently in API work times are created already attached
@@ -29,7 +29,7 @@ class TestUnassignControl(test.bootstrap.IFC4):
# assign and unassign
relation = ifcopenshell.api.control.assign_control(self.file, relating_control=control, related_objects=[wall])
assert relation
ifcopenshell.api.control.unassign_control(self.file, relating_control=control, related_object=wall)
ifcopenshell.api.control.unassign_control(self.file, relating_control=control, related_objects=[wall])
assert len(self.file.by_type("IfcRelAssignsToControl")) == 0
# 1 control 2 related objects
@@ -37,7 +37,7 @@ class TestUnassignControl(test.bootstrap.IFC4):
relation = ifcopenshell.api.control.assign_control(self.file, relating_control=control, related_objects=[wall])
assert relation
ifcopenshell.api.control.assign_control(self.file, relating_control=control, related_objects=[wall1])
ifcopenshell.api.control.unassign_control(self.file, relating_control=control, related_object=wall1)
ifcopenshell.api.control.unassign_control(self.file, relating_control=control, related_objects=[wall1])
assert len(self.file.by_type("IfcRelAssignsToControl")) == 1
assert relation.RelatedObjects == (wall,)
@@ -43,3 +43,12 @@ class TestTemporarySupportForDeprecatedAPIArguments(test.bootstrap.IFC4):
control = ifcopenshell.api.cost.add_cost_schedule(model)
ifcopenshell.api.control.assign_control(model, relating_control=control, related_objects=[element])
assert list(ifcopenshell.util.element.get_controls(element)) == [control]
@deprecation_check
def test_unassigning_control(self):
TestTemporarySupportForDeprecatedAPIArguments.test_assigning_control(self)
model = self.file
element = model.by_type("IfcWall")[0]
control = model.by_type("IfcCostSchedule")[0]
ifcopenshell.api.control.unassign_control(model, relating_control=control, related_objects=[element])
assert list(ifcopenshell.util.element.get_controls(element)) == []