Write documentation for resource API module

This commit is contained in:
Dion Moult
2022-12-16 15:07:02 +11:00
parent d2fee728f2
commit 436482532d
13 changed files with 386 additions and 56 deletions
@@ -53,8 +53,7 @@ class Usecase:
# Setup an organisation with a single role
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
role = ifcopenshell.api.run("owner.add_role", model, assigned_object=organisation)
ifcopenshell.api.run("owner.edit_role", model, role=role, attributes={"Role": "ARCHITECT"})
role = ifcopenshell.api.run("owner.add_role", model, assigned_object=organisation, role="ARCHITECT")
# Assign that organisation to a newly created actor
actor = ifcopenshell.api.run("owner.add_actor", model, actor=organisation)
@@ -31,11 +31,14 @@ class Usecase:
Here are a list of objects you may assign an actor to:
- IfcControl: Indicates project directives issued by the actor.
- IfcGroup: Indicates groups for which the actor is responsible.
- IfcProduct: Indicates products for which the actor is responsible.
- IfcProcess: Indicates processes for which the actor is responsible.
- IfcResource: Indicates resources for which the actor is responsible.
* IfcControl: Indicates project directives issued by the actor.
* IfcGroup: Indicates groups for which the actor is responsible.
* IfcProduct: Indicates products for which the actor is responsible.
* IfcProcess: Indicates processes for which the actor is responsible.
* IfcResource: Indicates resources for which the actor is responsible to
allocate, manage, or delegate. This is not the actor actually using
the resource or performing the work. For that type of actor, see
ifcopenshell.api.resource.assign_resource.
:param relating_actor: The IfcActor who is responsible for the object.
:type relating_actor: ifcopenshell.entity_instance.entity_instance
@@ -20,16 +20,61 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(
self, file, parent_resource=None, ifc_class="IfcCrewResource", name=None, predefined_type="NOTDEFINED"
):
"""Add a new construction resource
Construction resources may be managed and connected to cost schedules
and construction schedules. This allows calculations to be done on
resource utilisation, cost optimisation (e.g. labour rates), and
optioneering on build strategies.
There are typically two types of resources. Crew resources are resources
where you manage your own crew and you have full control over the
equipment, labour, products, and materials used by your crew.
Alternatively, there are subcontractor resources, where you simply
delegate all the details to a subcontractor and it is not decomposed
into further levels of detail.
This means when adding resources, you'd first either add a crew or
subcontract resource. If it is a crew resource, you'd then add child
resources to that crew, such as equipment (cranes, excavators, hoists,
etc), material (wood, concrete, etc), and labour (rigging crews,
formworkers, etc).
:param parent_resource: If this is a child resource (typically to a crew
resource), then nominate the parent IfcConstructionResource here.
:type parent_resource: ifcopenshell.entity_instance.entity_instance
:param ifc_class: The class of resource chosen from
IfcConstructionEquipmentResource, IfcConstructionMaterialResource,
IfcConstructionProductResource, IfcCrewResource, IfcLaborResource,
or IfcSubContractResource.
:type ifc_class: str,optional
:param name: The name of the resource
:type name: str,optional
:param predefined_type: Consult the IFC documentation for the valid
predefined types for each type of resource class.
:type predefined_type: str,optional
:return: The newly created resource depending on the nominated IFC
class.
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
# Add our own crew
crew = ifcopenshell.api.run("resource.add_resource", model, ifc_class="IfcCrewResource")
# Add some labour to our crew.
ifcopenshell.api.run("resource.add_resource", model, parent_resource=crew, ifc_class="IfcLaborResource")
"""
self.file = file
self.settings = {
"parent_resource": None,
"ifc_class": "IfcCrewResource",
"name": None,
"predefined_type": "NOTDEFINED",
"parent_resource": parent_resource,
"ifc_class": ifc_class,
"name": name,
"predefined_type": predefined_type,
}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
resource = ifcopenshell.api.run(
@@ -20,11 +20,49 @@ import ifcopenshell.util.element
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, resource=None, ifc_class="IfcQuantityCount"):
"""Adds a quantity to a resource
The quantity of a resource represents the "unit quantity" of that
resource. For example, labour might be hired on a daily basis (8 hours).
There are different types of quantities (e.g. volume, count, or time).
Which quantity is used depends on the type of resource. Material
resources may be quantified in terms of length, area, volume, or weight.
Equipment and labour resources are quantified in terms of time. Products
resources are quantified in terms of counts.
This base quantity is then used in other calculations.
:param resource: The IfcConstructionResource to add a quantity to.
:type resource: ifcopenshell.entity_instance.entity_instance
:param ifc_class: The type of quantity to add, chosen from
IfcQuantityArea (for material), IfcQuantityCount (for products),
IfcQuantityLength (for material), IfcQuantityTime (for equipment or
labour), IfcQuantityVolume (for material), and IfcQuantityWeight
(for material).
:type ifc_class: str,optional
:return: The newly created quantity depending on the IFC class
:rtype: ifcopenshell.entity_instance.entity_instance
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.
ifcopenshell.api.run("resource.add_resource_quantity", model,
resource=labour, ifc_class="IfcQuantityTime")
# Store the time used in hours
ifcopenshell.api.run("resource.edit_resource_quantity", model,
physical_quantity=time, attributes={"TimeValue": 8.0})
"""
self.file = file
self.settings = {"resource": None, "ifc_class": "IfcQuantityCount"}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"resource": resource, "ifc_class": ifc_class}
def execute(self):
quantity = self.file.create_entity(self.settings["ifc_class"], Name="Unnamed")
@@ -20,13 +20,45 @@ import ifcopenshell.util.date
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, resource=None):
"""Adds the time that a resource is used for
For labour and equipment resources, the total duration that the resource
is used for may be stored. This may either be input manually or
calculated parametrically. This is known as the resource time, and may
be used to calculate other parameters like resource utilisation.
:param resource: The IfcConstructionResource to record time for.
:type resource: ifcopenshell.entity_instance.entity_instance
:return: The newly created IfcResourceTime
:rtype: ifcopenshell.entity_instance.entity_instance
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.
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=time, attributes={"TimeValue": 8.0})
# Let's imagine we've used the resource for 2 days.
time = ifcopenshell.api.run("resource.add_resource_time", model, resource=labour)
ifcopenshell.api.run("resource.edit_resource_time", model,
resource_time=time, attributes={"ScheduleWork": "P16H"})
"""
self.file = file
self.settings = {
"resource": None,
"resource": resource,
}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
resource_time = self.file.create_entity("IfcResourceTime")
@@ -21,14 +21,66 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, relating_resource=None, related_object=None):
"""Assigns a resource to an object
Two types of objects are typically assigned to resources: products and
actors.
If a product is assigned to a resource, that means that the product
represents the resource on site. This may be represented via material
handling zones on a construction site, or equipment like cranes and
their physical locations.
If an actor is assigned to a resource, that means that the actor (person
or organisation) is the actor consuming the resource (e.g. if the
resource is material or equipment) or the actor performing the work
(e.g. if the resource is a labour resource).
:param relating_resource: The IfcResource to assign the object to.
:type relating_resource: ifcopenshell.entity_instance.entity_instance
:param related_object: The IfcProduct or IfcActor to assign to the
object.
:type related_object: ifcopenshell.entity_instance.entity_instance
:return: The newly created IfcRelAssignsToResource
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
# Add our own crew
crew = ifcopenshell.api.run("resource.add_resource", model, ifc_class="IfcCrewResource")
# Add some a tower crane to our crew.
crane = ifcopenshell.api.run("resource.add_resource", model,
parent_resource=crew, ifc_class="IfcConstructionEquipmentResource", name="Tower Crane 01")
# Our tower crane will be placed via this physical product.
product = ifcopenshell.api.run("root.create_entity", model,
ifc_class="IfcBuildingElementProxy", predefined_type="CRANE")
# Let's place our crane at some X, Y coordinates.
matrix = numpy.eye(4)
matrix[0][3], matrix[1][3] = 3.0, 4.0
ifcopenshell.api.run("geometry.edit_object_placement", model, product=crane, matrix=matrix)
# Let's assign our crane to the resource. The crane now represents
# the resource.
ifcopenshell.api.run("resource.assign_resource", model, relating_resource=crane, related_object=product)
# Setup an organisation actor who will operate the crane
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="UCO", name="Unionised Crane Operators Pty Ltd")
role = ifcopenshell.api.run("owner.add_role", model, assigned_object=organisation, role="CREW")
actor = ifcopenshell.api.run("owner.add_actor", model, actor=organisation)
# This means that UCO is now our crane operator.
ifcopenshell.api.run("resource.assign_resource", model, relating_resource=crane, related_object=actor)
"""
self.file = file
self.settings = {
"relating_resource": None,
"related_object": None,
"relating_resource": relating_resource,
"related_object": related_object,
}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
if self.settings["related_object"].HasAssignments:
@@ -23,11 +23,40 @@ import ifcopenshell.util.element
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, resource=None):
"""Calculates the work that a resource is used for
This is an unofficial parametric calculation that may be done on a
resource based on careful analysis of the relationships between the
costing, scheduling, and resource domains in IFC.
A resource may store a productivity rate in a property set called
EPset_Productivity. This stores three properties:
* BaseQuantityConsumed - a duration that the resource is consumed for.
* BaseQuantityProducedName - what quantity the resource can produce,
such as area or volume.
* BaseQuantityProducedValue - what value of that quantity the resource
can produce during that duration.
For example, a labour or equipment resource might produce 100m3 of
NetVolume every day (i.e. 8 hours are consumed).
Then, if a resource is assigned to a construction task, and that
construction task is assigned to concrete slabs totalling 200m3, we can
calculate that the resource consumes 16 hours of work.
This calculated work is stored against the resource as scheduled work
under the resource time data.
:param resource: The IfcConstructionResource that you want to calculate
the work performed.
:type resource: ifcopenshell.entity_instance.entity_instance
:return None:
:rtype None:
"""
self.file = file
self.settings = {"resource": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"resource": resource}
def execute(self):
self.productivity = ifcopenshell.util.element.get_psets(
@@ -18,11 +18,29 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, resource=None, attributes=None):
"""Edits the attributes of an IfcResource
For more information about the attributes and data types of an
IfcResource, consult the IFC documentation.
:param resource: The IfcResource entity you want to edit
:type resource: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
Example::
# Add our own crew
crew = ifcopenshell.api.run("resource.add_resource", model, ifc_class="IfcCrewResource")
# Change the name of the resource to "Zone A Crew"
ifcopenshell.api.run("resource.edit_resource", model, resource=resource, attributes={"Name": "Foo"})
"""
self.file = file
self.settings = {"resource": None, "attributes": {}}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"resource": resource, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
@@ -18,11 +18,38 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, physical_quantity=None, attributes=None):
"""Edits the attributes of an IFC quantity
For more information about the attributes and data types of an
IfC quantity, consult the IFC documentation.
:param physical_quantity: The IfC quantity entity you want to edit
:type physical_quantity: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
: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.
ifcopenshell.api.run("resource.add_resource_quantity", model,
resource=labour, ifc_class="IfcQuantityTime")
# Store the time used in hours
ifcopenshell.api.run("resource.edit_resource_quantity", model,
physical_quantity=time, attributes={"TimeValue": 8.0})
"""
self.file = file
self.settings = {"physical_quantity": None, "attributes": {}}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"physical_quantity": physical_quantity, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
@@ -21,11 +21,43 @@ import ifcopenshell.util.date
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, resource_time=None, attributes=None):
"""Edits the attributes of an IfcResourceTime
For more information about the attributes and data types of an
IfcResourceTime, consult the IFC documentation.
:param resource_time: The IfcResourceTime entity you want to edit
:type resource_time: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
: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.
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=time, attributes={"TimeValue": 8.0})
# Let's imagine we've used the resource for 2 days.
time = ifcopenshell.api.run("resource.add_resource_time", model, resource=labour)
ifcopenshell.api.run("resource.edit_resource_time", model,
resource_time=time, attributes={"ScheduleWork": "P16H"})
"""
self.file = file
self.settings = {"resource_time": None, "attributes": {}}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"resource_time": resource_time, "attributes": attributes or {}}
def execute(self):
self.resource = self.get_resource()
@@ -20,11 +20,19 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, resource=None):
"""Removes a resource and all relationships
Example::
# Add our own crew
crew = ifcopenshell.api.run("resource.add_resource", model, ifc_class="IfcCrewResource")
# Fire our crew
ifcopenshell.api.run("resource.remove_resource", model, resource=crew)
"""
self.file = file
self.settings = {"resource": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"resource": resource}
def execute(self):
# TODO: review deep purge
@@ -20,11 +20,28 @@ import ifcopenshell.util.element
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, resource=None):
"""Removes the base quantity of a resource
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.
ifcopenshell.api.run("resource.add_resource_quantity", model,
resource=labour, ifc_class="IfcQuantityTime")
# Let's say we only want to store the resource but no quantities,
# let's clean up our mess and remove the quantity.
ifcopenshell.api.run("resource.remove_resource_quantity", model, resource=labour)
"""
self.file = file
self.settings = {"resource": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"resource": resource}
def execute(self):
old_quantity = self.settings["resource"].BaseQuantity
@@ -20,14 +20,44 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, relating_resource=None, related_object=None):
"""Removes the relationship between a resource and object
:param relating_resource: The IfcResource to assign the object to.
:type relating_resource: ifcopenshell.entity_instance.entity_instance
:param related_object: The IfcProduct or IfcActor to assign to the
object.
:type related_object: ifcopenshell.entity_instance.entity_instance
:return: The newly created IfcRelAssignsToResource
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
# Add our own crew
crew = ifcopenshell.api.run("resource.add_resource", model, ifc_class="IfcCrewResource")
# Add some a tower crane to our crew.
crane = ifcopenshell.api.run("resource.add_resource", model,
parent_resource=crew, ifc_class="IfcConstructionEquipmentResource", name="Tower Crane 01")
# Our tower crane will be placed via this physical product.
product = ifcopenshell.api.run("root.create_entity", model,
ifc_class="IfcBuildingElementProxy", predefined_type="CRANE")
# Let's assign our crane to the resource. The crane now represents
# the resource.
ifcopenshell.api.run("resource.assign_resource", model,
relating_resource=crane, related_object=product)
# Undo it.
ifcopenshell.api.run("resource.unassign_resource", model,
relating_resource=crane, related_object=product)
"""
self.file = file
self.settings = {
"relating_resource": None,
"related_object": None,
"relating_resource": relating_resource,
"related_object": related_object,
}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
for rel in self.settings["related_object"].HasAssignments or []: