mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-16 21:42:19 +00:00
Write documentation for sequence API module
This commit is contained in:
@@ -69,8 +69,10 @@ class Usecase:
|
|||||||
project = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcProject")
|
project = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcProject")
|
||||||
element = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcSite")
|
element = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcSite")
|
||||||
subelement = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcBuilding")
|
subelement = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcBuilding")
|
||||||
|
|
||||||
# The project contains a site (note that project aggregation is a special case in IFC)
|
# The project contains a site (note that project aggregation is a special case in IFC)
|
||||||
ifcopenshell.api.run("aggregate.assign_object", model, product=element, relating_object=project)
|
ifcopenshell.api.run("aggregate.assign_object", model, product=element, relating_object=project)
|
||||||
|
|
||||||
# The site has a building
|
# The site has a building
|
||||||
ifcopenshell.api.run("aggregate.assign_object", model, product=subelement, relating_object=element)
|
ifcopenshell.api.run("aggregate.assign_object", model, product=subelement, relating_object=element)
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -54,12 +54,12 @@ class Usecase:
|
|||||||
parent_resource=crew, ifc_class="IfcLaborResource")
|
parent_resource=crew, ifc_class="IfcLaborResource")
|
||||||
|
|
||||||
# Labour resource is quantified in terms of time.
|
# Labour resource is quantified in terms of time.
|
||||||
ifcopenshell.api.run("resource.add_resource_quantity", model,
|
quantity = ifcopenshell.api.run("resource.add_resource_quantity", model,
|
||||||
resource=labour, ifc_class="IfcQuantityTime")
|
resource=labour, ifc_class="IfcQuantityTime")
|
||||||
|
|
||||||
# Store the time used in hours
|
# Store the time used in hours
|
||||||
ifcopenshell.api.run("resource.edit_resource_quantity", model,
|
ifcopenshell.api.run("resource.edit_resource_quantity", model,
|
||||||
physical_quantity=time, attributes={"TimeValue": 8.0})
|
physical_quantity=quantity, attributes={"TimeValue": 8.0})
|
||||||
"""
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"resource": resource, "ifc_class": ifc_class}
|
self.settings = {"resource": resource, "ifc_class": ifc_class}
|
||||||
|
|||||||
@@ -43,17 +43,17 @@ class Usecase:
|
|||||||
parent_resource=crew, ifc_class="IfcLaborResource")
|
parent_resource=crew, ifc_class="IfcLaborResource")
|
||||||
|
|
||||||
# Labour resource is quantified in terms of time.
|
# Labour resource is quantified in terms of time.
|
||||||
ifcopenshell.api.run("resource.add_resource_quantity", model,
|
quantity = ifcopenshell.api.run("resource.add_resource_quantity", model,
|
||||||
resource=labour, ifc_class="IfcQuantityTime")
|
resource=labour, ifc_class="IfcQuantityTime")
|
||||||
|
|
||||||
# Store the unit time used in hours
|
# Store the unit time used in hours
|
||||||
ifcopenshell.api.run("resource.edit_resource_quantity", model,
|
ifcopenshell.api.run("resource.edit_resource_quantity", model,
|
||||||
physical_quantity=time, attributes={"TimeValue": 8.0})
|
physical_quantity=quantity, attributes={"TimeValue": 8.0})
|
||||||
|
|
||||||
# Let's imagine we've used the resource for 2 days.
|
# Let's imagine we've used the resource for 2 days.
|
||||||
time = ifcopenshell.api.run("resource.add_resource_time", model, resource=labour)
|
time = ifcopenshell.api.run("resource.add_resource_time", model, resource=labour)
|
||||||
ifcopenshell.api.run("resource.edit_resource_time", model,
|
ifcopenshell.api.run("resource.edit_resource_time", model,
|
||||||
resource_time=time, attributes={"ScheduleWork": "P16H"})
|
resource_time=time, attributes={"ScheduleWork": "PT16H"})
|
||||||
"""
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {
|
||||||
|
|||||||
@@ -21,32 +21,149 @@ import ifcopenshell
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(
|
||||||
|
self,
|
||||||
|
file,
|
||||||
|
work_schedule=None,
|
||||||
|
parent_task=None,
|
||||||
|
name=None,
|
||||||
|
description=None,
|
||||||
|
identification=None,
|
||||||
|
predefined_type="NOTDEFINED",
|
||||||
|
):
|
||||||
|
"""Adds a new task
|
||||||
|
|
||||||
|
Tasks are typically used for two purposes: construction scheduling and
|
||||||
|
facility management.
|
||||||
|
|
||||||
|
In construction scheduling, a task represents a job to be done in a work
|
||||||
|
schedule. Tasks are organised in a hierarchical manner known as a work
|
||||||
|
breakdown structure (WBS) and have lots of sequential relationships
|
||||||
|
(e.g. this task must finish before the next task can start) and date
|
||||||
|
information (e.g. durations, start dates). This is often represented as
|
||||||
|
a gantt chart and used to analyse critical paths to try and reduce
|
||||||
|
project time to stay on-time and within budget.
|
||||||
|
|
||||||
|
In facility management, a task represents a maintenance task to maintain
|
||||||
|
a piece of equipment. Tasks are broken down into a punch list, or simply
|
||||||
|
a bulleted or ordered sequence of tasks to be performed (e.g. turn off
|
||||||
|
equipment, check power connection, etc) in order to maintain the
|
||||||
|
equipment. Tasks will also typically have recurring scheduled dates in
|
||||||
|
line with the maintenance schedule. These maintenance tasks and
|
||||||
|
procedures are typically published as part of an operations and
|
||||||
|
maintenance manual.
|
||||||
|
|
||||||
|
All tasks must be grouped in a work schedule, either directly as a root
|
||||||
|
or top-level task, or indirectly as a child or subtask of a parent task.
|
||||||
|
In construction scheduling, tasks may be nested many times to create the
|
||||||
|
work breakdown structure, and the "leaf" tasks (i.e. tasks with no more
|
||||||
|
subtasks) are considered to be the activities with dates, whereas all
|
||||||
|
parent tasks are part of the breakdown structure used for categorisation
|
||||||
|
purposes. In facility management, top-level tasks represent the overall
|
||||||
|
maintenance job to be performed, and child tasks represent an ordered
|
||||||
|
list of things to do for that maintenance. These form a 2-level
|
||||||
|
hierarchy. No further child tasks are recommended.
|
||||||
|
|
||||||
|
: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.entity_instance
|
||||||
|
: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.entity_instance
|
||||||
|
: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.entity_instance
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's imagine we are creating a construction schedule. All tasks
|
||||||
|
# need to be part of a work schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# Add a root task to represent the design milestones, and major
|
||||||
|
# project phases.
|
||||||
|
ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Milestones", identification="A")
|
||||||
|
ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Design", identification="B")
|
||||||
|
construction = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Construction", identification="C")
|
||||||
|
|
||||||
|
# Let's start creating our work breakdown structure.
|
||||||
|
ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=construction, name="Early Works", identification="C1")
|
||||||
|
ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=construction, name="Substructure", identification="C2")
|
||||||
|
superstructure = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=construction, name="Superstructure", identification="C3")
|
||||||
|
|
||||||
|
# Notice how the leaf task is the actual activity
|
||||||
|
ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=superstructure, name="Ground Floor FRP", identification="C3.1")
|
||||||
|
|
||||||
|
# Let's imagine we are digitising an operations and maintenance
|
||||||
|
# manual for the mechanical discipline.
|
||||||
|
maintenance = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Mechanical Maintenance")
|
||||||
|
|
||||||
|
# Imagine we have to clean the condenser coils for a chiller every
|
||||||
|
# month. Like the schedule above, to keep things simple we won't
|
||||||
|
# show scheduling times and calendars. This root task represents the
|
||||||
|
# overall maintenance task.
|
||||||
|
cleaning = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=maintenance, name="Condenser coil cleaning")
|
||||||
|
|
||||||
|
# These subtasks represent the punch list of maintenance tasks.
|
||||||
|
ifcopenshell.api.run("sequence.add_task", model, parent_task=cleaning, identification="1",
|
||||||
|
description="Prior to work, wear safety shoes, gloves, and goggles.")
|
||||||
|
ifcopenshell.api.run("sequence.add_task", model, parent_task=cleaning, identification="2",
|
||||||
|
description="Prepare jet pump, screwdriver, hose clamp, and control panel door key.")
|
||||||
|
ifcopenshell.api.run("sequence.add_task", model, parent_task=cleaning, identification="3",
|
||||||
|
description="Switch OFF the chiller unit.")
|
||||||
|
ifcopenshell.api.run("sequence.add_task", model, parent_task=cleaning, identification="3",
|
||||||
|
description="Open the isolator switch.")
|
||||||
|
ifcopenshell.api.run("sequence.add_task", model, parent_task=cleaning, identification="3",
|
||||||
|
description="Setup the water pressure by tapping to a water supply and connecting to a ...")
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {
|
||||||
"work_schedule": None,
|
"work_schedule": work_schedule,
|
||||||
"parent_task": None,
|
"parent_task": parent_task,
|
||||||
|
"name": name,
|
||||||
|
"description": description,
|
||||||
|
"identification": identification,
|
||||||
|
"predefined_type": predefined_type,
|
||||||
}
|
}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
task = ifcopenshell.api.run(
|
task = ifcopenshell.api.run(
|
||||||
"root.create_entity",
|
"root.create_entity",
|
||||||
self.file,
|
self.file,
|
||||||
ifc_class="IfcTask",
|
ifc_class="IfcTask",
|
||||||
name=None,
|
name=self.settings["name"],
|
||||||
predefined_type="NOTDEFINED",
|
predefined_type=self.settings["predefined_type"],
|
||||||
)
|
)
|
||||||
|
if self.settings["description"]:
|
||||||
|
task.Description = self.settings["description"]
|
||||||
|
if self.settings["identification"]:
|
||||||
|
task.Identification = self.settings["identification"]
|
||||||
task.IsMilestone = False
|
task.IsMilestone = False
|
||||||
if self.settings["work_schedule"]:
|
if self.settings["work_schedule"]:
|
||||||
self.file.create_entity(
|
self.file.create_entity(
|
||||||
"IfcRelAssignsToControl",
|
"IfcRelAssignsToControl",
|
||||||
**{
|
**{
|
||||||
"GlobalId": ifcopenshell.guid.new(),
|
"GlobalId": ifcopenshell.guid.new(),
|
||||||
"OwnerHistory": ifcopenshell.api.run(
|
"OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", self.file),
|
||||||
"owner.create_owner_history", self.file
|
|
||||||
),
|
|
||||||
"RelatedObjects": [task],
|
"RelatedObjects": [task],
|
||||||
"RelatingControl": self.settings["work_schedule"],
|
"RelatingControl": self.settings["work_schedule"],
|
||||||
}
|
}
|
||||||
@@ -59,9 +176,5 @@ class Usecase:
|
|||||||
relating_object=self.settings["parent_task"],
|
relating_object=self.settings["parent_task"],
|
||||||
)
|
)
|
||||||
if self.settings["parent_task"].Identification:
|
if self.settings["parent_task"].Identification:
|
||||||
task.Identification = (
|
task.Identification = self.settings["parent_task"].Identification + "." + str(len(rel.RelatedObjects))
|
||||||
self.settings["parent_task"].Identification
|
|
||||||
+ "."
|
|
||||||
+ str(len(rel.RelatedObjects))
|
|
||||||
)
|
|
||||||
return task
|
return task
|
||||||
|
|||||||
@@ -16,19 +16,54 @@
|
|||||||
# 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.util.date
|
|
||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, task=None, is_recurring=False):
|
||||||
|
"""Adds a task time to a task
|
||||||
|
|
||||||
|
Some tasks, such as activities within a work breakdown structure or
|
||||||
|
overall maintenance tasks will have time related information. This
|
||||||
|
includes start dates, durations, end dates, and possible recurring times
|
||||||
|
(especially for maintenance tasks).
|
||||||
|
|
||||||
|
:param task: The task to add time data to.
|
||||||
|
:type task: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param is_recurring: Whether or not the time should recur.
|
||||||
|
:type is_recurring: bool
|
||||||
|
:return: The newly created IfcTaskTime.
|
||||||
|
:rtype: ifcopenshell.entity_instance.entity_instance
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's imagine we are creating a construction schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# Create a portion of a work breakdown structure.
|
||||||
|
construction = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Construction", identification="C")
|
||||||
|
superstructure = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=construction, name="Superstructure", identification="C3")
|
||||||
|
task = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=superstructure, name="Ground Floor FRP", identification="C3.1")
|
||||||
|
|
||||||
|
# Add time data. Note that time data is blank by default.
|
||||||
|
time = ifcopenshell.api.run("sequence.add_task_time", model, task=task)
|
||||||
|
|
||||||
|
# Let's say our task starts on the first of January when everybody
|
||||||
|
# is still drunk from the new years celebration, and lasts for 2
|
||||||
|
# days. Note we don't need to specify the end date, as that is
|
||||||
|
# derived from the start plus the duration. In this simple example,
|
||||||
|
# no calendar has been specified, so we are working 24/7. Yikes!
|
||||||
|
ifcopenshell.api.run("sequence.edit_task_time", model,
|
||||||
|
task_time=time, attributes={"ScheduleStart": "2000-01-01", "ScheduleDuration": "P2D"})
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {"task": task, "is_recurring": is_recurring}
|
||||||
"task": None,
|
|
||||||
}
|
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
task_time = self.file.create_entity("IfcTaskTime")
|
if self.settings["is_recurring"]:
|
||||||
|
task_time = self.file.create_entity("IfcTaskTime")
|
||||||
|
else:
|
||||||
|
task_time = self.file.create_entity("IfcTaskTimeRecurring")
|
||||||
self.settings["task"].TaskTime = task_time
|
self.settings["task"].TaskTime = task_time
|
||||||
return task_time
|
return task_time
|
||||||
|
|||||||
@@ -23,15 +23,62 @@ from datetime import timedelta
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, recurrence_pattern=None, start_time=None, end_time=None):
|
||||||
|
"""Adds a time period to a recurrence pattern
|
||||||
|
|
||||||
|
A recurring time may be an all-day event, or only during certain time
|
||||||
|
periods of the day. For example, you might say that every 1st of January
|
||||||
|
recurring is a public holiday, which is an all-day event. Alternatively,
|
||||||
|
you might say that you work every (i.e. recurringly) Monday to Friday,
|
||||||
|
from 9am to 5pm. The 9am to 5pm is the time period.
|
||||||
|
|
||||||
|
There may also be multiple recurrence patterns, such as from 9am to
|
||||||
|
12pm, and then another from 1pm to 5pm (to indicate an hour break for
|
||||||
|
lunch).
|
||||||
|
|
||||||
|
:param recurrence_pattern: The IfcRecurrencePattern to add the time
|
||||||
|
period to. See ifcopenshell.api.sequence.assign_recurrence_pattern.
|
||||||
|
:type recurrence_pattern: ifcopenshell.entity_instance.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.entity_instance
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's create a new calendar.
|
||||||
|
calendar = ifcopenshell.api.run("sequence.add_work_calendar", model)
|
||||||
|
|
||||||
|
# Let's start defining the times that we work during the week.
|
||||||
|
work_time = ifcopenshell.api.run("sequence.add_work_time", model,
|
||||||
|
work_calendar=calendar, time_type="WorkingTimes")
|
||||||
|
|
||||||
|
# We create a weekly recurrence
|
||||||
|
pattern = ifcopenshell.api.run("sequence.assign_recurrence_pattern", model,
|
||||||
|
parent=work_time, recurrence_type="WEEKLY")
|
||||||
|
|
||||||
|
# State that we work from weekdays 1 to 5 (i.e. Monday to Friday)
|
||||||
|
ifcopenshell.api.run("sequence.edit_recurrence_pattern", model,
|
||||||
|
recurrence_pattern=pattern, attributes={"WeekdayComponent": [1, 2, 3, 4, 5]})
|
||||||
|
|
||||||
|
# The morning work session, lunch, then the afternoon work session.
|
||||||
|
ifcopenshell.api.run("sequence.add_time_period", model,
|
||||||
|
recurrence_pattern=pattern, start_time="09:00", end_time="12:00")
|
||||||
|
ifcopenshell.api.run("sequence.add_time_period", model,
|
||||||
|
recurrence_pattern=pattern, start_time="13:00", end_time="17:00")
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {
|
||||||
"recurrence_pattern": None,
|
"recurrence_pattern": recurrence_pattern,
|
||||||
"start_time": None,
|
"start_time": start_time,
|
||||||
"end_time": None,
|
"end_time": end_time,
|
||||||
}
|
}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
time_period = self.file.create_entity("IfcTimePeriod")
|
time_period = self.file.create_entity("IfcTimePeriod")
|
||||||
|
|||||||
@@ -20,11 +20,63 @@ import ifcopenshell.api
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, name="Unnamed", predefined_type="NOTDEFINED"):
|
||||||
|
"""Add a work calendar
|
||||||
|
|
||||||
|
A work calendar defines when work is allowed to occur and when the
|
||||||
|
holidays are. This is a fundamental concept in construction planning.
|
||||||
|
Every task in a work schedule will have an associated calendar. Some
|
||||||
|
task and resources work 24/7, whereas others work Monday to Friday, or
|
||||||
|
5.5 day weeks, etc. This is important, as tasks durations may only occur
|
||||||
|
during working times in a work calendar.
|
||||||
|
|
||||||
|
Work calendars can also be used to associate with events, such as
|
||||||
|
indicating that during certain days and times of the year, motion
|
||||||
|
sensors should turn on the lights, and other smart building controls.
|
||||||
|
|
||||||
|
: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.entity_instance
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's imagine we are creating a construction schedule. All tasks
|
||||||
|
# need to be part of a work schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# Add a root task to represent the construction tasks.
|
||||||
|
task = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Construction", identification="C")
|
||||||
|
|
||||||
|
# Let's create a new calendar.
|
||||||
|
calendar = ifcopenshell.api.run("sequence.add_work_calendar", model, name="5 Day Week")
|
||||||
|
|
||||||
|
# Let's start defining the times that we work during the week.
|
||||||
|
work_time = ifcopenshell.api.run("sequence.add_work_time", model,
|
||||||
|
work_calendar=calendar, time_type="WorkingTimes")
|
||||||
|
|
||||||
|
# We create a weekly recurrence
|
||||||
|
pattern = ifcopenshell.api.run("sequence.assign_recurrence_pattern", model,
|
||||||
|
parent=work_time, recurrence_type="WEEKLY")
|
||||||
|
|
||||||
|
# State that we work from weekdays 1 to 5 (i.e. Monday to Friday), 9am to 5pm
|
||||||
|
ifcopenshell.api.run("sequence.edit_recurrence_pattern", mdoel,
|
||||||
|
recurrence_pattern=pattern, attributes={"WeekdayComponent": [1, 2, 3, 4, 5]})
|
||||||
|
ifcopenshell.api.run("sequence.add_time_period", model,
|
||||||
|
recurrence_pattern=pattern, start_time="09:00", end_time="17:00")
|
||||||
|
|
||||||
|
# We associate the calendar with the construction root task. All
|
||||||
|
# subtasks underneath the construction work task will also inherit
|
||||||
|
# this calendar by default (though you can override them).
|
||||||
|
ifcopenshell.api.run("control.assign_control", model, relating_control=calendar, related_object=task)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"name": "Unnamed", "predefined_type": "NOTDEFINED"}
|
self.settings = {"name": name, "predefined_type": predefined_type}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
work_calendar = ifcopenshell.api.run(
|
work_calendar = ifcopenshell.api.run(
|
||||||
|
|||||||
@@ -22,15 +22,43 @@ from datetime import datetime
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, name=None, predefined_type="NOTDEFINED", start_time=None):
|
||||||
|
"""Add a new work plan
|
||||||
|
|
||||||
|
A work plan is a group of work schedules. Since work schedules may have
|
||||||
|
different purposes, such as for maintenance or construction scheduling,
|
||||||
|
baseline comparison, or phasing, work plans can be used to group related
|
||||||
|
work schedules. At a minimum, it is recommended to use work plans to
|
||||||
|
indicate whether the work schedules are for facility management or for
|
||||||
|
construction scheduling.
|
||||||
|
|
||||||
|
: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.entity_instance
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# This will hold all our construction schedules
|
||||||
|
work_plan = ifcopenshell.api.run("sequence.add_work_plan", model, name="Construction")
|
||||||
|
|
||||||
|
# This is one of our schedules in our work plan.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model,
|
||||||
|
name="Construction Schedule A", work_plan=work_plan)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {
|
||||||
"name": None,
|
"name": name,
|
||||||
"predefined_type": "NOTDEFINED",
|
"predefined_type": predefined_type,
|
||||||
"start_time": datetime.now(),
|
"start_time": start_time or datetime.now(),
|
||||||
}
|
}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
work_plan = ifcopenshell.api.run(
|
work_plan = ifcopenshell.api.run(
|
||||||
|
|||||||
@@ -22,16 +22,55 @@ from datetime import datetime
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, name="Unnamed", predefined_type="NOTDEFINED", start_time=None, work_plan=None):
|
||||||
|
"""Add a new work schedule
|
||||||
|
|
||||||
|
A work schedule is a group of tasks, where the tasks are typically
|
||||||
|
either for maintenance or for construction scheduling.
|
||||||
|
|
||||||
|
:param name: The name of the work schedule.
|
||||||
|
:type name: str
|
||||||
|
:param predefined_type: The type of schedule, chosen from ACTUAL,
|
||||||
|
BASELINE, and PLANNED. Typically you would start with PLANNED, then
|
||||||
|
convert to a BASELINE when changes are made with separate schedules,
|
||||||
|
then have a parallel ACTUAL schedule.
|
||||||
|
:type predefined_type: str
|
||||||
|
:param start_time: The earlier start time when the schedule is relevant.
|
||||||
|
May be represented with an ISO standard string.
|
||||||
|
:type start_time: str,datetime.time,optional
|
||||||
|
:param work_plan: The IfcWorkPlan the schedule will be part of. If not
|
||||||
|
provided, the schedule will not be grouped in a work plan and would
|
||||||
|
exist as a top level schedule in the project. This is not
|
||||||
|
recommended.
|
||||||
|
:type work_plan: ifcopenshell.entity_instance.entity_instance,optional
|
||||||
|
:return: The newly created IfcWorkSchedule
|
||||||
|
:rtype: ifcopenshell.entity_instance.entity_instance
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# This will hold all our construction schedules
|
||||||
|
work_plan = ifcopenshell.api.run("sequence.add_work_plan", model, name="Construction")
|
||||||
|
|
||||||
|
# Let's imagine this is one of our schedules in our work plan.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model,
|
||||||
|
name="Construction Schedule A", work_plan=work_plan)
|
||||||
|
|
||||||
|
# Add a root task to represent the design milestones, and major
|
||||||
|
# project phases.
|
||||||
|
ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Milestones", identification="A")
|
||||||
|
ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Design", identification="B")
|
||||||
|
construction = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Construction", identification="C")
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {
|
||||||
"name": "Unnamed",
|
"name": name,
|
||||||
"predefined_type": "NOTDEFINED",
|
"predefined_type": predefined_type,
|
||||||
"start_time": datetime.now(),
|
"start_time": start_time or datetime.now(),
|
||||||
"work_plan": None,
|
"work_plan": work_plan,
|
||||||
}
|
}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
work_schedule = ifcopenshell.api.run(
|
work_schedule = ifcopenshell.api.run(
|
||||||
|
|||||||
@@ -18,11 +18,57 @@
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, work_calendar=None, time_type="WorkingTimes"):
|
||||||
|
"""Add either working times or holiday times to a calendar
|
||||||
|
|
||||||
|
A calendar defines when work occurs by defining working times and
|
||||||
|
holiday times. First, the working times are defined, then the holidays
|
||||||
|
may override the working times. For this reason, holidays are also known
|
||||||
|
as exception times. For example, you might define the working times as
|
||||||
|
every Monday to Friday, then define a few holidays in the year, such as
|
||||||
|
the 1st of January. If the 1st of January is on a weekday, it will
|
||||||
|
override the work time.
|
||||||
|
|
||||||
|
:param work_calendar: The IfcWorkCalendar to add the work or holiday
|
||||||
|
time definition to.
|
||||||
|
:type work_calendar: ifcopenshell.entity_instance.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.entity_instance
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's create a new calendar.
|
||||||
|
calendar = ifcopenshell.api.run("sequence.add_work_calendar", model)
|
||||||
|
|
||||||
|
# Let's start defining the times that we work during the week.
|
||||||
|
work_time = ifcopenshell.api.run("sequence.add_work_time", model,
|
||||||
|
work_calendar=calendar, time_type="WorkingTimes")
|
||||||
|
|
||||||
|
# We create a weekly recurrence
|
||||||
|
pattern = ifcopenshell.api.run("sequence.assign_recurrence_pattern", model,
|
||||||
|
parent=work_time, recurrence_type="WEEKLY")
|
||||||
|
|
||||||
|
# State that we work from weekdays 1 to 5 (i.e. Monday to Friday)
|
||||||
|
ifcopenshell.api.run("sequence.edit_recurrence_pattern", model,
|
||||||
|
recurrence_pattern=pattern, attributes={"WeekdayComponent": [1, 2, 3, 4, 5]})
|
||||||
|
|
||||||
|
# Let's set some holidays
|
||||||
|
holidays = ifcopenshell.api.run("sequence.add_work_time", model,
|
||||||
|
work_calendar=calendar, time_type="ExceptionTimes")
|
||||||
|
|
||||||
|
# We create a yearly recurrence
|
||||||
|
pattern = ifcopenshell.api.run("sequence.assign_recurrence_pattern", model,
|
||||||
|
parent=work_time, recurrence_type="YEARLY_BY_DAY_OF_MONTH")
|
||||||
|
|
||||||
|
# The holiday is every 1st of January
|
||||||
|
ifcopenshell.api.run("sequence.edit_recurrence_pattern", model,
|
||||||
|
recurrence_pattern=pattern, attributes={"DayComponent": [1], "MonthComponent": [1]})
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"work_calendar": None, "time_type": None}
|
self.settings = {"work_calendar": work_calendar, "time_type": time_type}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
work_time = self.file.create_entity("IfcWorkTime")
|
work_time = self.file.create_entity("IfcWorkTime")
|
||||||
|
|||||||
@@ -20,15 +20,73 @@ import ifcopenshell.util.date
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, rel_sequence=None, lag_value=None, duration_type="WORKTIME"):
|
||||||
|
"""Assign a lag time to a sequence relationship between tasks
|
||||||
|
|
||||||
|
A task sequence (e.g. finish to start) may optionally have a lag time
|
||||||
|
defined. This is a fundamental concept in construction scheduling. The
|
||||||
|
lag is defined as a duration, and the duration is typically either
|
||||||
|
calendar based (i.e. follows the working times and holidays of the
|
||||||
|
calendar) or elapsed time based (i.e. 24/7).
|
||||||
|
|
||||||
|
A sequence may only have a single lag time defined. Negative lag times
|
||||||
|
are allowed.
|
||||||
|
|
||||||
|
:param rel_sequence: The IfcRelSequence to assign the lag time to.
|
||||||
|
:type rel_sequence: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param lag_value: An ISO standardised duration string.
|
||||||
|
:type lag_value: str
|
||||||
|
:param duration_type: Choose from WORKTIME for the associated
|
||||||
|
calendar-based lag times (this is the most common scenario and is
|
||||||
|
recommended as a default), or ELAPSEDTIME to not follow the
|
||||||
|
calendar. You may also choose NOTDEFINED but the behaviour of this
|
||||||
|
is unclear.
|
||||||
|
:type duration_type: str
|
||||||
|
:return: The newly created IfcLagTime
|
||||||
|
:rtype: ifcopenshell.entity_instance.entity_instance
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's imagine we are creating a construction schedule. All tasks
|
||||||
|
# need to be part of a work schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# Let's imagine a root construction task
|
||||||
|
construction = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Construction", identification="C")
|
||||||
|
|
||||||
|
# Let's imagine we're doing a typically formwork, reinforcement,
|
||||||
|
# pour sequence. Let's start with the formwork. It'll take us 2
|
||||||
|
# days.
|
||||||
|
formwork = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=construction, name="Formwork", identification="C.1")
|
||||||
|
time = ifcopenshell.api.run("sequence.add_task_time", model, task=formwork)
|
||||||
|
ifcopenshell.api.run("sequence.edit_task_time", model,
|
||||||
|
task_time=time, attributes={"ScheduleStart": "2000-01-01", "ScheduleDuration": "P2D"})
|
||||||
|
|
||||||
|
# Now let's do the reinforcement. It'll take us another 2 days.
|
||||||
|
reinforcement = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=construction, name="Reinforcement", identification="C.2")
|
||||||
|
time = ifcopenshell.api.run("sequence.add_task_time", model, task=reinforcement)
|
||||||
|
ifcopenshell.api.run("sequence.edit_task_time", model,
|
||||||
|
task_time=time, attributes={"ScheduleStart": "2000-01-01", "ScheduleDuration": "P2D"})
|
||||||
|
|
||||||
|
# Now let's say the formwork must finish before the reinforcement
|
||||||
|
# can start. This is a typical finish to start relationship (FS).
|
||||||
|
sequence = ifcopenshell.api.run("sequence.assign_sequence", model,
|
||||||
|
relating_process=formwork, related_process=reinforcement)
|
||||||
|
|
||||||
|
# Now typically there would be no lag time between formwork and
|
||||||
|
# reinforcement, but let's pretend that we had to allow 1 day gap
|
||||||
|
# for whatever reason.
|
||||||
|
ifcopenshell.api.run("sequence.assign_lag_time", model, rel_sequence=sequence, lag_value="P1D")
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {
|
||||||
"rel_sequence": None,
|
"rel_sequence": rel_sequence,
|
||||||
"lag_value": None,
|
"lag_value": lag_value,
|
||||||
"duration_type": "NOTDEFINED",
|
"duration_type": duration_type,
|
||||||
}
|
}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
lag_value = self.file.createIfcDuration(
|
lag_value = self.file.createIfcDuration(
|
||||||
|
|||||||
@@ -21,21 +21,82 @@ import ifcopenshell.api
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, relating_process=None, related_object=None):
|
||||||
|
"""Assigns an object to be related to a process, typically a construction task
|
||||||
|
|
||||||
|
Processes work using the ICOM (Input, Controls, Outputs, Mechanisms)
|
||||||
|
paradigm in IFC. This process model is commonly used in modeling
|
||||||
|
manufacturing functions.
|
||||||
|
|
||||||
|
For example, processes (such as tasks) consume Inputs and transform them
|
||||||
|
into Outputs. The process may only occur within the limits of Controls
|
||||||
|
(e.g. cost items) and may require Mechanisms (ISO9000 calls them
|
||||||
|
Mechanisms, whereas IFC calls them resources, such as raw materials,
|
||||||
|
labour, or equipment).
|
||||||
|
|
||||||
|
+----------+
|
||||||
|
| Controls |
|
||||||
|
+----------+
|
||||||
|
|
|
||||||
|
V
|
||||||
|
+--------+ +---------+ +---------+
|
||||||
|
| Inputs | --> | Process | --> | Outputs |
|
||||||
|
+--------+ +---------+ +---------+
|
||||||
|
^
|
||||||
|
|
|
||||||
|
+-----------+
|
||||||
|
| Resources |
|
||||||
|
+-----------+
|
||||||
|
|
||||||
|
There are three main scenarios where an object may be related to a
|
||||||
|
task: defining inputs, controls, and resources of a process.
|
||||||
|
|
||||||
|
For inputs, a product (i.e. wall) may be defined as an input to a task,
|
||||||
|
such as when the task is to demolish the wall (i.e. the wall is an
|
||||||
|
input, and there is no output).
|
||||||
|
|
||||||
|
For controls, a cost item may be defined as a control to a task.
|
||||||
|
|
||||||
|
For resources, any construction resource may be assigned to a task.
|
||||||
|
|
||||||
|
:param relating_process: The IfcProcess (typically IfcTask) that the
|
||||||
|
input, control, or resource is related to.
|
||||||
|
:type relating_process: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param related_object: The IfcProduct (for input), IfcCostItem (for
|
||||||
|
control) or IfcConstructionResource (for resource).
|
||||||
|
:type related_object: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: The newly created IfcRelAssignsToProcess relationship
|
||||||
|
:rtype: ifcopenshell.entity_instance.entity_instance
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's imagine we are creating a construction schedule. All tasks
|
||||||
|
# need to be part of a work schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# Let's create a construction task. Note that the predefined type is
|
||||||
|
# important to distinguish types of tasks.
|
||||||
|
task = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Demolish existing", identification="A", predefined_type="DEMOLITION")
|
||||||
|
|
||||||
|
# Let's say we have a wall somewhere.
|
||||||
|
wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall")
|
||||||
|
|
||||||
|
# Let's demolish that wall!
|
||||||
|
ifcopenshell.api.run("sequence.assign_process", model, relating_process=task, related_object=wall)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {
|
||||||
"relating_process": None,
|
"relating_process": relating_process,
|
||||||
"related_object": None,
|
"related_object": related_object,
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
if self.settings["related_object"].HasAssignments:
|
if self.settings["related_object"].HasAssignments:
|
||||||
for assignment in self.settings["related_object"].HasAssignments:
|
for assignment in self.settings["related_object"].HasAssignments:
|
||||||
if (
|
if (
|
||||||
assignment.is_a("IfclRelAssignsToProcess")
|
assignment.is_a("IfcRelAssignsToProcess")
|
||||||
and assignment.RelatingProcess == self.settings["relating_process"]
|
and assignment.RelatingProcess == self.settings["relating_process"]
|
||||||
):
|
):
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -21,14 +21,51 @@ import ifcopenshell.api
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, relating_product=None, related_object=None):
|
||||||
|
"""Assigns a product to be produced as a result of a process
|
||||||
|
|
||||||
|
A construction task may result in products (e.g. a wall) being
|
||||||
|
constructed. These task "Outputs" are defined in IFC through product
|
||||||
|
relationships.
|
||||||
|
|
||||||
|
Not all tasks have Outputs. For example, maintenance tasks will
|
||||||
|
typically not have any outputs.
|
||||||
|
|
||||||
|
See ifcopenshell.api.sequence.assign_process for Inputs and other types
|
||||||
|
of process relationships that can be described in manufacturing
|
||||||
|
process modeling.
|
||||||
|
|
||||||
|
:param relating_product: The IfcProduct that was constructed as a result
|
||||||
|
of the task.
|
||||||
|
:type relating_product: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param related_object: The IfcProcess (typically IfcTask) of the
|
||||||
|
construction task.
|
||||||
|
:type related_object: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: The newly created IfcRelAssignsToProduct relationship
|
||||||
|
:rtype: ifcopenshell.entity_instance.entity_instance
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's imagine we are creating a construction schedule. All tasks
|
||||||
|
# need to be part of a work schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# Let's create a construction task. Note that the predefined type is
|
||||||
|
# important to distinguish types of tasks.
|
||||||
|
task = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Build wall", identification="A", predefined_type="CONSTRUCTION")
|
||||||
|
|
||||||
|
# Let's say we have a wall somewhere.
|
||||||
|
wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall")
|
||||||
|
|
||||||
|
# Let's construct that wall!
|
||||||
|
ifcopenshell.api.run("sequence.assign_product", relating_product=wall, related_object=task)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {
|
||||||
"relating_product": None,
|
"relating_product": relating_product,
|
||||||
"related_object": None,
|
"related_object": related_object,
|
||||||
}
|
}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
if self.settings["related_object"].HasAssignments:
|
if self.settings["related_object"].HasAssignments:
|
||||||
|
|||||||
@@ -18,11 +18,91 @@
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, parent=None, recurrence_type="WEEKLY"):
|
||||||
|
"""Define a time to recur at a particular interval
|
||||||
|
|
||||||
|
There are two scenarios where you might want to define a recurring time
|
||||||
|
pattern.
|
||||||
|
|
||||||
|
You might want a task to be scheduled at a recurring interval,
|
||||||
|
this is common for maintenance tasks which need to be performed monthly,
|
||||||
|
every 6 months, every year, etc.
|
||||||
|
|
||||||
|
Alternatively, you might be defining a work calendar, which defines
|
||||||
|
working days or holidays. The working days might be every week from
|
||||||
|
monday to friday ("every" week means it recurs every week), or the
|
||||||
|
holidays might be the same every year.
|
||||||
|
|
||||||
|
The types of recurrence are:
|
||||||
|
|
||||||
|
- DAILY: every Nth (interval) day for up to X (Occurrences) occurrences.
|
||||||
|
e.g. Every day, every 2 days, every day up to 5 times, etc
|
||||||
|
- WEEKLY: every Nth (interval) MTWTFSS (WeekdayComponent) for up to X
|
||||||
|
(Occurrences) occurrences. e.g. Every Monday, every weekday, every
|
||||||
|
other saturday, etc
|
||||||
|
- MONTHLY_BY_DAY_OF_MONTH: every Nth (DayComponent) of every Xth
|
||||||
|
(Interval) Month up to Y (Occurrences) occurrences. e.g. Every 15th of
|
||||||
|
the Month.
|
||||||
|
- MONTHLY_BY_POSITION: Every Nth (Position) MTWTFSS (WeekdayComponent)
|
||||||
|
of every Xth (Interval) Month up to Y (Occurrences) occurrences. e.g.
|
||||||
|
Every second Tuesday of the Month.
|
||||||
|
- YEARLY_BY_DAY_OF_MONTH: every Nth (DayComponent) of every JFMAMJJASOND
|
||||||
|
(MonthComponent) month of every Yth (Interval) Year up to Z
|
||||||
|
(Occurrences) occurrences. e.g. every 25th of December.
|
||||||
|
- YEARLY_BY_POSITION: every Nth (Position) MTWTFSS (WeekdayComponent) of
|
||||||
|
every JFMAMJJASOND (MonthComponent) month of every Yth (Interval)
|
||||||
|
Year up to Z (Occurrences) occurrences. e.g. every third Wednesday
|
||||||
|
of January.
|
||||||
|
|
||||||
|
These recurrence patterns are fairly standard in all calendar and
|
||||||
|
scheduling applications.
|
||||||
|
|
||||||
|
:param parent: Either an IfcTaskTimeRecurring if you are defining a
|
||||||
|
recurring schedule for a task, or IfcWorkTime if you are defining a
|
||||||
|
recurring pattern for a workdays or holidays in a calendar.
|
||||||
|
:type parent: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param recurrence_type: One of the types of recurrences.
|
||||||
|
:type recurrence_type: str
|
||||||
|
:return: The newly created IfcRecurrencePattern
|
||||||
|
:rtype: ifcopenshell.entity_instance.entity_instance
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's create a new calendar.
|
||||||
|
calendar = ifcopenshell.api.run("sequence.add_work_calendar", model)
|
||||||
|
|
||||||
|
# Let's start defining the times that we work during the week.
|
||||||
|
work_time = ifcopenshell.api.run("sequence.add_work_time", model,
|
||||||
|
work_calendar=calendar, time_type="WorkingTimes")
|
||||||
|
|
||||||
|
# We create a weekly recurrence
|
||||||
|
pattern = ifcopenshell.api.run("sequence.assign_recurrence_pattern", model,
|
||||||
|
parent=work_time, recurrence_type="WEEKLY")
|
||||||
|
|
||||||
|
# State that we work from weekdays 1 to 5 (i.e. Monday to Friday)
|
||||||
|
ifcopenshell.api.run("sequence.edit_recurrence_pattern", model,
|
||||||
|
recurrence_pattern=pattern, attributes={"WeekdayComponent": [1, 2, 3, 4, 5]})
|
||||||
|
|
||||||
|
# Let's imagine we are creating a maintenance schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Equipment Maintenance")
|
||||||
|
|
||||||
|
# Now let's imagine we have a task to maintain the chillers
|
||||||
|
task = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Chiller maintenance")
|
||||||
|
|
||||||
|
# Because it is a maintenance task, we must schedule a recurring time
|
||||||
|
time = ifcopenshell.api.run("sequence.add_task_time", model, task=task, is_recurring=True)
|
||||||
|
|
||||||
|
# We create a monthly recurrence
|
||||||
|
pattern = ifcopenshell.api.run("sequence.assign_recurrence_pattern", model,
|
||||||
|
parent=work_time, recurrence_type="MONTHLY_BY_DAY_OF_MONTH")
|
||||||
|
|
||||||
|
# Specifically, the maintenance task must occur every 6 months
|
||||||
|
ifcopenshell.api.run("sequence.edit_recurrence_pattern", model,
|
||||||
|
recurrence_pattern=pattern, attributes={"DayComponent": [1], "Interval": 6})
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"parent": None, "recurrence_type": "WEEKLY"}
|
self.settings = {"parent": parent, "recurrence_type": recurrence_type}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
recurrence = self.file.createIfcRecurrencePattern(
|
recurrence = self.file.createIfcRecurrencePattern(
|
||||||
|
|||||||
@@ -21,14 +21,92 @@ import ifcopenshell.api
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, relating_process=None, related_process=None, sequence_type="FINISH_START"):
|
||||||
|
"""Assign a sequential relationship between tasks
|
||||||
|
|
||||||
|
Tasks in construction sequencing typically have sequence relationships
|
||||||
|
between them, indicating that one task must happen after another. This
|
||||||
|
is used to automatically compute new start and end dates and cascade
|
||||||
|
changes when dates are changed. This is also used to calculate critical
|
||||||
|
paths and floats.
|
||||||
|
|
||||||
|
There are four types of sequence relationships, known as finish to
|
||||||
|
start, finish to finish, start to start, and start to finish, sometimes
|
||||||
|
abbreviated as a (FS, FF, SS, and SF). The most common is the finish to
|
||||||
|
start relationship, indicating that the previous task must finish before
|
||||||
|
the next task can start.
|
||||||
|
|
||||||
|
You must not create cyclical task sequences. This makes the computer
|
||||||
|
unhappy.
|
||||||
|
|
||||||
|
Note that "previous" or "next" does not necessarily mean the task
|
||||||
|
chronologically happens before or after. They simply indicate the order
|
||||||
|
of the sequence relationship. For this reason, they are often called
|
||||||
|
predecessor and successor tasks in the planning profession.
|
||||||
|
|
||||||
|
:param relating_process: The previous / predecessor task.
|
||||||
|
:type relating_process: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param related_process: The next / successor task.
|
||||||
|
:type related_process: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param sequence_type: Choose from FINISH_START, FINISH_FINISH,
|
||||||
|
START_START, or START_FINISH.
|
||||||
|
:return: The newly created IfcRelSequence
|
||||||
|
:rtype: ifcopenshell.entity_instance.entity_instance
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's imagine we are creating a construction schedule. All tasks
|
||||||
|
# need to be part of a work schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# Let's imagine a root construction task
|
||||||
|
construction = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Construction", identification="C")
|
||||||
|
|
||||||
|
# Let's imagine we're doing a typically formwork, reinforcement,
|
||||||
|
# pour sequence. Let's start with the formwork. It'll take us 2
|
||||||
|
# days.
|
||||||
|
formwork = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=construction, name="Formwork", identification="C.1")
|
||||||
|
time = ifcopenshell.api.run("sequence.add_task_time", model, task=formwork)
|
||||||
|
ifcopenshell.api.run("sequence.edit_task_time", model,
|
||||||
|
task_time=time, attributes={"ScheduleStart": "2000-01-01", "ScheduleDuration": "P2D"})
|
||||||
|
|
||||||
|
# Now let's do the reinforcement. It'll take us another 2 days.
|
||||||
|
reinforcement = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=construction, name="Reinforcement", identification="C.2")
|
||||||
|
time = ifcopenshell.api.run("sequence.add_task_time", model, task=reinforcement)
|
||||||
|
ifcopenshell.api.run("sequence.edit_task_time", model,
|
||||||
|
task_time=time, attributes={"ScheduleStart": "2000-01-01", "ScheduleDuration": "P2D"})
|
||||||
|
|
||||||
|
# Now the pour itself. It'll only take 1 day.
|
||||||
|
pour = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=construction, name="Reinforcement", identification="C.3")
|
||||||
|
time = ifcopenshell.api.run("sequence.add_task_time", model, task=pour)
|
||||||
|
ifcopenshell.api.run("sequence.edit_task_time", model,
|
||||||
|
task_time=time, attributes={"ScheduleStart": "2000-01-01", "ScheduleDuration": "P1D"})
|
||||||
|
|
||||||
|
# Now let's say the formwork must finish before the reinforcement
|
||||||
|
# can start, and the reinforcement must finish before the pour can
|
||||||
|
# start. This is a typical finish to start relationship (FS).
|
||||||
|
ifcopenshell.api.run("sequence.assign_sequence", model,
|
||||||
|
relating_process=formwork, related_process=reinforcement)
|
||||||
|
ifcopenshell.api.run("sequence.assign_sequence", model,
|
||||||
|
relating_process=reinforcement, related_process=pour)
|
||||||
|
|
||||||
|
# Notice how we set all the scheduled start dates arbitrarily at
|
||||||
|
# 2000-01-01. This is because we can ask IfcOpenShell to
|
||||||
|
# automatically cascade the dates, starting from any task. This will
|
||||||
|
# update the reinforcement date to be 2000-01-03 and the pour date
|
||||||
|
# to be 2000-01-05.
|
||||||
|
ifcopenshell.api.run("sequence.cascade_schedule", model, task=formwork)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {
|
||||||
"relating_process": None,
|
"relating_process": relating_process,
|
||||||
"related_process": None,
|
"related_process": related_process,
|
||||||
|
"sequence_type": sequence_type,
|
||||||
}
|
}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
for rel in self.settings["related_process"].IsSuccessorFrom or []:
|
for rel in self.settings["related_process"].IsSuccessorFrom or []:
|
||||||
@@ -38,11 +116,9 @@ class Usecase:
|
|||||||
"IfcRelSequence",
|
"IfcRelSequence",
|
||||||
**{
|
**{
|
||||||
"GlobalId": ifcopenshell.guid.new(),
|
"GlobalId": ifcopenshell.guid.new(),
|
||||||
"OwnerHistory": ifcopenshell.api.run(
|
"OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", self.file),
|
||||||
"owner.create_owner_history", self.file
|
|
||||||
),
|
|
||||||
"RelatingProcess": self.settings["relating_process"],
|
"RelatingProcess": self.settings["relating_process"],
|
||||||
"RelatedProcess": self.settings["related_process"],
|
"RelatedProcess": self.settings["related_process"],
|
||||||
"SequenceType": "FINISH_START",
|
"SequenceType": self.settings["sequence_type"],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -21,11 +21,33 @@ import ifcopenshell.api
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, work_schedule=None, work_plan=None):
|
||||||
|
"""Assigns a work schedule to a work plan
|
||||||
|
|
||||||
|
Typically, work schedules would be assigned to a work plan at creation.
|
||||||
|
However you may also delay this and do it manually afterwards.
|
||||||
|
|
||||||
|
:param work_schedule: The IfcWorkSchedule that will be assigned to the
|
||||||
|
work plan.
|
||||||
|
:type work_schedule: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param work_plan: The IfcWorkPlan for the schedule to be assigned to.
|
||||||
|
:type work_plan: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: The IfcRelAggregates relationship
|
||||||
|
:rtype: ifcopenshell.entity_instance.entity_instance
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# This will hold all our construction schedules
|
||||||
|
work_plan = ifcopenshell.api.run("sequence.add_work_plan", model, name="Construction")
|
||||||
|
|
||||||
|
# Alternatively, if you create a schedule without a work plan ...
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# ... you can assign the work plan afterwards.
|
||||||
|
ifcopenshell.api.run("sequence.assign_workplan", work_schedule=schedule, work_plan=work_plan)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"work_schedule": None, "work_plan": None}
|
self.settings = {"work_schedule": work_schedule, "work_plan": work_plan}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
# TODO: this is an ambiguity by buildingSMART
|
# TODO: this is an ambiguity by buildingSMART
|
||||||
|
|||||||
@@ -23,11 +23,64 @@ import ifcopenshell.util.element
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, task=None):
|
||||||
|
"""Calculates the task duration based on resource usage
|
||||||
|
|
||||||
|
If a task has labour or equipment resources assigned to it, its duration
|
||||||
|
may be parametrically derived from the scheduled work of the resource.
|
||||||
|
For example, a labour resource with scheduled work of 10 working days
|
||||||
|
and a resource utilisation of 200% (i.e. two labour teams) will imply
|
||||||
|
that the task duration is 5 working days.
|
||||||
|
|
||||||
|
If this data is not available, such as if the task has no resources,
|
||||||
|
then nothing happens.
|
||||||
|
|
||||||
|
:param task: The IfcTask to calculate the duration for.
|
||||||
|
:type task: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Add our own crew
|
||||||
|
crew = ifcopenshell.api.run("resource.add_resource", model, ifc_class="IfcCrewResource")
|
||||||
|
|
||||||
|
# Add some labour to our crew.
|
||||||
|
labour = ifcopenshell.api.run("resource.add_resource", model,
|
||||||
|
parent_resource=crew, ifc_class="IfcLaborResource")
|
||||||
|
|
||||||
|
# Labour resource is quantified in terms of time.
|
||||||
|
quantity = ifcopenshell.api.run("resource.add_resource_quantity", model,
|
||||||
|
resource=labour, ifc_class="IfcQuantityTime")
|
||||||
|
|
||||||
|
# Store the unit time used in hours
|
||||||
|
ifcopenshell.api.run("resource.edit_resource_quantity", model,
|
||||||
|
physical_quantity=quantity, attributes={"TimeValue": 8.0})
|
||||||
|
|
||||||
|
# Let's imagine we've used the resource for 10 days with a
|
||||||
|
# utilisation of 200%.
|
||||||
|
time = ifcopenshell.api.run("resource.add_resource_time", model, resource=labour)
|
||||||
|
ifcopenshell.api.run("resource.edit_resource_time", model,
|
||||||
|
resource_time=time, attributes={"ScheduleWork": "PT80H", "ScheduleUsage": 2})
|
||||||
|
|
||||||
|
# Let's imagine we are creating a construction schedule. All tasks
|
||||||
|
# need to be part of a work schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# Let's create a construction task. Note that the predefined type is
|
||||||
|
# important to distinguish types of tasks.
|
||||||
|
task = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Foundations", identification="A")
|
||||||
|
|
||||||
|
# Assign our resource to the task.
|
||||||
|
ifcopenshell.api.run("sequence.assign_process", model, relating_process=task, related_object=labour)
|
||||||
|
|
||||||
|
# Now we can calculate the task duration based on the resource. This
|
||||||
|
# will set task.TaskTime.ScheduleDuration to be P5D.
|
||||||
|
ifcopenshell.api.run("sequence.calculate_task_duration", model, task=task)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"task": None}
|
self.settings = {"task": task}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
self.seconds_per_workday = self.calculate_seconds_per_workday()
|
self.seconds_per_workday = self.calculate_seconds_per_workday()
|
||||||
|
|||||||
@@ -22,11 +22,86 @@ import ifcopenshell.util.sequence
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, task=None):
|
||||||
|
"""Cascades start and end dates of tasks based on durations
|
||||||
|
|
||||||
|
Given a start task with a start date and duration, the end date, and the
|
||||||
|
start and end of all successor tasks with durations may be automatically
|
||||||
|
computed.
|
||||||
|
|
||||||
|
Using this automatic computation is recommended is an alternative to
|
||||||
|
manually specifying dates. It is useful for doing edits and cascading
|
||||||
|
changes.
|
||||||
|
|
||||||
|
Dates can only cascade from predecessor to successors, not backwards.
|
||||||
|
Cyclical relationships are invalid and will result in a recursion error
|
||||||
|
being raised.
|
||||||
|
|
||||||
|
Note that there may be differences between how different planning
|
||||||
|
software calculate start and end dates. Some may consider Monday 5pm to
|
||||||
|
be equivalent to be Tuesday 8am, for instance.
|
||||||
|
|
||||||
|
:param task: The start task to begin cascading from.
|
||||||
|
:type task: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Define a convenience function to add a task chained to a predecessor
|
||||||
|
def add_task(model, name, predecessor, work_schedule):
|
||||||
|
# Add a construction task
|
||||||
|
task = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=work_schedule, name=name, predefined_type="CONSTRUCTION")
|
||||||
|
|
||||||
|
# Give it a time
|
||||||
|
task_time = ifcopenshell.api.run("sequence.add_task_time", model, task=task)
|
||||||
|
|
||||||
|
# Arbitrarily set the task's scheduled time duration to be 1 week
|
||||||
|
ifcopenshell.api.run("sequence.edit_task_time", model, task_time=task_time,
|
||||||
|
attributes={"ScheduleStart": datetime.date(2000, 1, 1), "ScheduleDuration": "P1W"})
|
||||||
|
|
||||||
|
# If a predecessor exists, create a finish to start relationship
|
||||||
|
if predecessor:
|
||||||
|
ifcopenshell.api.run("sequence.assign_sequence", model,
|
||||||
|
relating_process=predecessor, related_process=task)
|
||||||
|
|
||||||
|
return task
|
||||||
|
|
||||||
|
# Open an existing IFC4 model you have of a building
|
||||||
|
model = ifcopenshell.open("/path/to/existing/model.ifc")
|
||||||
|
|
||||||
|
# Create a new construction schedule
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction")
|
||||||
|
|
||||||
|
# Let's imagine a starting task for site establishment.
|
||||||
|
task = add_task(model, "Site establishment", None, schedule)
|
||||||
|
start_task = task
|
||||||
|
|
||||||
|
# Get all our storeys sorted by elevation ascending.
|
||||||
|
storeys = sorted(model.by_type("IfcBuildingStorey"), key=lambda s: get_storey_elevation(s))
|
||||||
|
|
||||||
|
# For each storey ...
|
||||||
|
for storey in storeys:
|
||||||
|
|
||||||
|
# Add a construction task to construct that storey, using our convenience function
|
||||||
|
task = add_task(model, f"Construct {storey.Name}", task, schedule)
|
||||||
|
|
||||||
|
# Assign all the products in that storey to the task as construction outputs.
|
||||||
|
for product in get_decomposition(storey):
|
||||||
|
ifcopenshell.api.run("sequence.assign_product", model, relating_product=product, related_object=task)
|
||||||
|
|
||||||
|
# Ask the computer to calculate all the dates for us from the start task.
|
||||||
|
# For example, if the first task started on the 1st of January and took a
|
||||||
|
# week, the next task will start on the 8th of January. This saves us
|
||||||
|
# manually doing date calculations.
|
||||||
|
ifcopenshell.api.run("sequence.cascade_schedule", model, task=start_task)
|
||||||
|
|
||||||
|
# Calculate the critical path and floats.
|
||||||
|
ifcopenshell.api.run("sequence.recalculate_schedule", model, work_schedule=schedule)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"task": None}
|
self.settings = {"task": task}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
self.calendar_cache = {}
|
self.calendar_cache = {}
|
||||||
|
|||||||
@@ -21,11 +21,60 @@ import ifcopenshell.util.date
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, lag_time=None, attributes=None):
|
||||||
|
"""Edits the attributes of an IfcLagTime
|
||||||
|
|
||||||
|
For more information about the attributes and data types of an
|
||||||
|
IfcLagTime, consult the IFC documentation.
|
||||||
|
|
||||||
|
:param lag_time: The IfcLagTime entity you want to edit
|
||||||
|
:type lag_time: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param attributes: a dictionary of attribute names and values.
|
||||||
|
:type attributes: dict, optional
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's imagine we are creating a construction schedule. All tasks
|
||||||
|
# need to be part of a work schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# Let's imagine a root construction task
|
||||||
|
construction = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Construction", identification="C")
|
||||||
|
|
||||||
|
# Let's imagine we're doing a typically formwork, reinforcement,
|
||||||
|
# pour sequence. Let's start with the formwork. It'll take us 2
|
||||||
|
# days.
|
||||||
|
formwork = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=construction, name="Formwork", identification="C.1")
|
||||||
|
time = ifcopenshell.api.run("sequence.add_task_time", model, task=formwork)
|
||||||
|
ifcopenshell.api.run("sequence.edit_task_time", model,
|
||||||
|
task_time=time, attributes={"ScheduleStart": "2000-01-01", "ScheduleDuration": "P2D"})
|
||||||
|
|
||||||
|
# Now let's do the reinforcement. It'll take us another 2 days.
|
||||||
|
reinforcement = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=construction, name="Reinforcement", identification="C.2")
|
||||||
|
time = ifcopenshell.api.run("sequence.add_task_time", model, task=reinforcement)
|
||||||
|
ifcopenshell.api.run("sequence.edit_task_time", model,
|
||||||
|
task_time=time, attributes={"ScheduleStart": "2000-01-01", "ScheduleDuration": "P2D"})
|
||||||
|
|
||||||
|
# Now let's say the formwork must finish before the reinforcement
|
||||||
|
# can start. This is a typical finish to start relationship (FS).
|
||||||
|
sequence = ifcopenshell.api.run("sequence.assign_sequence", model,
|
||||||
|
relating_process=formwork, related_process=reinforcement)
|
||||||
|
|
||||||
|
# Now typically there would be no lag time between formwork and
|
||||||
|
# reinforcement, but let's pretend that we had to allow 1 day gap
|
||||||
|
# for whatever reason.
|
||||||
|
lag = ifcopenshell.api.run("sequence.assign_lag_time", model, rel_sequence=sequence, lag_value="P1D")
|
||||||
|
|
||||||
|
# Or, let's make it 2 days instead.
|
||||||
|
ifcopenshell.api.run("sequence.edit_lag_time", model, lag_time=lag, attributes={"LagValue": "P2D"})
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"lag_time": None, "attributes": {}}
|
self.settings = {"lag_time": lag_time, "attributes": attributes or {}}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
for name, value in self.settings["attributes"].items():
|
for name, value in self.settings["attributes"].items():
|
||||||
|
|||||||
@@ -18,11 +18,38 @@
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, recurrence_pattern=None, attributes=None):
|
||||||
|
"""Edits the attributes of an IfcRecurrencePattern
|
||||||
|
|
||||||
|
For more information about the attributes and data types of an
|
||||||
|
IfcRecurrencePattern, consult the IFC documentation.
|
||||||
|
|
||||||
|
:param recurrence_pattern: The IfcRecurrencePattern entity you want to edit
|
||||||
|
:type recurrence_pattern: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param attributes: a dictionary of attribute names and values.
|
||||||
|
:type attributes: dict, optional
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's create a new calendar.
|
||||||
|
calendar = ifcopenshell.api.run("sequence.add_work_calendar", model)
|
||||||
|
|
||||||
|
# Let's start defining the times that we work during the week.
|
||||||
|
work_time = ifcopenshell.api.run("sequence.add_work_time", model,
|
||||||
|
work_calendar=calendar, time_type="WorkingTimes")
|
||||||
|
|
||||||
|
# We create a weekly recurrence
|
||||||
|
pattern = ifcopenshell.api.run("sequence.assign_recurrence_pattern", model,
|
||||||
|
parent=work_time, recurrence_type="WEEKLY")
|
||||||
|
|
||||||
|
# State that we work from weekdays 1 to 5 (i.e. Monday to Friday)
|
||||||
|
ifcopenshell.api.run("sequence.edit_recurrence_pattern", model,
|
||||||
|
recurrence_pattern=pattern, attributes={"WeekdayComponent": [1, 2, 3, 4, 5]})
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"recurrence_pattern": None, "attributes": {}}
|
self.settings = {"recurrence_pattern": recurrence_pattern, "attributes": attributes or {}}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
for name, value in self.settings["attributes"].items():
|
for name, value in self.settings["attributes"].items():
|
||||||
|
|||||||
@@ -21,11 +21,45 @@ import ifcopenshell.api
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, rel_sequence=None, attributes=None):
|
||||||
|
"""Edits the attributes of an IfcRelSequence
|
||||||
|
|
||||||
|
For more information about the attributes and data types of an
|
||||||
|
IfcRelSequence, consult the IFC documentation.
|
||||||
|
|
||||||
|
:param rel_sequence: The IfcRelSequence entity you want to edit
|
||||||
|
:type rel_sequence: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param attributes: a dictionary of attribute names and values.
|
||||||
|
:type attributes: dict, optional
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's imagine we are creating a construction schedule. All tasks
|
||||||
|
# need to be part of a work schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# Let's imagine a root construction task
|
||||||
|
construction = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Construction", identification="C")
|
||||||
|
|
||||||
|
# Let's imagine we're building 2 zones, one after another.
|
||||||
|
zone1 = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=construction, name="Zone 1", identification="C.1")
|
||||||
|
zone2 = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=construction, name="Zone 2", identification="C.2")
|
||||||
|
|
||||||
|
# Zone 1 finishes, then zone 2 starts.
|
||||||
|
sequence = ifcopenshell.api.run("sequence.assign_sequence", model,
|
||||||
|
relating_process=zone1, related_process=zone2)
|
||||||
|
|
||||||
|
# What if they both started at the same time?
|
||||||
|
ifcopenshell.api.run("sequence.edit_sequence", model,
|
||||||
|
rel_sequence=sequence, attributes={"SequenceType": "START_START"})
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"rel_sequence": None, "attributes": {}}
|
self.settings = {"rel_sequence": rel_sequence, "attributes": attributes or {}}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
for name, value in self.settings["attributes"].items():
|
for name, value in self.settings["attributes"].items():
|
||||||
|
|||||||
@@ -18,11 +18,35 @@
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, task=None, attributes=None):
|
||||||
|
"""Edits the attributes of an IfcTask
|
||||||
|
|
||||||
|
For more information about the attributes and data types of an
|
||||||
|
IfcTask, consult the IFC documentation.
|
||||||
|
|
||||||
|
:param task: The IfcTask entity you want to edit
|
||||||
|
:type task: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param attributes: a dictionary of attribute names and values.
|
||||||
|
:type attributes: dict, optional
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's imagine we are creating a construction schedule. All tasks
|
||||||
|
# need to be part of a work schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# Add a root task to represent the design milestones, and major
|
||||||
|
# project phases.
|
||||||
|
task = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Milestones", identification="A")
|
||||||
|
|
||||||
|
# Change the identification
|
||||||
|
ifcopenshell.api.run("sequence.edit_task", model, task=task, attributes={"Identification": "M"})
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"task": None, "attributes": {}}
|
self.settings = {"task": task, "attributes": attributes or {}}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
for name, value in self.settings["attributes"].items():
|
for name, value in self.settings["attributes"].items():
|
||||||
|
|||||||
@@ -22,11 +22,36 @@ import ifcopenshell.util.sequence
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, task_time=None, attributes=None):
|
||||||
|
"""Edits the attributes of an IfcTaskTime
|
||||||
|
|
||||||
|
For more information about the attributes and data types of an
|
||||||
|
IfcTaskTime, consult the IFC documentation.
|
||||||
|
|
||||||
|
:param task_time: The IfcTaskTime entity you want to edit
|
||||||
|
:type task_time: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param attributes: a dictionary of attribute names and values.
|
||||||
|
:type attributes: dict, optional
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's imagine we are creating a construction schedule. All tasks
|
||||||
|
# need to be part of a work schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# Create a task to do formwork
|
||||||
|
task = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Formwork", identification="A")
|
||||||
|
|
||||||
|
# Let's say it takes 2 days and starts on the 1st of January, 2000
|
||||||
|
time = ifcopenshell.api.run("sequence.add_task_time", model, task=formwork)
|
||||||
|
ifcopenshell.api.run("sequence.edit_task_time", model,
|
||||||
|
task_time=time, attributes={"ScheduleStart": "2000-01-01", "ScheduleDuration": "P2D"})
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"task_time": None, "attributes": {}}
|
self.settings = {"task_time": task_time, "attributes": attributes or {}}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
self.task = self.get_task()
|
self.task = self.get_task()
|
||||||
|
|||||||
@@ -18,11 +18,30 @@
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, work_calendar=None, attributes=None):
|
||||||
|
"""Edits the attributes of an IfcWorkCalendar
|
||||||
|
|
||||||
|
For more information about the attributes and data types of an
|
||||||
|
IfcWorkCalendar, consult the IFC documentation.
|
||||||
|
|
||||||
|
:param work_calendar: The IfcWorkCalendar entity you want to edit
|
||||||
|
:type work_calendar: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param attributes: a dictionary of attribute names and values.
|
||||||
|
:type attributes: dict, optional
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's create a new calendar.
|
||||||
|
calendar = ifcopenshell.api.run("sequence.add_work_calendar", model, name="5 Day Week")
|
||||||
|
|
||||||
|
# Let's give it a description
|
||||||
|
ifcopenshell.api.run("sequence.edit_work_calendar", model,
|
||||||
|
work_calendar=calendar, attributes={"Description": "Monday to Friday 8 hour days"})
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"work_calendar": None, "attributes": {}}
|
self.settings = {"work_calendar": work_calendar, "attributes": attributes or {}}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
for name, value in self.settings["attributes"].items():
|
for name, value in self.settings["attributes"].items():
|
||||||
|
|||||||
@@ -20,11 +20,30 @@ import ifcopenshell.util.date
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, work_plan=None, attributes=None):
|
||||||
|
"""Edits the attributes of an IfcWorkPlan
|
||||||
|
|
||||||
|
For more information about the attributes and data types of an
|
||||||
|
IfcWorkPlan, consult the IFC documentation.
|
||||||
|
|
||||||
|
:param work_plan: The IfcWorkPlan entity you want to edit
|
||||||
|
:type work_plan: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param attributes: a dictionary of attribute names and values.
|
||||||
|
:type attributes: dict, optional
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# This will hold all our construction schedules
|
||||||
|
work_plan = ifcopenshell.api.run("sequence.add_work_plan", model, name="Construction")
|
||||||
|
|
||||||
|
# Let's give it a description
|
||||||
|
ifcopenshell.api.run("sequence.edit_work_plan", model,
|
||||||
|
work_plan=work_plan, attributes={"Description": "Construction of phase 1"})
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"work_plan": None, "attributes": {}}
|
self.settings = {"work_plan": work_plan, "attributes": attributes or {}}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
for name, value in self.settings["attributes"].items():
|
for name, value in self.settings["attributes"].items():
|
||||||
|
|||||||
@@ -20,11 +20,34 @@ import ifcopenshell.util.date
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, work_schedule=None, attributes=None):
|
||||||
|
"""Edits the attributes of an IfcWorkSchedule
|
||||||
|
|
||||||
|
For more information about the attributes and data types of an
|
||||||
|
IfcWorkSchedule, consult the IFC documentation.
|
||||||
|
|
||||||
|
:param work_schedule: The IfcWorkSchedule entity you want to edit
|
||||||
|
:type work_schedule: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param attributes: a dictionary of attribute names and values.
|
||||||
|
:type attributes: dict, optional
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# This will hold all our construction schedules
|
||||||
|
work_plan = ifcopenshell.api.run("sequence.add_work_plan", model, name="Construction")
|
||||||
|
|
||||||
|
# Let's imagine this is one of our schedules in our work plan.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model,
|
||||||
|
name="Construction Schedule A", work_plan=work_plan)
|
||||||
|
|
||||||
|
# Let's give it a description
|
||||||
|
ifcopenshell.api.run("sequence.edit_work_schedule", model,
|
||||||
|
work_schedule=work_schedule, attributes={"Description": "3 crane design option"})
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"work_schedule": None, "attributes": {}}
|
self.settings = {"work_schedule": work_schedule, "attributes": attributes or {}}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
for name, value in self.settings["attributes"].items():
|
for name, value in self.settings["attributes"].items():
|
||||||
|
|||||||
@@ -20,11 +20,35 @@ import ifcopenshell.util.date
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, work_time=None, attributes=None):
|
||||||
|
"""Edits the attributes of an IfcWorkTime
|
||||||
|
|
||||||
|
For more information about the attributes and data types of an
|
||||||
|
IfcWorkTime, consult the IFC documentation.
|
||||||
|
|
||||||
|
:param work_time: The IfcWorkTime entity you want to edit
|
||||||
|
:type work_time: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param attributes: a dictionary of attribute names and values.
|
||||||
|
:type attributes: dict, optional
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's create a new calendar.
|
||||||
|
calendar = ifcopenshell.api.run("sequence.add_work_calendar", model)
|
||||||
|
|
||||||
|
# Let's start defining the times that we work during the week.
|
||||||
|
work_time = ifcopenshell.api.run("sequence.add_work_time", model,
|
||||||
|
work_calendar=calendar, time_type="WorkingTimes")
|
||||||
|
|
||||||
|
# Edit our work time to state that the work time only applies after
|
||||||
|
# a start date.
|
||||||
|
ifcopenshell.api.run("sequence.edit_work_time", model,
|
||||||
|
work_time=work_time, attributes={"StartDate": "2000-01-01"})
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"work_time": None, "attributes": {}}
|
self.settings = {"work_time": work_time, "attributes": attributes or {}}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
for name, value in self.settings["attributes"].items():
|
for name, value in self.settings["attributes"].items():
|
||||||
|
|||||||
@@ -20,14 +20,45 @@ import ifcopenshell
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, relating_product=None, related_object=None):
|
||||||
|
"""Gets the related products being output by a task
|
||||||
|
|
||||||
|
This API function will be removed in the future and migrated to a
|
||||||
|
utility module.
|
||||||
|
|
||||||
|
:param relating_product: One of the products already output by the task.
|
||||||
|
:type relating_product: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param related_object: The IfcTask that you want to get all the related
|
||||||
|
products for.
|
||||||
|
:type related_object: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: A set of IfcProducts output by the IfcTask.
|
||||||
|
:rtype: set[ifcopenshell.entity_instance.entity_instance]
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's imagine we are creating a construction schedule. All tasks
|
||||||
|
# need to be part of a work schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# Let's create a construction task. Note that the predefined type is
|
||||||
|
# important to distinguish types of tasks.
|
||||||
|
task = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Build wall", identification="A", predefined_type="CONSTRUCTION")
|
||||||
|
|
||||||
|
# Let's say we have a wall somewhere.
|
||||||
|
wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall")
|
||||||
|
|
||||||
|
# Let's construct that wall!
|
||||||
|
ifcopenshell.api.run("sequence.assign_product", relating_product=wall, related_object=task)
|
||||||
|
|
||||||
|
# This will give us a set with that wall in it.
|
||||||
|
products = ifcopenshell.api.run("sequence.get_related_products", model, related_object=task)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {
|
||||||
"relating_product": None,
|
"relating_product": relating_product,
|
||||||
"related_object": None,
|
"related_object": related_object,
|
||||||
}
|
}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
products = set()
|
products = set()
|
||||||
|
|||||||
@@ -24,11 +24,31 @@ import ifcopenshell.util.sequence
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, work_schedule=None):
|
||||||
|
"""Calculate the critical path and floats for a work schedule
|
||||||
|
|
||||||
|
This implements critical path analysis, using the forward pass and
|
||||||
|
backward pass method. When run, any tasks that have no float will be
|
||||||
|
marked as critical, and both the total and free floats will be
|
||||||
|
populated for all task times.
|
||||||
|
|
||||||
|
Cyclical relationships are detected and will result in a recursion
|
||||||
|
error.
|
||||||
|
|
||||||
|
:param work_schedule: The IfcWorkSchedule to perform the calculation on.
|
||||||
|
:type work_schedule: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# See the example for ifcopenshell.api.sequence.cascade_schedule for
|
||||||
|
# details of how to set up a basic set of tasks and calculate the
|
||||||
|
# critical path. Typically cascade_schedule is run prior to ensure
|
||||||
|
# that dates are correct.
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"work_schedule": None}
|
self.settings = {"work_schedule": work_schedule}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
# The method implemented is the same as shown here:
|
# The method implemented is the same as shown here:
|
||||||
|
|||||||
@@ -20,11 +20,38 @@ import ifcopenshell.api
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, task=None):
|
||||||
|
"""Removes a task
|
||||||
|
|
||||||
|
All subtasks are also removed recursively. Any relationships such as
|
||||||
|
sequences or controls are also removed.
|
||||||
|
|
||||||
|
:param task: The IfcTask to remove.
|
||||||
|
:type task: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's imagine we are creating a construction schedule. All tasks
|
||||||
|
# need to be part of a work schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# Add a root task to represent the design milestones, and major
|
||||||
|
# project phases.
|
||||||
|
ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Milestones", identification="A")
|
||||||
|
design = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Design", identification="B")
|
||||||
|
ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Construction", identification="C")
|
||||||
|
|
||||||
|
# Ah, let's delete the design section, who needs it anyway we'll
|
||||||
|
# just fix it on site.
|
||||||
|
ifcopenshell.api.run("sequence.remove_task", model, task=design)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"task": None}
|
self.settings = {"task": task}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
# TODO: do a deep purge
|
# TODO: do a deep purge
|
||||||
|
|||||||
@@ -20,11 +20,42 @@ import ifcopenshell.api
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, time_period=None):
|
||||||
|
"""Removes a time period
|
||||||
|
|
||||||
|
:param time_period: The IfcTimePeriod to remove.
|
||||||
|
:type time_period: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's create a new calendar.
|
||||||
|
calendar = ifcopenshell.api.run("sequence.add_work_calendar", model)
|
||||||
|
|
||||||
|
# Let's start defining the times that we work during the week.
|
||||||
|
work_time = ifcopenshell.api.run("sequence.add_work_time", model,
|
||||||
|
work_calendar=calendar, time_type="WorkingTimes")
|
||||||
|
|
||||||
|
# We create a weekly recurrence
|
||||||
|
pattern = ifcopenshell.api.run("sequence.assign_recurrence_pattern", model,
|
||||||
|
parent=work_time, recurrence_type="WEEKLY")
|
||||||
|
|
||||||
|
# State that we work from weekdays 1 to 5 (i.e. Monday to Friday)
|
||||||
|
ifcopenshell.api.run("sequence.edit_recurrence_pattern", model,
|
||||||
|
recurrence_pattern=pattern, attributes={"WeekdayComponent": [1, 2, 3, 4, 5]})
|
||||||
|
|
||||||
|
# The morning work session, lunch, then the afternoon work session.
|
||||||
|
morning = ifcopenshell.api.run("sequence.add_time_period", model,
|
||||||
|
recurrence_pattern=pattern, start_time="09:00", end_time="12:00")
|
||||||
|
afternoon = ifcopenshell.api.run("sequence.add_time_period", model,
|
||||||
|
recurrence_pattern=pattern, start_time="13:00", end_time="17:00")
|
||||||
|
|
||||||
|
# Let's take the afternoon off!
|
||||||
|
ifcopenshell.api.run("sequence.remove_time_period", model, time_period=afternoon)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"time_period": None}
|
self.settings = {"time_period": time_period}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
self.file.remove(self.settings["time_period"])
|
self.file.remove(self.settings["time_period"])
|
||||||
|
|||||||
@@ -20,11 +20,27 @@ import ifcopenshell
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, work_calendar=None):
|
||||||
|
"""Removes a work calendar
|
||||||
|
|
||||||
|
All relationships are also removed, such as if a task is set to use that
|
||||||
|
calendar.
|
||||||
|
|
||||||
|
:param work_calendar: The IfcWorkCalendar to remove
|
||||||
|
:type work_calendar: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's create a new calendar.
|
||||||
|
calendar = ifcopenshell.api.run("sequence.add_work_calendar", model, name="5 Day Week")
|
||||||
|
|
||||||
|
# And remove it immediately
|
||||||
|
ifcopenshell.api.run("sequence.remove_work_calendar", model, work_calendar=calendar)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"work_calendar": None}
|
self.settings = {"work_calendar": work_calendar}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
# TODO: do a deep purge
|
# TODO: do a deep purge
|
||||||
|
|||||||
@@ -20,11 +20,27 @@ import ifcopenshell
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, work_plan=None):
|
||||||
|
"""Removes a work plan
|
||||||
|
|
||||||
|
Note that schedules that are grouped under the work plan are not
|
||||||
|
removed.
|
||||||
|
|
||||||
|
:param work_plan: The IfcWorkPlan to remove.
|
||||||
|
:type work_plan: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# This will hold all our construction schedules
|
||||||
|
work_plan = ifcopenshell.api.run("sequence.add_work_plan", model, name="Construction")
|
||||||
|
|
||||||
|
# And remove it immediately
|
||||||
|
ifcopenshell.api.run("sequence.remove_work_plan", model, work_plan=work_plan)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"work_plan": None}
|
self.settings = {"work_plan": work_plan}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
# TODO: do a deep purge
|
# TODO: do a deep purge
|
||||||
|
|||||||
@@ -20,11 +20,30 @@ import ifcopenshell.api
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, work_schedule=None):
|
||||||
|
"""Removes a work schedule
|
||||||
|
|
||||||
|
All tasks in the work schedule are also removed recursively.
|
||||||
|
|
||||||
|
:param work_schedule: The IfcWorkSchedule to remove.
|
||||||
|
:type work_schedule: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# This will hold all our construction schedules
|
||||||
|
work_plan = ifcopenshell.api.run("sequence.add_work_plan", model, name="Construction")
|
||||||
|
|
||||||
|
# Let's imagine this is one of our schedules in our work plan.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model,
|
||||||
|
name="Construction Schedule A", work_plan=work_plan)
|
||||||
|
|
||||||
|
# And remove it immediately
|
||||||
|
ifcopenshell.api.run("sequence.remove_work_schedule", model, work_schedule=schedule)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"work_schedule": None}
|
self.settings = {"work_schedule": work_schedule}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
# TODO: do a deep purge
|
# TODO: do a deep purge
|
||||||
|
|||||||
@@ -18,11 +18,28 @@
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, work_time=None):
|
||||||
|
"""Removes a work time
|
||||||
|
|
||||||
|
:param work_time: The IfcWorkTime to remove.
|
||||||
|
:type work_time: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's create a new calendar.
|
||||||
|
calendar = ifcopenshell.api.run("sequence.add_work_calendar", model)
|
||||||
|
|
||||||
|
# Let's start defining the times that we work during the week.
|
||||||
|
work_time = ifcopenshell.api.run("sequence.add_work_time", model,
|
||||||
|
work_calendar=calendar, time_type="WorkingTimes")
|
||||||
|
|
||||||
|
# And remove it immediately
|
||||||
|
ifcopenshell.api.run("sequence.remove_work_time", model, work_time=work_time)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"work_time": None}
|
self.settings = {"work_time": work_time}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
self.file.remove(self.settings["work_time"])
|
self.file.remove(self.settings["work_time"])
|
||||||
|
|||||||
@@ -20,13 +20,46 @@ import ifcopenshell.api
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, rel_sequence=None):
|
||||||
|
"""Removes any lag time in a sequence
|
||||||
|
|
||||||
|
The schedule is cascaded afterwards.
|
||||||
|
|
||||||
|
:param rel_sequence: The sequence to remove the lag time from.
|
||||||
|
:type rel_sequence: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's imagine we are creating a construction schedule. All tasks
|
||||||
|
# need to be part of a work schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# Let's imagine a root construction task
|
||||||
|
construction = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Construction", identification="C")
|
||||||
|
|
||||||
|
# Let's imagine we're building 2 zones, one after another.
|
||||||
|
zone1 = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=construction, name="Zone 1", identification="C.1")
|
||||||
|
zone2 = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=construction, name="Zone 2", identification="C.2")
|
||||||
|
|
||||||
|
# Zone 1 finishes, then zone 2 starts.
|
||||||
|
sequence = ifcopenshell.api.run("sequence.assign_sequence", model,
|
||||||
|
relating_process=zone1, related_process=zone2)
|
||||||
|
|
||||||
|
# What if you had to wait 1 week before you could start zone 2?
|
||||||
|
ifcopenshell.api.run("sequence.assign_lag_time", model, rel_sequence=sequence, lag_value="P1W")
|
||||||
|
|
||||||
|
# What if you didn't?
|
||||||
|
ifcopenshell.api.run("sequence.unassign_lag_time", model, rel_sequence=sequence)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {
|
||||||
"rel_sequence": None,
|
"rel_sequence": rel_sequence,
|
||||||
}
|
}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
if len(self.file.get_inverse(self.settings["rel_sequence"].TimeLag)) == 1:
|
if len(self.file.get_inverse(self.settings["rel_sequence"].TimeLag)) == 1:
|
||||||
|
|||||||
@@ -21,14 +21,43 @@ import ifcopenshell.api
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, relating_process=None, related_object=None):
|
||||||
|
"""Unassigns a process and object relationship
|
||||||
|
|
||||||
|
See ifcopenshell.api.sequence.assign_process for details.
|
||||||
|
|
||||||
|
:param relating_process: The IfcTask in the relationship.
|
||||||
|
:type relating_process: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param related_object: The related object.
|
||||||
|
:type related_object: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's imagine we are creating a construction schedule. All tasks
|
||||||
|
# need to be part of a work schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# Let's create a construction task. Note that the predefined type is
|
||||||
|
# important to distinguish types of tasks.
|
||||||
|
task = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Demolish existing", identification="A", predefined_type="DEMOLITION")
|
||||||
|
|
||||||
|
# Let's say we have a wall somewhere.
|
||||||
|
wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall")
|
||||||
|
|
||||||
|
# Let's demolish that wall!
|
||||||
|
ifcopenshell.api.run("sequence.assign_process", model, relating_process=task, related_object=wall)
|
||||||
|
|
||||||
|
# Change our mind.
|
||||||
|
ifcopenshell.api.run("sequence.unassign_process", model, relating_process=task, related_object=wall)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {
|
||||||
"relating_process": None,
|
"relating_process": relating_process,
|
||||||
"related_object": None,
|
"related_object": related_object,
|
||||||
}
|
}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
for rel in self.settings["related_object"].HasAssignments or []:
|
for rel in self.settings["related_object"].HasAssignments or []:
|
||||||
|
|||||||
@@ -21,14 +21,43 @@ import ifcopenshell.api
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, relating_product=None, related_object=None):
|
||||||
|
"""Unassigns a product and object relationship
|
||||||
|
|
||||||
|
See ifcopenshell.api.sequence.assign_product for details.
|
||||||
|
|
||||||
|
:param relating_product: The IfcProduct in the relationship.
|
||||||
|
:type relating_product: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param related_object: The IfcTask in the relationship.
|
||||||
|
:type related_object: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's imagine we are creating a construction schedule. All tasks
|
||||||
|
# need to be part of a work schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# Let's create a construction task. Note that the predefined type is
|
||||||
|
# important to distinguish types of tasks.
|
||||||
|
task = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Build wall", identification="A", predefined_type="CONSTRUCTION")
|
||||||
|
|
||||||
|
# Let's say we have a wall somewhere.
|
||||||
|
wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall")
|
||||||
|
|
||||||
|
# Let's construct that wall!
|
||||||
|
ifcopenshell.api.run("sequence.assign_product", relating_product=wall, related_object=task)
|
||||||
|
|
||||||
|
# Change our mind.
|
||||||
|
ifcopenshell.api.run("sequence.unassign_product", relating_product=wall, related_object=task)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {
|
||||||
"relating_product": None,
|
"relating_product": relating_product,
|
||||||
"related_object": None,
|
"related_object": related_object,
|
||||||
}
|
}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
for rel in self.settings["related_object"].HasAssignments or []:
|
for rel in self.settings["related_object"].HasAssignments or []:
|
||||||
|
|||||||
@@ -20,11 +20,35 @@ import ifcopenshell.api
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, recurrence_pattern=None):
|
||||||
|
"""Unassigns a recurrence pattern
|
||||||
|
|
||||||
|
Note that a recurring task time must have a recurrence pattern, so if
|
||||||
|
you remove it, be sure to clean up after yourself.
|
||||||
|
|
||||||
|
:param recurrence_pattern: The IfcRecurrencePattern to remove.
|
||||||
|
:type recurrence_pattern: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's create a new calendar.
|
||||||
|
calendar = ifcopenshell.api.run("sequence.add_work_calendar", model)
|
||||||
|
|
||||||
|
# Let's start defining the times that we work during the week.
|
||||||
|
work_time = ifcopenshell.api.run("sequence.add_work_time", model,
|
||||||
|
work_calendar=calendar, time_type="WorkingTimes")
|
||||||
|
|
||||||
|
# We create a weekly recurrence
|
||||||
|
pattern = ifcopenshell.api.run("sequence.assign_recurrence_pattern", model,
|
||||||
|
parent=work_time, recurrence_type="WEEKLY")
|
||||||
|
|
||||||
|
# Change our mind, let's just maintain it whenever we feel like it.
|
||||||
|
ifcopenshell.api.run("sequence.unassign_recurrence_pattern", recurrence_pattern=pattern)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"recurrence_pattern": None}
|
self.settings = {"recurrence_pattern": recurrence_pattern}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
self.file.remove(self.settings["recurrence_pattern"])
|
self.file.remove(self.settings["recurrence_pattern"])
|
||||||
|
|||||||
@@ -21,14 +21,44 @@ import ifcopenshell.api
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, relating_process=None, related_process=None):
|
||||||
|
"""Removes a sequence relationship between tasks
|
||||||
|
|
||||||
|
:param relating_process: The previous / predecessor task.
|
||||||
|
:type relating_process: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param related_process: The next / successor task.
|
||||||
|
:type related_process: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# Let's imagine we are creating a construction schedule. All tasks
|
||||||
|
# need to be part of a work schedule.
|
||||||
|
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||||
|
|
||||||
|
# Let's imagine a root construction task
|
||||||
|
construction = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
work_schedule=schedule, name="Construction", identification="C")
|
||||||
|
|
||||||
|
# Let's imagine we're building 2 zones, one after another.
|
||||||
|
zone1 = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=construction, name="Zone 1", identification="C.1")
|
||||||
|
zone2 = ifcopenshell.api.run("sequence.add_task", model,
|
||||||
|
parent_task=construction, name="Zone 2", identification="C.2")
|
||||||
|
|
||||||
|
# Zone 1 finishes, then zone 2 starts.
|
||||||
|
ifcopenshell.api.run("sequence.assign_sequence", model, relating_process=zone1, related_process=zone2)
|
||||||
|
|
||||||
|
# Let's make them unrelated
|
||||||
|
ifcopenshell.api.run("sequence.unassign_sequence", model,
|
||||||
|
relating_process=zone1, related_process=zone2)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {
|
||||||
"relating_process": None,
|
"relating_process": relating_process,
|
||||||
"related_process": None,
|
"related_process": related_process,
|
||||||
}
|
}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
for rel in self.settings["related_process"].IsSuccessorFrom or []:
|
for rel in self.settings["related_process"].IsSuccessorFrom or []:
|
||||||
|
|||||||
Reference in New Issue
Block a user