This commit is contained in:
Andrej730
2025-03-14 10:43:47 +05:00
parent 10ecac33b8
commit 0e8810c1f5
118 changed files with 869 additions and 1203 deletions
@@ -69,23 +69,16 @@ def add_task(
:param work_schedule: The work schedule to group the task in, if the
task is to be a top-level or root task. This is mutually exclusive
with the parent_task parameter.
:type work_schedule: ifcopenshell.entity_instance, optional
:param parent_task: The parent task, if the task is to be a subtask or
child task. This is mutually exclusive with the work_schedule
parameter.
:type parent_task: ifcopenshell.entity_instance, optioanl
:param name: The name of the task.
:type name: str,optional
:param description: The description of the task.
:type description: str,optional
:param identification: The identification code of the task.
:type identification: str,optional
:param predefined_type: The predefined type of the task. Common ones
include CONSTRUCTION, DEMOLITION, or MAINTENANCE. Consultant the
IFC documentation for IfcTaskTypeEnum for more information.
:type predefined_type: str
:return: The newly created IfcTask
:rtype: ifcopenshell.entity_instance
Example:
@@ -139,39 +132,28 @@ def add_task(
ifcopenshell.api.sequence.add_task(model, parent_task=cleaning, identification="3",
description="Setup the water pressure by tapping to a water supply and connecting to a ...")
"""
settings = {
"work_schedule": work_schedule,
"parent_task": parent_task,
"name": name,
"description": description,
"identification": identification,
"predefined_type": predefined_type,
}
task = ifcopenshell.api.root.create_entity(
file, ifc_class="IfcTask", name=settings["name"], predefined_type=settings["predefined_type"]
)
if settings["description"]:
task.Description = settings["description"]
if settings["identification"]:
task.Identification = settings["identification"]
task = ifcopenshell.api.root.create_entity(file, ifc_class="IfcTask", name=name, predefined_type=predefined_type)
if description:
task.Description = description
if identification:
task.Identification = identification
task.IsMilestone = False
if settings["work_schedule"]:
if work_schedule:
file.create_entity(
"IfcRelAssignsToControl",
**{
"GlobalId": ifcopenshell.guid.new(),
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
"RelatedObjects": [task],
"RelatingControl": settings["work_schedule"],
"RelatingControl": work_schedule,
}
)
elif settings["parent_task"]:
elif parent_task:
rel = ifcopenshell.api.nest.assign_object(
file,
related_objects=[task],
relating_object=settings["parent_task"],
relating_object=parent_task,
)
if file.schema != "IFC2X3" and settings["parent_task"].Identification:
task.Identification = settings["parent_task"].Identification + "." + str(len(rel.RelatedObjects))
if file.schema != "IFC2X3" and parent_task.Identification:
task.Identification = parent_task.Identification + "." + str(len(rel.RelatedObjects))
return task
@@ -44,17 +44,13 @@ def add_time_period(
:param recurrence_pattern: The IfcRecurrencePattern to add the time
period to. See ifcopenshell.api.sequence.assign_recurrence_pattern.
:type recurrence_pattern: ifcopenshell.entity_instance
:param start_time: The start time of the time period, in a format
compatible with IfcTime, such as an ISO format time string or a
datetime.time object.
:type start_time: str,datetime.time
:param end_time: The end time of the time period, in a format
compatible with IfcTime, such as an ISO format time string or a
datetime.time object.
:type end_time: str,datetime.time
:return: The newly created IfcTimePeriod
:rtype: ifcopenshell.entity_instance
Example:
@@ -81,18 +77,12 @@ def add_time_period(
ifcopenshell.api.sequence.add_time_period(model,
recurrence_pattern=pattern, start_time="13:00", end_time="17:00")
"""
settings = {
"recurrence_pattern": recurrence_pattern,
"start_time": start_time,
"end_time": end_time,
}
time_period = file.create_entity("IfcTimePeriod")
time_period.StartTime = ifcopenshell.util.date.datetime2ifc(settings["start_time"], "IfcTime")
time_period.EndTime = ifcopenshell.util.date.datetime2ifc(settings["end_time"], "IfcTime")
time_periods = list(settings["recurrence_pattern"].TimePeriods or [])
time_period.StartTime = ifcopenshell.util.date.datetime2ifc(start_time, "IfcTime")
time_period.EndTime = ifcopenshell.util.date.datetime2ifc(end_time, "IfcTime")
time_periods = list(recurrence_pattern.TimePeriods or [])
time_periods.append(time_period)
settings["recurrence_pattern"].TimePeriods = time_periods
recurrence_pattern.TimePeriods = time_periods
ifcopenshell.util.sequence.is_working_day.cache_clear()
ifcopenshell.util.sequence.is_calendar_applicable.cache_clear()
@@ -38,12 +38,10 @@ def add_work_calendar(
:param name: The name of the calendar. Typically something like
"5 Day Working Week" or "24/7".
:type name: str, optional
:param predefined_type: The type of calendar, typically used to more
specifically define shifts, such as FIRSTSHIFT, SECONDSHIFT, or
THIRDSHIFT. Leave as NOTDEFINED for basic calendar usage.
:return: The newly created IfcWorkCalendar
:rtype: ifcopenshell.entity_instance
Example:
@@ -79,13 +77,11 @@ def add_work_calendar(
# this calendar by default (though you can override them).
ifcopenshell.api.control.assign_control(model, relating_control=calendar, related_object=task)
"""
settings = {"name": name, "predefined_type": predefined_type}
work_calendar = ifcopenshell.api.root.create_entity(
file,
ifc_class="IfcWorkCalendar",
predefined_type=settings["predefined_type"],
name=settings["name"],
predefined_type=predefined_type,
name=name,
)
context = file.by_type("IfcContext")[0]
ifcopenshell.api.project.assign_declaration(
@@ -41,15 +41,11 @@ def add_work_plan(
:param name: The name of the work plan. Recommended to be "Maintenance"
or "Construction" for the two main purposes.
:type name: str, optional
:param predefined_type: The type of work plan, used for baselining.
Leave as "NOTDEFINED" if unsure.
:type predefined_type: str
:param start_time: The earliest start time when the schedules grouped
within the work plan are relevant.
:type start_time: str,datetime.time
:return: The newly created IfcWorkPlan
:rtype: ifcopenshell.entity_instance
Example:
@@ -62,23 +58,18 @@ def add_work_plan(
schedule = ifcopenshell.api.sequence.add_work_schedule(model,
name="Construction Schedule A", work_plan=work_plan)
"""
settings = {
"name": name,
"predefined_type": predefined_type,
"start_time": start_time or datetime.now(),
}
start_time = start_time or datetime.now()
work_plan = ifcopenshell.api.root.create_entity(
file,
ifc_class="IfcWorkPlan",
predefined_type=settings["predefined_type"],
name=settings["name"],
predefined_type=predefined_type,
name=name,
)
work_plan.CreationDate = ifcopenshell.util.date.datetime2ifc(datetime.now(), "IfcDateTime")
user = ifcopenshell.api.owner.settings.get_user(file)
if user:
work_plan.Creators = [user.ThePerson]
work_plan.StartTime = ifcopenshell.util.date.datetime2ifc(settings["start_time"], "IfcDateTime")
work_plan.StartTime = ifcopenshell.util.date.datetime2ifc(start_time, "IfcDateTime")
context = file.by_type("IfcContext")[0]
ifcopenshell.api.project.assign_declaration(
@@ -77,19 +77,12 @@ def add_work_schedule(
construction = ifcopenshell.api.sequence.add_task(model,
work_schedule=schedule, name="Construction", identification="C")
"""
settings = {
"name": name,
"predefined_type": predefined_type,
"object_type": object_type,
"start_time": start_time or datetime.now(),
"work_plan": work_plan,
}
start_time = start_time or datetime.now()
work_schedule = ifcopenshell.api.root.create_entity(
file,
ifc_class="IfcWorkSchedule",
predefined_type=settings["predefined_type"],
name=settings["name"],
predefined_type=predefined_type,
name=name,
)
if file.schema == "IFC2X3":
work_schedule.CreationDate = createIfcDateAndTime(file, datetime.now())
@@ -99,17 +92,17 @@ def add_work_schedule(
if user:
work_schedule.Creators = [user.ThePerson]
if file.schema == "IFC2X3":
work_schedule.StartTime = createIfcDateAndTime(file, settings["start_time"])
work_schedule.StartTime = createIfcDateAndTime(file, start_time)
else:
work_schedule.StartTime = ifcopenshell.util.date.datetime2ifc(settings["start_time"], "IfcDateTime")
if settings["object_type"]:
work_schedule.ObjectType = settings["object_type"]
if settings["work_plan"]:
work_schedule.StartTime = ifcopenshell.util.date.datetime2ifc(start_time, "IfcDateTime")
if object_type:
work_schedule.ObjectType = object_type
if work_plan:
ifcopenshell.api.aggregate.assign_object(
file,
**{
"products": [work_schedule],
"relating_object": settings["work_plan"],
"relating_object": work_plan,
}
)
elif file.schema != "IFC2X3":
@@ -36,12 +36,9 @@ def add_work_time(
:param work_calendar: The IfcWorkCalendar to add the work or holiday
time definition to.
:type work_calendar: ifcopenshell.entity_instance
:param time_type: Either WorkingTimes or ExceptionTimes, depending on
what you want to define.
:type time_type: str
:return: The newly created IfcWorkTime
:rtype: ifcopenshell.entity_instance
Example:
@@ -74,15 +71,13 @@ def add_work_time(
ifcopenshell.api.sequence.edit_recurrence_pattern(model,
recurrence_pattern=pattern, attributes={"DayComponent": [1], "MonthComponent": [1]})
"""
settings = {"work_calendar": work_calendar, "time_type": time_type}
work_time = file.create_entity("IfcWorkTime")
if settings["time_type"] == "WorkingTimes":
working_times = list(settings["work_calendar"].WorkingTimes or [])
if time_type == "WorkingTimes":
working_times = list(work_calendar.WorkingTimes or [])
working_times.append(work_time)
settings["work_calendar"].WorkingTimes = working_times
elif settings["time_type"] == "ExceptionTimes":
exception_times = list(settings["work_calendar"].ExceptionTimes or [])
work_calendar.WorkingTimes = working_times
elif time_type == "ExceptionTimes":
exception_times = list(work_calendar.ExceptionTimes or [])
exception_times.append(work_time)
settings["work_calendar"].ExceptionTimes = exception_times
work_calendar.ExceptionTimes = exception_times
return work_time
@@ -65,12 +65,9 @@ def assign_process(
:param relating_process: The IfcProcess (typically IfcTask) that the
input, control, or resource is related to.
:type relating_process: ifcopenshell.entity_instance
:param related_object: The IfcProduct (for input), IfcCostItem (for
control) or IfcConstructionResource (for resource).
:type related_object: ifcopenshell.entity_instance
:return: The newly created IfcRelAssignsToProcess relationship
:rtype: ifcopenshell.entity_instance
Example:
@@ -91,23 +88,18 @@ def assign_process(
# Let's demolish that wall!
ifcopenshell.api.sequence.assign_process(model, relating_process=task, related_object=wall)
"""
settings = {
"relating_process": relating_process,
"related_object": related_object,
}
if settings["related_object"].HasAssignments:
for assignment in settings["related_object"].HasAssignments:
if assignment.is_a("IfcRelAssignsToProcess") and assignment.RelatingProcess == settings["relating_process"]:
if related_object.HasAssignments:
for assignment in related_object.HasAssignments:
if assignment.is_a("IfcRelAssignsToProcess") and assignment.RelatingProcess == relating_process:
return
operates_on = None
if settings["relating_process"].OperatesOn:
operates_on = settings["relating_process"].OperatesOn[0]
if relating_process.OperatesOn:
operates_on = relating_process.OperatesOn[0]
if operates_on:
related_objects = list(operates_on.RelatedObjects)
related_objects.append(settings["related_object"])
related_objects.append(related_object)
operates_on.RelatedObjects = related_objects
ifcopenshell.api.owner.update_owner_history(file, **{"element": operates_on})
else:
@@ -116,8 +108,8 @@ def assign_process(
**{
"GlobalId": ifcopenshell.guid.new(),
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
"RelatedObjects": [settings["related_object"]],
"RelatingProcess": settings["relating_process"],
"RelatedObjects": [related_object],
"RelatingProcess": relating_process,
}
)
return operates_on
@@ -41,12 +41,9 @@ def assign_product(
:param relating_product: The IfcProduct that was constructed as a result
of the task.
:type relating_product: ifcopenshell.entity_instance
:param related_object: The IfcProcess (typically IfcTask) of the
construction task.
:type related_object: ifcopenshell.entity_instance
:return: The newly created IfcRelAssignsToProduct relationship
:rtype: ifcopenshell.entity_instance
Example:
@@ -67,23 +64,18 @@ def assign_product(
# Let's construct that wall!
ifcopenshell.api.sequence.assign_product(model, relating_product=wall, related_object=task)
"""
settings = {
"relating_product": relating_product,
"related_object": related_object,
}
if settings["related_object"].HasAssignments:
for assignment in settings["related_object"].HasAssignments:
if assignment.is_a("IfcRelAssignsToProduct") and assignment.RelatingProduct == settings["relating_product"]:
if related_object.HasAssignments:
for assignment in related_object.HasAssignments:
if assignment.is_a("IfcRelAssignsToProduct") and assignment.RelatingProduct == relating_product:
return assignment
referenced_by = None
if settings["relating_product"].ReferencedBy:
referenced_by = settings["relating_product"].ReferencedBy[0]
if relating_product.ReferencedBy:
referenced_by = relating_product.ReferencedBy[0]
if referenced_by:
related_objects = list(referenced_by.RelatedObjects)
related_objects.append(settings["related_object"])
related_objects.append(related_object)
referenced_by.RelatedObjects = related_objects
ifcopenshell.api.owner.update_owner_history(file, **{"element": referenced_by})
else:
@@ -92,8 +84,8 @@ def assign_product(
**{
"GlobalId": ifcopenshell.guid.new(),
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
"RelatedObjects": [settings["related_object"]],
"RelatingProduct": settings["relating_product"],
"RelatedObjects": [related_object],
"RelatingProduct": relating_product,
}
)
return referenced_by
@@ -19,11 +19,12 @@
import ifcopenshell
import ifcopenshell.api.project
import ifcopenshell.api.aggregate
from typing import Union
def assign_work_plan(
file: ifcopenshell.file, work_schedule: ifcopenshell.entity_instance, work_plan: ifcopenshell.entity_instance
) -> ifcopenshell.entity_instance:
) -> Union[ifcopenshell.entity_instance, None]:
"""Assigns a work schedule to a work plan
Typically, work schedules would be assigned to a work plan at creation.
@@ -31,11 +32,8 @@ def assign_work_plan(
:param work_schedule: The IfcWorkSchedule that will be assigned to the
work plan.
:type work_schedule: ifcopenshell.entity_instance
:param work_plan: The IfcWorkPlan for the schedule to be assigned to.
:type work_plan: ifcopenshell.entity_instance
:return: The IfcRelAggregates relationship
:rtype: ifcopenshell.entity_instance
Example:
@@ -50,20 +48,16 @@ def assign_work_plan(
# ... you can assign the work plan afterwards.
ifcopenshell.api.sequence.assign_work_plan(work_schedule=schedule, work_plan=work_plan)
"""
settings = {"work_schedule": work_schedule, "work_plan": work_plan}
# TODO: this is an ambiguity by buildingSMART
# See https://forums.buildingsmart.org/t/is-the-ifcworkschedule-project-declaration-mutually-exclusive-to-aggregation-within-a-relating-ifcworkplan/3510
ifcopenshell.api.project.unassign_declaration(
file,
definitions=[settings["work_schedule"]],
definitions=[work_schedule],
relating_context=file.by_type("IfcContext")[0],
)
rel_aggregates = ifcopenshell.api.aggregate.assign_object(
file,
**{
"products": [settings["work_schedule"]],
"relating_object": settings["work_plan"],
}
products=[work_schedule],
relating_object=work_plan,
)
return rel_aggregates
@@ -21,6 +21,7 @@ import ifcopenshell.guid
import ifcopenshell.api.nest
import ifcopenshell.api.owner
import ifcopenshell.api.sequence
import ifcopenshell.util.date
import ifcopenshell.util.element
import ifcopenshell.util.sequence
from typing import Union, Any
@@ -155,7 +156,9 @@ class Usecase:
duration_type=inverse.TimeLag.DurationType,
)
def create_object_reference(self, relating_object, related_object):
def create_object_reference(
self, relating_object: ifcopenshell.entity_instance, related_object: ifcopenshell.entity_instance
) -> ifcopenshell.entity_instance:
referenced_by = None
if relating_object.Declares:
referenced_by = relating_object.Declares[0]
@@ -31,9 +31,7 @@ def remove_task(file: ifcopenshell.file, task: ifcopenshell.entity_instance) ->
sequences or controls are also removed.
:param task: The IfcTask to remove.
:type task: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
@@ -56,76 +54,74 @@ def remove_task(file: ifcopenshell.file, task: ifcopenshell.entity_instance) ->
# just fix it on site.
ifcopenshell.api.sequence.remove_task(model, task=design)
"""
settings = {"task": task}
# TODO: do a deep purge
ifcopenshell.api.project.unassign_declaration(
file,
definitions=[settings["task"]],
definitions=[task],
relating_context=file.by_type("IfcContext")[0],
)
if task_time := settings["task"].TaskTime:
if task_time := task.TaskTime:
if task_time.is_a("IfcTaskTimeRecurring"):
ifcopenshell.api.sequence.unassign_recurrence_pattern(file, task_time.Recurrence)
file.remove(task_time)
# Handle IfcRelNests.
if rels := settings["task"].IsNestedBy:
if rels := task.IsNestedBy:
subtasks = rels[0].RelatedObjects
# Use batching for optimization.
ifcopenshell.api.nest.unassign_object(file, subtasks)
for task_ in subtasks:
ifcopenshell.api.sequence.remove_task(file, task=task_)
if settings["task"].Nests:
ifcopenshell.api.nest.unassign_object(file, [settings["task"]])
if task.Nests:
ifcopenshell.api.nest.unassign_object(file, [task])
for inverse in file.get_inverse(settings["task"]):
for inverse in file.get_inverse(task):
if inverse.is_a("IfcRelSequence"):
history = inverse.OwnerHistory
file.remove(inverse)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
elif inverse.is_a("IfcRelAssignsToControl"):
if inverse.RelatingControl == settings["task"] or len(inverse.RelatedObjects) == 1:
if inverse.RelatingControl == task or len(inverse.RelatedObjects) == 1:
history = inverse.OwnerHistory
file.remove(inverse)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
else:
related_objects = list(inverse.RelatedObjects)
related_objects.remove(settings["task"])
related_objects.remove(task)
inverse.RelatedObjects = related_objects
elif inverse.is_a("IfcRelDefinesByProperties"):
ifcopenshell.api.pset.remove_pset(
file,
product=settings["task"],
product=task,
pset=inverse.RelatingPropertyDefinition,
)
elif inverse.is_a("IfcRelAssignsToProcess"):
if inverse.RelatingProcess == settings["task"] or len(inverse.RelatedObjects) == 1:
if inverse.RelatingProcess == task or len(inverse.RelatedObjects) == 1:
history = inverse.OwnerHistory
file.remove(inverse)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
elif inverse.is_a("IfcRelAssignsToProduct"):
if inverse.RelatingProduct == settings["task"] or len(inverse.RelatedObjects) == 1:
if inverse.RelatingProduct == task or len(inverse.RelatedObjects) == 1:
history = inverse.OwnerHistory
file.remove(inverse)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
else:
related_objects = list(inverse.RelatedObjects)
related_objects.remove(settings["task"])
related_objects.remove(task)
inverse.RelatedObjects = related_objects
elif inverse.is_a("IfcRelAssignsToObject"):
if inverse.RelatingObject == settings["task"] or len(inverse.RelatedObjects) == 1:
if inverse.RelatingObject == task or len(inverse.RelatedObjects) == 1:
history = inverse.OwnerHistory
file.remove(inverse)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
else:
related_objects = list(inverse.RelatedObjects)
related_objects.remove(settings["task"])
related_objects.remove(task)
inverse.RelatedObjects = related_objects
elif inverse.is_a("IfcRelAssignsToProcess"):
history = inverse.OwnerHistory
@@ -133,7 +129,7 @@ def remove_task(file: ifcopenshell.file, task: ifcopenshell.entity_instance) ->
if history:
ifcopenshell.util.element.remove_deep2(file, history)
history = settings["task"].OwnerHistory
file.remove(settings["task"])
history = task.OwnerHistory
file.remove(task)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
@@ -23,9 +23,7 @@ def remove_time_period(file: ifcopenshell.file, time_period: ifcopenshell.entity
"""Removes a time period
:param time_period: The IfcTimePeriod to remove.
:type time_period: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
@@ -55,6 +53,4 @@ def remove_time_period(file: ifcopenshell.file, time_period: ifcopenshell.entity
# Let's take the afternoon off!
ifcopenshell.api.sequence.remove_time_period(model, time_period=afternoon)
"""
settings = {"time_period": time_period}
file.remove(settings["time_period"])
file.remove(time_period)
@@ -30,9 +30,7 @@ def remove_work_calendar(file: ifcopenshell.file, work_calendar: ifcopenshell.en
calendar.
:param work_calendar: The IfcWorkCalendar to remove
:type work_calendar: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
@@ -44,32 +42,30 @@ def remove_work_calendar(file: ifcopenshell.file, work_calendar: ifcopenshell.en
# And remove it immediately
ifcopenshell.api.sequence.remove_work_calendar(model, work_calendar=calendar)
"""
settings = {"work_calendar": work_calendar}
# TODO: do a deep purge
ifcopenshell.api.project.unassign_declaration(
file,
definitions=[settings["work_calendar"]],
definitions=[work_calendar],
relating_context=file.by_type("IfcContext")[0],
)
if settings["work_calendar"].Controls:
for rel in settings["work_calendar"].Controls:
if work_calendar.Controls:
for rel in work_calendar.Controls:
for related_object in rel.RelatedObjects:
ifcopenshell.api.control.unassign_control(
file,
relating_control=settings["work_calendar"],
relating_control=work_calendar,
related_object=related_object,
)
# Currently in API work times are created already attached
# to the work calendar, so they are never reused.
for working_time in settings["work_calendar"].WorkingTimes or []:
for working_time in work_calendar.WorkingTimes or []:
ifcopenshell.api.sequence.remove_work_time(file, work_time=working_time)
for exception_time in settings["work_calendar"].ExceptionTimes or []:
for exception_time in work_calendar.ExceptionTimes or []:
ifcopenshell.api.sequence.remove_work_time(file, work_time=exception_time)
history = settings["work_calendar"].OwnerHistory
file.remove(settings["work_calendar"])
history = work_calendar.OwnerHistory
file.remove(work_calendar)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
@@ -29,9 +29,7 @@ def remove_work_plan(file: ifcopenshell.file, work_plan: ifcopenshell.entity_ins
removed.
:param work_plan: The IfcWorkPlan to remove.
:type work_plan: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
@@ -43,11 +41,9 @@ def remove_work_plan(file: ifcopenshell.file, work_plan: ifcopenshell.entity_ins
# And remove it immediately
ifcopenshell.api.sequence.remove_work_plan(model, work_plan=work_plan)
"""
settings = {"work_plan": work_plan}
ifcopenshell.api.project.unassign_declaration(
file,
definitions=[settings["work_plan"]],
definitions=[work_plan],
relating_context=file.by_type("IfcContext")[0],
)
@@ -55,7 +51,7 @@ def remove_work_plan(file: ifcopenshell.file, work_plan: ifcopenshell.entity_ins
if related_objects:
ifcopenshell.api.aggregate.unassign_object(file, related_objects)
history = settings["work_plan"].OwnerHistory
file.remove(settings["work_plan"])
history = work_plan.OwnerHistory
file.remove(work_plan)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
@@ -47,32 +47,30 @@ def remove_work_schedule(file: ifcopenshell.file, work_schedule: ifcopenshell.en
# And remove it immediately
ifcopenshell.api.sequence.remove_work_schedule(model, work_schedule=schedule)
"""
settings = {"work_schedule": work_schedule}
# TODO: do a deep purge
ifcopenshell.api.project.unassign_declaration(
file, definitions=[settings["work_schedule"]], relating_context=file.by_type("IfcContext")[0]
file, definitions=[work_schedule], relating_context=file.by_type("IfcContext")[0]
)
if settings["work_schedule"].Declares:
for rel in settings["work_schedule"].Declares:
for work_schedule in rel.RelatedObjects:
ifcopenshell.api.sequence.remove_work_schedule(file, work_schedule=work_schedule)
if work_schedule.Declares:
for rel in work_schedule.Declares:
for work_schedule_ in rel.RelatedObjects:
ifcopenshell.api.sequence.remove_work_schedule(file, work_schedule=work_schedule_)
# Unassign from work plans.
if settings["work_schedule"].Decomposes:
ifcopenshell.api.aggregate.unassign_object(file, [settings["work_schedule"]])
if work_schedule.Decomposes:
ifcopenshell.api.aggregate.unassign_object(file, [work_schedule])
for inverse in file.get_inverse(settings["work_schedule"]):
for inverse in file.get_inverse(work_schedule):
if inverse.is_a("IfcRelDefinesByObject"):
if inverse.RelatingObject == settings["work_schedule"] or len(inverse.RelatedObjects) == 1:
if inverse.RelatingObject == work_schedule or len(inverse.RelatedObjects) == 1:
history = inverse.OwnerHistory
file.remove(inverse)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
else:
related_objects = list(inverse.RelatedObjects)
related_objects.remove(settings["work_schedule"])
related_objects.remove(work_schedule)
inverse.RelatedObjects = related_objects
elif inverse.is_a("IfcRelAssignsToControl"):
[
@@ -81,7 +79,7 @@ def remove_work_schedule(file: ifcopenshell.file, work_schedule: ifcopenshell.en
if related_object.is_a("IfcTask")
]
history = settings["work_schedule"].OwnerHistory
file.remove(settings["work_schedule"])
history = work_schedule.OwnerHistory
file.remove(work_schedule)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
@@ -31,11 +31,8 @@ def unassign_process(
See ifcopenshell.api.sequence.assign_process for details.
:param relating_process: The IfcTask in the relationship.
:type relating_process: ifcopenshell.entity_instance
:param related_object: The related object.
:type related_object: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
@@ -59,13 +56,8 @@ def unassign_process(
# Change our mind.
ifcopenshell.api.sequence.unassign_process(model, relating_process=task, related_object=wall)
"""
settings = {
"relating_process": relating_process,
"related_object": related_object,
}
for rel in settings["related_object"].HasAssignments or []:
if not rel.is_a("IfcRelAssignsToProcess") or rel.RelatingProcess != settings["relating_process"]:
for rel in related_object.HasAssignments or []:
if not rel.is_a("IfcRelAssignsToProcess") or rel.RelatingProcess != relating_process:
continue
if len(rel.RelatedObjects) == 1:
history = rel.OwnerHistory
@@ -74,7 +66,7 @@ def unassign_process(
ifcopenshell.util.element.remove_deep2(file, history)
return
related_objects = list(rel.RelatedObjects)
related_objects.remove(settings["related_object"])
related_objects.remove(related_object)
rel.RelatedObjects = related_objects
ifcopenshell.api.owner.update_owner_history(file, element=rel)
return rel
@@ -31,11 +31,8 @@ def unassign_product(
See ifcopenshell.api.sequence.assign_product for details.
:param relating_product: The IfcProduct in the relationship.
:type relating_product: ifcopenshell.entity_instance
:param related_object: The IfcTask in the relationship.
:type related_object: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
@@ -59,13 +56,8 @@ def unassign_product(
# Change our mind.
ifcopenshell.api.sequence.unassign_product(relating_product=wall, related_object=task)
"""
settings = {
"relating_product": relating_product,
"related_object": related_object,
}
for rel in settings["related_object"].HasAssignments or []:
if not rel.is_a("IfcRelAssignsToProduct") or rel.RelatingProduct != settings["relating_product"]:
for rel in related_object.HasAssignments or []:
if not rel.is_a("IfcRelAssignsToProduct") or rel.RelatingProduct != relating_product:
continue
if len(rel.RelatedObjects) == 1:
history = rel.OwnerHistory
@@ -74,7 +66,7 @@ def unassign_product(
ifcopenshell.util.element.remove_deep2(file, history)
return
related_objects = list(rel.RelatedObjects)
related_objects.remove(settings["related_object"])
related_objects.remove(related_object)
rel.RelatedObjects = related_objects
ifcopenshell.api.owner.update_owner_history(file, element=rel)
return rel
@@ -28,9 +28,7 @@ def unassign_recurrence_pattern(file: ifcopenshell.file, recurrence_pattern: ifc
or replace IfcTaskTimeRecurring with IfcTaskTime).
:param recurrence_pattern: The IfcRecurrencePattern to remove.
:type recurrence_pattern: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
@@ -50,8 +48,6 @@ def unassign_recurrence_pattern(file: ifcopenshell.file, recurrence_pattern: ifc
# Change our mind, let's just maintain it whenever we feel like it.
ifcopenshell.api.sequence.unassign_recurrence_pattern(recurrence_pattern=pattern)
"""
settings = {"recurrence_pattern": recurrence_pattern}
for time_period in settings["recurrence_pattern"].TimePeriods or []:
for time_period in recurrence_pattern.TimePeriods or []:
file.remove(time_period)
file.remove(settings["recurrence_pattern"])
file.remove(recurrence_pattern)
@@ -29,11 +29,8 @@ def unassign_sequence(
"""Removes a sequence relationship between tasks
:param relating_process: The previous / predecessor task.
:type relating_process: ifcopenshell.entity_instance
:param related_process: The next / successor task.
:type related_process: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
@@ -60,15 +57,10 @@ def unassign_sequence(
ifcopenshell.api.sequence.unassign_sequence(model,
relating_process=zone1, related_process=zone2)
"""
settings = {
"relating_process": relating_process,
"related_process": related_process,
}
for rel in settings["related_process"].IsSuccessorFrom or []:
if rel.RelatingProcess == settings["relating_process"]:
for rel in related_process.IsSuccessorFrom or []:
if rel.RelatingProcess == relating_process:
history = rel.OwnerHistory
file.remove(rel)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
ifcopenshell.api.sequence.cascade_schedule(file, task=settings["related_process"])
ifcopenshell.api.sequence.cascade_schedule(file, task=related_process)