mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 02:07:36 +00:00
control.assign_control to support batching
This commit is contained in:
@@ -135,10 +135,8 @@ def assign_cost_item_type(
|
|||||||
List of found product types.
|
List of found product types.
|
||||||
"""
|
"""
|
||||||
product_types = list(spatial.get_selected_product_types())
|
product_types = list(spatial.get_selected_product_types())
|
||||||
rels = [
|
ifc.run("control.assign_control", relating_control=cost_item, related_objects=product_types)
|
||||||
ifc.run("control.assign_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,10 +211,10 @@ def assign_cost_value(
|
|||||||
ifc.run("cost.assign_cost_value", cost_item=cost_item, cost_rate=cost_rate)
|
ifc.run("cost.assign_cost_value", cost_item=cost_item, cost_rate=cost_rate)
|
||||||
existing_cost_rate = cost.get_assigned_rate_cost_item(cost_item)
|
existing_cost_rate = cost.get_assigned_rate_cost_item(cost_item)
|
||||||
if existing_cost_rate is None:
|
if existing_cost_rate is None:
|
||||||
ifc.run("control.assign_control", relating_control=cost_rate, related_object=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_object=cost_item)
|
||||||
ifc.run("control.assign_control", relating_control=cost_rate, related_object=cost_item)
|
ifc.run("control.assign_control", relating_control=cost_rate, related_objects=[cost_item])
|
||||||
|
|
||||||
|
|
||||||
def load_schedule_of_rates(cost: type[tool.Cost], schedule_of_rates: ifcopenshell.entity_instance) -> None:
|
def load_schedule_of_rates(cost: type[tool.Cost], schedule_of_rates: ifcopenshell.entity_instance) -> None:
|
||||||
|
|||||||
@@ -422,7 +422,7 @@ def edit_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.assign_control", relating_control=work_calendar, related_object=task)
|
ifc.run("control.assign_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()
|
||||||
|
|
||||||
|
|||||||
@@ -261,6 +261,7 @@ class ScheduleIfcGenerator:
|
|||||||
wbs: Union[WBSEntry, None],
|
wbs: Union[WBSEntry, None],
|
||||||
work_schedule: Union[ifcopenshell.entity_instance, None],
|
work_schedule: Union[ifcopenshell.entity_instance, None],
|
||||||
) -> None:
|
) -> None:
|
||||||
|
assert self.file
|
||||||
activity["ifc"] = ifcopenshell.api.sequence.add_task(
|
activity["ifc"] = ifcopenshell.api.sequence.add_task(
|
||||||
self.file,
|
self.file,
|
||||||
work_schedule=None if wbs else work_schedule,
|
work_schedule=None if wbs else work_schedule,
|
||||||
@@ -283,7 +284,7 @@ class ScheduleIfcGenerator:
|
|||||||
ifcopenshell.api.control.assign_control(
|
ifcopenshell.api.control.assign_control(
|
||||||
self.file,
|
self.file,
|
||||||
relating_control=calendar["ifc"],
|
relating_control=calendar["ifc"],
|
||||||
related_object=activity["ifc"],
|
related_objects=[activity["ifc"]],
|
||||||
)
|
)
|
||||||
ifcopenshell.api.sequence.edit_task_time(
|
ifcopenshell.api.sequence.edit_task_time(
|
||||||
self.file,
|
self.file,
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ class MSP2Ifc:
|
|||||||
ifcopenshell.api.control.assign_control(
|
ifcopenshell.api.control.assign_control(
|
||||||
self.file,
|
self.file,
|
||||||
relating_control=calendar,
|
relating_control=calendar,
|
||||||
related_object=task["ifc"],
|
related_objects=[task["ifc"]],
|
||||||
)
|
)
|
||||||
|
|
||||||
ifcopenshell.api.sequence.edit_task(
|
ifcopenshell.api.sequence.edit_task(
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ from __future__ import annotations
|
|||||||
import csv
|
import csv
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.api
|
import ifcopenshell.api
|
||||||
|
import ifcopenshell.api.control
|
||||||
import ifcopenshell.api.cost
|
import ifcopenshell.api.cost
|
||||||
import ifcopenshell.api.root
|
import ifcopenshell.api.root
|
||||||
import ifcopenshell.util.unit
|
import ifcopenshell.util.unit
|
||||||
@@ -353,14 +354,14 @@ class Csv2Ifc:
|
|||||||
existing_cost_rate = assignment.RelatingControl
|
existing_cost_rate = assignment.RelatingControl
|
||||||
if existing_cost_rate is None:
|
if existing_cost_rate is None:
|
||||||
ifcopenshell.api.control.assign_control(
|
ifcopenshell.api.control.assign_control(
|
||||||
self.file, relating_control=rate_cost_item, related_object=cost_item["ifc"]
|
self.file, relating_control=rate_cost_item, related_objects=[cost_item["ifc"]]
|
||||||
)
|
)
|
||||||
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_object=cost_item["ifc"]
|
||||||
)
|
)
|
||||||
ifcopenshell.api.control.assign_control(
|
ifcopenshell.api.control.assign_control(
|
||||||
self.file, relating_control=rate_cost_item, related_object=cost_item["ifc"]
|
self.file, relating_control=rate_cost_item, related_objects=[cost_item["ifc"]]
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
print(f"No cost item found with RateID={cost_rate['RateID']}")
|
print(f"No cost item found with RateID={cost_rate['RateID']}")
|
||||||
|
|||||||
@@ -53,6 +53,22 @@ pre_listeners: dict[str, dict] = {}
|
|||||||
post_listeners: dict[str, dict] = {}
|
post_listeners: dict[str, dict] = {}
|
||||||
|
|
||||||
|
|
||||||
|
def batching_argument_deprecation(
|
||||||
|
usecase_path: str, settings: dict, prev_argument: str, new_argument: str, replace_usecase: Optional[str] = None
|
||||||
|
) -> tuple[str, dict]:
|
||||||
|
if replace_usecase is not None:
|
||||||
|
print(f"WARNING. `{usecase_path}` api method is deprecated and should be replaced with `{replace_usecase}`.")
|
||||||
|
|
||||||
|
if prev_argument in settings:
|
||||||
|
print(
|
||||||
|
f"WARNING. `{prev_argument}` argument is deprecated for API method "
|
||||||
|
f'"{usecase_path}" and should be replaced with `{new_argument}`.'
|
||||||
|
)
|
||||||
|
settings = settings | {new_argument: [settings[prev_argument]]}
|
||||||
|
settings.pop(prev_argument)
|
||||||
|
return (replace_usecase or usecase_path, settings)
|
||||||
|
|
||||||
|
|
||||||
def renamed_arguments_deprecation(
|
def renamed_arguments_deprecation(
|
||||||
usecase_path: str, settings: dict, arguments_remapped: dict[str, str]
|
usecase_path: str, settings: dict, arguments_remapped: dict[str, str]
|
||||||
) -> tuple[str, dict]:
|
) -> tuple[str, dict]:
|
||||||
@@ -71,7 +87,11 @@ def renamed_arguments_deprecation(
|
|||||||
# "group.add_group": partial(
|
# "group.add_group": partial(
|
||||||
# renamed_arguments_deprecation, arguments_remapped={"Name": "name", "Description": "description"}
|
# renamed_arguments_deprecation, arguments_remapped={"Name": "name", "Description": "description"}
|
||||||
# ),
|
# ),
|
||||||
ARGUMENTS_DEPRECATION: dict[str, Callable[[str, dict[str, Any]], tuple[str, dict[str, Any]]]] = {}
|
ARGUMENTS_DEPRECATION: dict[str, Callable[[str, dict[str, Any]], tuple[str, dict[str, Any]]]] = {
|
||||||
|
"control.assign_control": partial(
|
||||||
|
batching_argument_deprecation, prev_argument="related_object", new_argument="related_objects"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
CACHED_USECASE_CLASSES: dict[str, Callable] = {}
|
CACHED_USECASE_CLASSES: dict[str, Callable] = {}
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ from typing import Union
|
|||||||
def assign_control(
|
def assign_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]:
|
) -> Union[ifcopenshell.entity_instance, None]:
|
||||||
"""Assigns a planning control or constraint to an object
|
"""Assigns a planning control or constraint to a list of objects.
|
||||||
|
|
||||||
IFC can describe concepts that control other objects. For example, a
|
IFC can describe concepts that control other objects. For example, a
|
||||||
planning calendar controls the availability of working days for
|
planning calendar controls the availability of working days for
|
||||||
@@ -42,7 +42,7 @@ def assign_control(
|
|||||||
|
|
||||||
: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 of IfcObjectDefinition that is being controlled
|
||||||
:return: The newly created IfcRelAssignsToControl. If relationship already
|
:return: The newly created IfcRelAssignsToControl. If relationship already
|
||||||
existed before and wasn't changed then returns None.
|
existed before and wasn't changed then returns None.
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ def assign_control(
|
|||||||
# All subtasks will inherit this calendar, so assigning a single
|
# All subtasks will inherit this calendar, so assigning a single
|
||||||
# calendar to the root task effectively defines a "default" calendar
|
# calendar to the root task effectively defines a "default" calendar
|
||||||
ifcopenshell.api.control.assign_control(model,
|
ifcopenshell.api.control.assign_control(model,
|
||||||
relating_control=calendar, related_object=task)
|
relating_control=calendar, related_objects=[task])
|
||||||
|
|
||||||
# Another common example might be relating a cost item and a product
|
# Another common example might be relating a cost item and a product
|
||||||
wall = ifcopenshell.api.root.create_entity(model, ifc_class="IfcWall")
|
wall = ifcopenshell.api.root.create_entity(model, ifc_class="IfcWall")
|
||||||
@@ -67,22 +67,33 @@ def assign_control(
|
|||||||
cost_item = ifcopenshell.api.cost.add_cost_item(model,
|
cost_item = ifcopenshell.api.cost.add_cost_item(model,
|
||||||
cost_schedule=schedule)
|
cost_schedule=schedule)
|
||||||
ifcopenshell.api.control.assign_control(model,
|
ifcopenshell.api.control.assign_control(model,
|
||||||
relating_control=cost_item, related_object=wall)
|
relating_control=cost_item, related_objects=[wall])
|
||||||
"""
|
"""
|
||||||
if related_object.HasAssignments:
|
# Filter out already assigned objects.
|
||||||
for assignment in related_object.HasAssignments:
|
related_objects_set = set(related_objects)
|
||||||
if assignment.is_a("IfcRelAssignsToControl") and assignment.RelatingControl == relating_control:
|
objects_to_assign: set[ifcopenshell.entity_instance] = set()
|
||||||
return
|
|
||||||
|
control_assignments = set(relating_control.Controls)
|
||||||
|
if control_assignments:
|
||||||
|
for obj in related_objects_set:
|
||||||
|
existing_assignment = next((a for a in obj.HasAssignments if a in control_assignments), None)
|
||||||
|
# Skip objects already assigned to this control.
|
||||||
|
if existing_assignment:
|
||||||
|
continue
|
||||||
|
objects_to_assign.add(obj)
|
||||||
|
else:
|
||||||
|
objects_to_assign = related_objects_set
|
||||||
|
|
||||||
|
if not objects_to_assign:
|
||||||
|
return None
|
||||||
|
|
||||||
controls: Union[ifcopenshell.entity_instance, None]
|
controls: Union[ifcopenshell.entity_instance, None]
|
||||||
controls = next(iter(relating_control.Controls), None)
|
controls = next(iter(relating_control.Controls), None)
|
||||||
|
|
||||||
if controls:
|
if controls:
|
||||||
if related_object in controls.RelatedObjects:
|
related_objects_new: list[ifcopenshell.entity_instance] = list(controls.RelatedObjects)
|
||||||
return
|
related_objects_new.extend(objects_to_assign)
|
||||||
related_objects = set(controls.RelatedObjects)
|
controls.RelatedObjects = list(related_objects_new)
|
||||||
related_objects.add(related_object)
|
|
||||||
controls.RelatedObjects = list(related_objects)
|
|
||||||
ifcopenshell.api.owner.update_owner_history(file, element=controls)
|
ifcopenshell.api.owner.update_owner_history(file, element=controls)
|
||||||
else:
|
else:
|
||||||
controls = file.create_entity(
|
controls = file.create_entity(
|
||||||
@@ -90,7 +101,7 @@ def assign_control(
|
|||||||
**{
|
**{
|
||||||
"GlobalId": ifcopenshell.guid.new(),
|
"GlobalId": ifcopenshell.guid.new(),
|
||||||
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
|
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
|
||||||
"RelatedObjects": [related_object],
|
"RelatedObjects": list(objects_to_assign),
|
||||||
"RelatingControl": relating_control,
|
"RelatingControl": relating_control,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ def unassign_control(
|
|||||||
cost_item = ifcopenshell.api.cost.add_cost_item(model,
|
cost_item = ifcopenshell.api.cost.add_cost_item(model,
|
||||||
cost_schedule=schedule)
|
cost_schedule=schedule)
|
||||||
ifcopenshell.api.control.assign_control(model,
|
ifcopenshell.api.control.assign_control(model,
|
||||||
relating_control=cost_item, related_object=wall)
|
relating_control=cost_item, related_objects=[wall])
|
||||||
|
|
||||||
# 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,
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ def add_cost_item(
|
|||||||
cost_item_ = ifcopenshell.api.root.create_entity(file, ifc_class="IfcCostItem")
|
cost_item_ = ifcopenshell.api.root.create_entity(file, ifc_class="IfcCostItem")
|
||||||
|
|
||||||
if cost_schedule:
|
if cost_schedule:
|
||||||
ifcopenshell.api.control.assign_control(file, cost_schedule, cost_item_)
|
ifcopenshell.api.control.assign_control(file, cost_schedule, [cost_item_])
|
||||||
elif cost_item:
|
elif cost_item:
|
||||||
ifcopenshell.api.nest.assign_object(file, related_objects=[cost_item_], relating_object=cost_item)
|
ifcopenshell.api.nest.assign_object(file, related_objects=[cost_item_], relating_object=cost_item)
|
||||||
return cost_item_
|
return cost_item_
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ def add_cost_item_quantity(
|
|||||||
schedule = ifcopenshell.api.cost.add_cost_schedule(model)
|
schedule = ifcopenshell.api.cost.add_cost_schedule(model)
|
||||||
item = ifcopenshell.api.cost.add_cost_item(model, cost_schedule=schedule)
|
item = ifcopenshell.api.cost.add_cost_item(model, cost_schedule=schedule)
|
||||||
ifcopenshell.api.control.assign_control(model,
|
ifcopenshell.api.control.assign_control(model,
|
||||||
relating_control=item, related_object=chair)
|
relating_control=item, related_objects=[chair])
|
||||||
|
|
||||||
# Let's assume we want to count the amount of chairs to calculate our cost item
|
# Let's assume we want to count the amount of chairs to calculate our cost item
|
||||||
# Because this is an IfcQuantityCount the count will be automatically set to "1" chair
|
# Because this is an IfcQuantityCount the count will be automatically set to "1" chair
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ class Usecase:
|
|||||||
) -> ifcopenshell.entity_instance:
|
) -> ifcopenshell.entity_instance:
|
||||||
return ifcopenshell.api.control.assign_control(
|
return ifcopenshell.api.control.assign_control(
|
||||||
self.file,
|
self.file,
|
||||||
related_object=related_object,
|
related_objects=[related_object],
|
||||||
relating_control=cost_item,
|
relating_control=cost_item,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ def calculate_cost_item_resource_value(file: ifcopenshell.file, cost_item: ifcop
|
|||||||
concrete = ifcopenshell.api.resource.add_resource(model,
|
concrete = ifcopenshell.api.resource.add_resource(model,
|
||||||
ifc_class="IfcConstructionMaterialResource", parent_resource=crew)
|
ifc_class="IfcConstructionMaterialResource", parent_resource=crew)
|
||||||
ifcopenshell.api.control.assign_control(model,
|
ifcopenshell.api.control.assign_control(model,
|
||||||
relating_control=item, related_object=concrete)
|
relating_control=item, related_objects=[concrete])
|
||||||
# ... which has a unit price of 42.0 per m3
|
# ... which has a unit price of 42.0 per m3
|
||||||
value = ifcopenshell.api.cost.add_cost_value(model, parent=concrete)
|
value = ifcopenshell.api.cost.add_cost_value(model, parent=concrete)
|
||||||
ifcopenshell.api.cost.edit_cost_value(model, cost_value=value,
|
ifcopenshell.api.cost.edit_cost_value(model, cost_value=value,
|
||||||
@@ -72,7 +72,7 @@ def calculate_cost_item_resource_value(file: ifcopenshell.file, cost_item: ifcop
|
|||||||
equipment = ifcopenshell.api.resource.add_resource(model,
|
equipment = ifcopenshell.api.resource.add_resource(model,
|
||||||
ifc_class="IfcConstructionEquipmentResource", parent_resource=crew)
|
ifc_class="IfcConstructionEquipmentResource", parent_resource=crew)
|
||||||
ifcopenshell.api.control.assign_control(model,
|
ifcopenshell.api.control.assign_control(model,
|
||||||
relating_control=item, related_object=equipment)
|
relating_control=item, related_objects=[equipment])
|
||||||
# ... with a fixed price of 50,000
|
# ... with a fixed price of 50,000
|
||||||
value = ifcopenshell.api.cost.add_cost_value(model, parent=concrete)
|
value = ifcopenshell.api.cost.add_cost_value(model, parent=concrete)
|
||||||
ifcopenshell.api.cost.edit_cost_value(model, cost_value=value,
|
ifcopenshell.api.cost.edit_cost_value(model, cost_value=value,
|
||||||
|
|||||||
@@ -45,5 +45,5 @@ def copy_cost_schedule(
|
|||||||
if isinstance(duplicated_cost_item, list):
|
if isinstance(duplicated_cost_item, list):
|
||||||
# All other nested items are not connected to the cost schedule explicitly.
|
# All other nested items are not connected to the cost schedule explicitly.
|
||||||
duplicated_cost_item = duplicated_cost_item[0]
|
duplicated_cost_item = duplicated_cost_item[0]
|
||||||
ifcopenshell.api.control.assign_control(file, new_schedule, duplicated_cost_item)
|
ifcopenshell.api.control.assign_control(file, new_schedule, [duplicated_cost_item])
|
||||||
return new_schedule
|
return new_schedule
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ def add_task(
|
|||||||
task.Identification = identification
|
task.Identification = identification
|
||||||
task.IsMilestone = False
|
task.IsMilestone = False
|
||||||
if work_schedule:
|
if work_schedule:
|
||||||
ifcopenshell.api.control.assign_control(file, work_schedule, task)
|
ifcopenshell.api.control.assign_control(file, work_schedule, [task])
|
||||||
elif parent_task:
|
elif parent_task:
|
||||||
rel = ifcopenshell.api.nest.assign_object(
|
rel = ifcopenshell.api.nest.assign_object(
|
||||||
file,
|
file,
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ def add_work_calendar(
|
|||||||
# We associate the calendar with the construction root task. All
|
# We associate the calendar with the construction root task. All
|
||||||
# subtasks underneath the construction work task will also inherit
|
# subtasks underneath the construction work task will also inherit
|
||||||
# this calendar by default (though you can override them).
|
# this calendar by default (though you can override them).
|
||||||
ifcopenshell.api.control.assign_control(model, relating_control=calendar, related_object=task)
|
ifcopenshell.api.control.assign_control(model, relating_control=calendar, related_objects=[task])
|
||||||
"""
|
"""
|
||||||
work_calendar = ifcopenshell.api.root.create_entity(
|
work_calendar = ifcopenshell.api.root.create_entity(
|
||||||
file,
|
file,
|
||||||
|
|||||||
@@ -47,5 +47,5 @@ def copy_work_schedule(
|
|||||||
duplicated_tasks = ifcopenshell.api.sequence.duplicate_task(file, task)[1]
|
duplicated_tasks = ifcopenshell.api.sequence.duplicate_task(file, task)[1]
|
||||||
# All other nested items are not connected to the work schedule explicitly.
|
# All other nested items are not connected to the work schedule explicitly.
|
||||||
duplicated_task = duplicated_tasks[0]
|
duplicated_task = duplicated_tasks[0]
|
||||||
ifcopenshell.api.control.assign_control(file, new_schedule, duplicated_task)
|
ifcopenshell.api.control.assign_control(file, new_schedule, [duplicated_task])
|
||||||
return new_schedule
|
return new_schedule
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ class Usecase:
|
|||||||
assert isinstance(res, list)
|
assert isinstance(res, list)
|
||||||
current, duplicate = res
|
current, duplicate = res
|
||||||
ifcopenshell.api.control.assign_control(
|
ifcopenshell.api.control.assign_control(
|
||||||
self.file, relating_control=baseline_work_schedule, related_object=duplicate[0]
|
self.file, relating_control=baseline_work_schedule, related_objects=[duplicate[0]]
|
||||||
)
|
)
|
||||||
for i, task in enumerate(current):
|
for i, task in enumerate(current):
|
||||||
self.create_baseline_reference(task, duplicate[i])
|
self.create_baseline_reference(task, duplicate[i])
|
||||||
|
|||||||
@@ -27,23 +27,33 @@ class TestAssignControl(test.bootstrap.IFC4):
|
|||||||
control = ifcopenshell.api.cost.add_cost_schedule(self.file)
|
control = ifcopenshell.api.cost.add_cost_schedule(self.file)
|
||||||
|
|
||||||
# simple assignment
|
# simple assignment
|
||||||
relation = ifcopenshell.api.control.assign_control(self.file, relating_control=control, related_object=wall)
|
relation = ifcopenshell.api.control.assign_control(self.file, relating_control=control, related_objects=[wall])
|
||||||
|
assert relation
|
||||||
assert len(self.file.by_type("IfcRelAssignsToControl")) == 1
|
assert len(self.file.by_type("IfcRelAssignsToControl")) == 1
|
||||||
assert relation.RelatingControl == control
|
assert relation.RelatingControl == control
|
||||||
assert relation.RelatedObjects == (wall,)
|
assert relation.RelatedObjects == (wall,)
|
||||||
|
|
||||||
# trying to establish existing relationship
|
# trying to establish existing relationship
|
||||||
relation = ifcopenshell.api.control.assign_control(self.file, relating_control=control, related_object=wall)
|
relation = ifcopenshell.api.control.assign_control(self.file, relating_control=control, related_objects=[wall])
|
||||||
assert relation is None
|
assert relation is None
|
||||||
|
|
||||||
# assigning same control to another object
|
# assigning same control to another object
|
||||||
wall1 = self.file.createIfcWall()
|
wall1 = self.file.createIfcWall()
|
||||||
relation = ifcopenshell.api.control.assign_control(self.file, relating_control=control, related_object=wall1)
|
relation = ifcopenshell.api.control.assign_control(self.file, relating_control=control, related_objects=[wall1])
|
||||||
assert relation is not None
|
assert relation is not None
|
||||||
assert len(self.file.by_type("IfcRelAssignsToControl")) == 1
|
assert len(self.file.by_type("IfcRelAssignsToControl")) == 1
|
||||||
assert relation.RelatingControl == control
|
assert relation.RelatingControl == control
|
||||||
assert set(relation.RelatedObjects) == set((wall, wall1))
|
assert set(relation.RelatedObjects) == set((wall, wall1))
|
||||||
|
|
||||||
|
def test_batch_assignment(self):
|
||||||
|
walls = [self.file.createIfcWall() for _ in range(5)]
|
||||||
|
control = ifcopenshell.api.cost.add_cost_schedule(self.file)
|
||||||
|
relation = ifcopenshell.api.control.assign_control(self.file, relating_control=control, related_objects=walls)
|
||||||
|
assert relation
|
||||||
|
assert len(self.file.by_type("IfcRelAssignsToControl")) == 1
|
||||||
|
assert relation.RelatingControl == control
|
||||||
|
assert set(relation.RelatedObjects) == set(walls)
|
||||||
|
|
||||||
|
|
||||||
class TestAssignControlIFC2X3(test.bootstrap.IFC2X3, TestAssignControl):
|
class TestAssignControlIFC2X3(test.bootstrap.IFC2X3, TestAssignControl):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -27,14 +27,16 @@ class TestUnassignControl(test.bootstrap.IFC4):
|
|||||||
control = ifcopenshell.api.cost.add_cost_schedule(self.file)
|
control = ifcopenshell.api.cost.add_cost_schedule(self.file)
|
||||||
|
|
||||||
# assign and unassign
|
# assign and unassign
|
||||||
relation = ifcopenshell.api.control.assign_control(self.file, relating_control=control, related_object=wall)
|
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_object=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
|
||||||
wall1 = self.file.createIfcWall()
|
wall1 = self.file.createIfcWall()
|
||||||
relation = ifcopenshell.api.control.assign_control(self.file, relating_control=control, related_object=wall)
|
relation = ifcopenshell.api.control.assign_control(self.file, relating_control=control, related_objects=[wall])
|
||||||
ifcopenshell.api.control.assign_control(self.file, relating_control=control, related_object=wall1)
|
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_object=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,)
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class TestAddCostItemQuantity(test.bootstrap.IFC4):
|
|||||||
schedule = ifcopenshell.api.cost.add_cost_schedule(self.file)
|
schedule = ifcopenshell.api.cost.add_cost_schedule(self.file)
|
||||||
item = ifcopenshell.api.cost.add_cost_item(self.file, cost_schedule=schedule)
|
item = ifcopenshell.api.cost.add_cost_item(self.file, cost_schedule=schedule)
|
||||||
wall = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
wall = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||||
ifcopenshell.api.control.assign_control(self.file, relating_control=item, related_object=wall)
|
ifcopenshell.api.control.assign_control(self.file, relating_control=item, related_objects=[wall])
|
||||||
|
|
||||||
quantities = []
|
quantities = []
|
||||||
for quantity_type in quantity_types:
|
for quantity_type in quantity_types:
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ class TestEditTaskTime(test.bootstrap.IFC4):
|
|||||||
ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject")
|
ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject")
|
||||||
calendar = ifcopenshell.api.sequence.add_work_calendar(self.file)
|
calendar = ifcopenshell.api.sequence.add_work_calendar(self.file)
|
||||||
task = self.file.createIfcTask()
|
task = self.file.createIfcTask()
|
||||||
ifcopenshell.api.control.assign_control(self.file, relating_control=calendar, related_object=task)
|
ifcopenshell.api.control.assign_control(self.file, relating_control=calendar, related_objects=[task])
|
||||||
task_time = ifcopenshell.api.sequence.add_task_time(self.file, task=task)
|
task_time = ifcopenshell.api.sequence.add_task_time(self.file, task=task)
|
||||||
ifcopenshell.api.sequence.edit_task_time(
|
ifcopenshell.api.sequence.edit_task_time(
|
||||||
self.file,
|
self.file,
|
||||||
@@ -195,7 +195,7 @@ class TestEditTaskTime(test.bootstrap.IFC4):
|
|||||||
ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject")
|
ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject")
|
||||||
calendar = ifcopenshell.api.sequence.add_work_calendar(self.file)
|
calendar = ifcopenshell.api.sequence.add_work_calendar(self.file)
|
||||||
task = self.file.createIfcTask()
|
task = self.file.createIfcTask()
|
||||||
ifcopenshell.api.control.assign_control(self.file, relating_control=calendar, related_object=task)
|
ifcopenshell.api.control.assign_control(self.file, relating_control=calendar, related_objects=[task])
|
||||||
task_time = ifcopenshell.api.sequence.add_task_time(self.file, task=task)
|
task_time = ifcopenshell.api.sequence.add_task_time(self.file, task=task)
|
||||||
ifcopenshell.api.sequence.edit_task_time(
|
ifcopenshell.api.sequence.edit_task_time(
|
||||||
self.file,
|
self.file,
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class TestRemoveWorkCalendar(test.bootstrap.IFC4):
|
|||||||
|
|
||||||
# Assign tasks.
|
# Assign tasks.
|
||||||
task = ifcopenshell.api.sequence.add_task(self.file)
|
task = ifcopenshell.api.sequence.add_task(self.file)
|
||||||
ifcopenshell.api.control.assign_control(self.file, work_calendar, task)
|
ifcopenshell.api.control.assign_control(self.file, work_calendar, [task])
|
||||||
|
|
||||||
ifcopenshell.api.sequence.remove_work_calendar(self.file, work_calendar)
|
ifcopenshell.api.sequence.remove_work_calendar(self.file, work_calendar)
|
||||||
|
|
||||||
|
|||||||
@@ -16,19 +16,30 @@
|
|||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import ifcopenshell.api.cost
|
||||||
|
import ifcopenshell.api.root
|
||||||
import test.bootstrap
|
import test.bootstrap
|
||||||
import ifcopenshell.api
|
import ifcopenshell.api
|
||||||
|
import ifcopenshell.api.control
|
||||||
|
import ifcopenshell.api.sequence
|
||||||
|
import ifcopenshell.util.element
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
|
|
||||||
def deprecation_check(test):
|
def deprecation_check(test):
|
||||||
def new_test(self):
|
def new_test(self):
|
||||||
assert datetime.now().date() < datetime(2024, 8, 1).date(), "API arguments are completely deprecated"
|
assert datetime.now().date() < datetime(2026, 1, 9).date(), "API arguments are completely deprecated"
|
||||||
test(self)
|
test(self)
|
||||||
|
|
||||||
return new_test
|
return new_test
|
||||||
|
|
||||||
|
|
||||||
class TestTemporarySupportForDeprecatedAPIArguments(test.bootstrap.IFC4):
|
class TestTemporarySupportForDeprecatedAPIArguments(test.bootstrap.IFC4):
|
||||||
pass
|
@deprecation_check
|
||||||
|
def test_assigning_control(self):
|
||||||
|
model = self.file
|
||||||
|
element = ifcopenshell.api.root.create_entity(model, ifc_class="IfcWall")
|
||||||
|
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]
|
||||||
|
|||||||
Reference in New Issue
Block a user