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
+2 -5
View File
@@ -154,10 +154,7 @@ def unassign_cost_item_type(
""" """
if not product_types: if not product_types:
product_types = list(spatial.get_selected_product_types()) product_types = list(spatial.get_selected_product_types())
[ ifc.run("control.unassign_control", relating_control=cost_item, related_objects=product_types)
ifc.run("control.unassign_control", relating_control=cost_item, related_object=product_type)
for product_type in product_types
]
cost.load_cost_item_types(cost_item) cost.load_cost_item_types(cost_item)
return product_types return product_types
@@ -213,7 +210,7 @@ def assign_cost_value(
if existing_cost_rate is None: if existing_cost_rate is None:
ifc.run("control.assign_control", relating_control=cost_rate, related_objects=[cost_item]) ifc.run("control.assign_control", relating_control=cost_rate, related_objects=[cost_item])
else: else:
ifc.run("control.unassign_control", relating_control=existing_cost_rate, related_object=cost_item) ifc.run("control.unassign_control", relating_control=existing_cost_rate, related_objects=[cost_item])
ifc.run("control.assign_control", relating_control=cost_rate, related_objects=[cost_item]) ifc.run("control.assign_control", relating_control=cost_rate, related_objects=[cost_item])
+1 -1
View File
@@ -433,7 +433,7 @@ def remove_task_calendar(
task: ifcopenshell.entity_instance, task: ifcopenshell.entity_instance,
work_calendar: ifcopenshell.entity_instance, work_calendar: ifcopenshell.entity_instance,
) -> None: ) -> None:
ifc.run("control.unassign_control", relating_control=work_calendar, related_object=task) ifc.run("control.unassign_control", relating_control=work_calendar, related_objects=[task])
ifc.run("sequence.cascade_schedule", task=task) ifc.run("sequence.cascade_schedule", task=task)
sequence.load_task_properties() sequence.load_task_properties()
+1 -1
View File
@@ -358,7 +358,7 @@ class Csv2Ifc:
) )
else: else:
ifcopenshell.api.control.unassign_control( ifcopenshell.api.control.unassign_control(
self.file, relating_control=existing_cost_rate, related_object=cost_item["ifc"] self.file, relating_control=existing_cost_rate, related_objects=[cost_item["ifc"]]
) )
ifcopenshell.api.control.assign_control( ifcopenshell.api.control.assign_control(
self.file, relating_control=rate_cost_item, related_objects=[cost_item["ifc"]] self.file, relating_control=rate_cost_item, related_objects=[cost_item["ifc"]]
@@ -19,21 +19,19 @@
import ifcopenshell import ifcopenshell
import ifcopenshell.api.owner import ifcopenshell.api.owner
import ifcopenshell.util.element import ifcopenshell.util.element
from typing import Union
def unassign_control( def unassign_control(
file: ifcopenshell.file, file: ifcopenshell.file,
relating_control: ifcopenshell.entity_instance, relating_control: ifcopenshell.entity_instance,
related_object: ifcopenshell.entity_instance, related_objects: list[ifcopenshell.entity_instance],
) -> Union[ifcopenshell.entity_instance, None]: ) -> None:
"""Unassigns a planning control or constraint to an object """Unassigns a planning control or constraint to an object
:param relating_control: The IfcControl entity that is creating the :param relating_control: The IfcControl entity that is creating the
control or constraint control or constraint
:param related_object: The IfcObjectDefinition that is being controlled :param related_objects: The list IfcObjectDefinitions that is being controlled
:return: If the control still is related to other objects, the :return: None
IfcRelAssignsToControl is returned, otherwise None.
Example: Example:
@@ -49,19 +47,19 @@ def unassign_control(
# And now let's change our mind # And now let's change our mind
ifcopenshell.api.control.unassign_control(model, 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 []: related_objects_set = set(related_objects)
if not rel.is_a("IfcRelAssignsToControl") or rel.RelatingControl != relating_control: control_assignments = set(relating_control.Controls)
continue rels = set(rel for obj in related_objects_set for rel in obj.HasAssignments if rel in control_assignments)
if len(rel.RelatedObjects) == 1:
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 history = rel.OwnerHistory
file.remove(rel) file.remove(rel)
if history: if history:
ifcopenshell.util.element.remove_deep2(file, 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: for product in products:
ifcopenshell.api.control.unassign_control( ifcopenshell.api.control.unassign_control(
self.file, self.file,
related_object=product, related_objects=[product],
relating_control=cost_item, relating_control=cost_item,
) )
self.update_cost_item_count(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( ifcopenshell.api.control.unassign_control(
file, file,
relating_control=work_calendar, relating_control=work_calendar,
related_object=related_object, related_objects=[related_object],
) )
# Currently in API work times are created already attached # Currently in API work times are created already attached
@@ -29,7 +29,7 @@ class TestUnassignControl(test.bootstrap.IFC4):
# assign and unassign # assign and unassign
relation = ifcopenshell.api.control.assign_control(self.file, relating_control=control, related_objects=[wall]) relation = ifcopenshell.api.control.assign_control(self.file, relating_control=control, related_objects=[wall])
assert relation 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 assert len(self.file.by_type("IfcRelAssignsToControl")) == 0
# 1 control 2 related objects # 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]) relation = ifcopenshell.api.control.assign_control(self.file, relating_control=control, related_objects=[wall])
assert relation assert relation
ifcopenshell.api.control.assign_control(self.file, relating_control=control, related_objects=[wall1]) 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 len(self.file.by_type("IfcRelAssignsToControl")) == 1
assert relation.RelatedObjects == (wall,) assert relation.RelatedObjects == (wall,)
@@ -43,3 +43,12 @@ class TestTemporarySupportForDeprecatedAPIArguments(test.bootstrap.IFC4):
control = ifcopenshell.api.cost.add_cost_schedule(model) control = ifcopenshell.api.cost.add_cost_schedule(model)
ifcopenshell.api.control.assign_control(model, relating_control=control, related_objects=[element]) ifcopenshell.api.control.assign_control(model, relating_control=control, related_objects=[element])
assert list(ifcopenshell.util.element.get_controls(element)) == [control] 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)) == []