Write documentation for structural API module

This commit is contained in:
Dion Moult
2023-01-03 17:32:08 +11:00
parent e53a9cd66c
commit 0c77fb81ce
21 changed files with 342 additions and 101 deletions
@@ -20,17 +20,52 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(
self,
file,
ifc_class="IfcStructuralPlanarAction",
predefined_type="CONST",
global_or_local="GLOBAL_COORDS",
applied_load=None,
structural_member=None,
):
"""Adds a new structural activity
A structural activity is either a structural action or a reaction. It
may be applied to a point, a curve, or a planar surface, and may be a
constant load, linear, etc.
The activity must be defined using an applied load, and associated with
a structural member.
:param ifc_class: Choose from any subtype of IfcStructuralActivity.
:type ifc_class: str
:param predefined_type: View the IFC documentation for what valid
predefined types may be chosen.
:type predefined_type: str
:param global_or_local: The location coordinates of the load is always
defined locally relative to the structural member the activity is
assigned to. However, the directions of the applied load may either
be specified globally or locally depending on how this argument is
set. Choose from GLOBAL_COORDS or LOCAL_COORDS.
:type global_or_local: str
:param applied_load: The IfcStructuralLoad that is applied in this
activity.
:type applied_load: ifcopenshell.entity_instance.entity_instance
:param structural_member: The IfcStructuralMember that the load is
applied to.
:type structural_member: ifcopenshell.entity_instance.entity_instance
:return: The newly created entity based on the ifc_class
:rtype: ifcopenshell.entity_instance.entity_instance
"""
self.file = file
self.settings = {
"ifc_class": "IfcStructuralPlanarAction",
"predefined_type": "CONST",
"global_or_local": "GLOBAL_COORDS",
"applied_load": None,
"structural_member": None,
"ifc_class": ifc_class,
"predefined_type": predefined_type,
"global_or_local": global_or_local,
"applied_load": applied_load,
"structural_member": structural_member,
}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
activity = ifcopenshell.api.run(
@@ -21,11 +21,25 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file):
"""Add a new structural analysis model
A structural analysis model is a group of all the loads, reactions,
structural members, and structural connections required to describe a
structural analysis model.
A 3D analytical model is assumed.
:return: The newly created IfcStructuralAnalysisModel
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
# Create a fresh blank structural analysis
analysis = ifcopenshell.api.run("structural.add_structural_analysis_model", model)
"""
self.file = file
self.settings = {}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
return ifcopenshell.api.run(
@@ -18,11 +18,33 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, name=None, connection=None, ifc_class="IfcBoundaryNodeCondition"):
"""Adds a new structural boundary condition to a structural connection
The type of boundary condition depends on the connection. Point
connections will have a node condition, curve connections will have an
edge condition, and surface connections will have a face condition.
:param name: The name of the boundary condition.
:type name: str,optional
:param connection: The IfcStructuralConnection to apply the boundary
condition to. This will determine the type of condition that is
created. If no connection is supplied, an orphan boundary condition
will be created using the ifc_class that you specify.
:type connection: ifcopenshell.entity_instance.entity_instance,optional
:param ifc_class: The class of IfcBoundaryCondition to create, only
relevant if you do not specify a connection and want to create an
orphaned boundary condition.
:type ifc_class: str,optional
:return: The newly created IfcBoundaryCondition
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
ifcopenshell.api.run("structural.add_structural_boundary_condition", model, connection=connection)
"""
self.file = file
self.settings = {"name": None, "connection": None, "ifc_class": "IfcBoundaryNodeCondition"}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"name": name, "connection": connection, "ifc_class": ifc_class}
def execute(self):
if self.settings["connection"]:
@@ -20,14 +20,32 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, name=None, ifc_class="IfcStructuralLoadLinearForce"):
"""Adds a new structural load
Structural loads may be actions or reactions. A simple load might be a
static and be linear, planar, or a single point. Alternatively, loads
may be defined as a configuration of multiple loads.
:param name: The name of the load
:type name: str,optional
:param ifc_class: The subtype of IfcStructuralLoad to create. Consult
the IFC documentation to see all the types of loads.
:type ifc_class: str
:return: The newly created load entity, depending on the ifc_class
specified.
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
# Create a simple linear load
ifcopenshell.api.run("structural.add_structural_load", model)
"""
self.file = file
self.settings = {
"name": None,
"ifc_class": "IfcStructuralLoadLinearForce",
"name": name,
"ifc_class": ifc_class,
}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
return self.file.create_entity(self.settings["ifc_class"], Name=self.settings["name"])
@@ -20,23 +20,36 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(
self, file, name="Unnamed", action_type="NOTDEFINED", action_source="NOTDEFINED"
):
"""Adds a new load case, which is a collection of related load groups
:param name: The name of the load case
:type name: str
:param action_type: Choose from EXTRAORDINARY_A, PERMANENT_G,
or VARIABLE_Q, taken from the Eurocode standard.
:type action_type: str
:param action_source: The source of the load case, such as DEAD_LOAD_G,
LIVE_LOAD_Q, TRANSPORT, ICE, etc. For the full list consult
IfcActionSourceTypeEnum in the IFC documentation.
:type action_source: str
:return: The new IfcStructuralLoadCase
:rtype: ifcopenshell.entity_instance.entity_instance
"""
self.file = file
self.settings = {
"name": "Unnamed",
"predefined_type": "LOAD_CASE",
"action_type": "NOTDEFINED",
"action_source": "NOTDEFINED",
"name": name,
"action_type": action_type,
"action_source": action_source,
}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
load_case = ifcopenshell.api.run(
"root.create_entity",
self.file,
ifc_class="IfcStructuralLoadCase",
predefined_type=self.settings["predefined_type"],
predefined_type="LOAD_CASE",
name=self.settings["name"],
)
load_case.ActionType = self.settings["action_type"]
@@ -20,23 +20,36 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(
self, file, name="Unnamed", action_type="NOTDEFINED", action_source="NOTDEFINED"
):
"""Adds a new load group, which is a collection of related loads
:param name: The name of the load group
:type name: str
:param action_type: Choose from EXTRAORDINARY_A, PERMANENT_G,
or VARIABLE_Q, taken from the Eurocode standard.
:type action_type: str
:param action_source: The source of the load case, such as DEAD_LOAD_G,
LIVE_LOAD_Q, TRANSPORT, ICE, etc. For the full list consult
IfcActionSourceTypeEnum in the IFC documentation.
:type action_source: str
:return: The new IfcStructuralLoadCase
:rtype: ifcopenshell.entity_instance.entity_instance
"""
self.file = file
self.settings = {
"name": "Unnamed",
"predefined_type": "LOAD_GROUP",
"action_type": "NOTDEFINED",
"action_source": "NOTDEFINED",
"name": name,
"action_type": action_type,
"action_source": action_source,
}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
load_group = ifcopenshell.api.run(
"root.create_entity",
self.file,
ifc_class="IfcStructuralLoadGroup",
predefined_type=self.settings["predefined_type"],
predefined_type="LOAD_GROUP",
name=self.settings["name"],
)
load_group.ActionType = self.settings["action_type"]
@@ -21,11 +21,23 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, relating_structural_member=None, related_structural_connection=None):
"""Relates a structural member and a structural connection
:param relating_structural_member: The IfcStructuralMember to have a
connection added to it.
:type relating_structural_member: ifcopenshell.entity_instance.entity_instance
:param related_structural_connection: The IfcStructuralConnection to add
to the IfcStructuralMember.
:type related_structural_connection: ifcopenshell.entity_instance.entity_instance
:return: The IfcRelConnectsStructuralMember relationship
:rtype: ifcopenshell.entity_instance.entity_instance
"""
self.file = file
self.settings = {"relating_structural_member": None, "related_structural_connection": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {
"relating_structural_member": relating_structural_member,
"related_structural_connection": related_structural_connection,
}
def execute(self):
for connection in self.settings["related_structural_connection"].ConnectsStructuralMembers or []:
@@ -21,14 +21,22 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, product=None, structural_analysis_model=None):
"""Assigns a load or structural member to an analysis model
:param product: The structural element that is part of the analysis.
:type product: ifcopenshell.entity_instance.entity_instance
:param structural_analysis_model: The IfcStructuralAnalysisModel that
the structural element is related to.
:type structural_analysis_model: ifcopenshell.entity_instance.entity_instance
:return: The IfcRelAssignsToGroup relationship
:rtype: ifcopenshell.entity_instance.entity_instance
"""
self.file = file
self.settings = {
"product": None,
"structural_analysis_model": None,
"product": product,
"structural_analysis_model": structural_analysis_model,
}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
if not self.settings["structural_analysis_model"].IsGroupedBy:
@@ -18,11 +18,21 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, structural_analysis_model=None, attributes=None):
"""Edits the attributes of an IfcStructuralAnalysisModel
For more information about the attributes and data types of an
IfcStructuralAnalysisModel, consult the IFC documentation.
:param structural_analysis_model: The IfcStructuralAnalysisModel entity you want to edit
:type structural_analysis_model: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
"""
self.file = file
self.settings = {"structural_analysis_model": None, "attributes": {}}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"structural_analysis_model": structural_analysis_model, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
@@ -18,11 +18,21 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, condition=None, attributes=None):
"""Edits the attributes of an IfcBoundaryCondition
For more information about the attributes and data types of an
IfcBoundaryCondition, consult the IFC documentation.
:param condition: The IfcBoundaryCondition entity you want to edit
:type condition: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
"""
self.file = file
self.settings = {"condition": None, "attributes": {}}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"condition": condition, "attributes": attributes or {}}
def execute(self):
for name, data in self.settings["attributes"].items():
@@ -18,22 +18,34 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, structural_item=None, axis=None, ref_direction=None):
"""Edits the coordinate system of a structural connection
:param structural_item: The IfcStructuralItem you want to modify.
:type structural_item: ifcopenshell.entity_instance.entity_instance
:param axis: The unit Z axis vector defined as a list of 3 floats.
Defaults to [0., 0., 1.].
:type axis: list[float]
:param ref_direction: The unit X axis vector defined as a list of 3
floats. Defaults to [1., 0., 0.].
:type ref_direction: list[float]
:return: None
:rtype: None
"""
self.file = file
self.settings = {"structural_item": None, "axis": [0.0, 0.0, 1.0], "ref_direction": [1.0, 0.0, 0.0]}
for key, value in settings.items():
self.settings[key] = value
self.settings = {
"structural_item": structural_item,
"axis": axis or [0.0, 0.0, 1.0],
"ref_direction": ref_direction or [1.0, 0.0, 0.0],
}
def execute(self):
if self.settings["structural_item"].ConditionCoordinateSystem is None:
point = self.file.createIfcCartesianPoint((0.0, 0.0, 0.0))
ccs = self.file.createIfcAxis2Placement3D(point, None, None)
self.settings["structural_item"].ConditionCoordinateSystem = ccs
print(ccs)
ccs = self.settings["structural_item"].ConditionCoordinateSystem
print("use case")
print(ccs)
if ccs.Axis and len(self.file.get_inverse(ccs.Axis)) == 1:
self.file.remove(ccs.Axis)
ccs.Axis = self.file.createIfcDirection(self.settings["axis"])
@@ -18,11 +18,19 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, structural_item=None, axis=None):
"""Edits the coordinate system of a structural connection
:param structural_item: The IfcStructuralItem you want to modify.
:type structural_item: ifcopenshell.entity_instance.entity_instance
:param axis: The unit Z axis vector defined as a list of 3 floats.
Defaults to [0., 0., 1.].
:type axis: list[float]
:return: None
:rtype: None
"""
self.file = file
self.settings = {"structural_item": None, "axis": [0.0, 0.0, 1.0]}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"structural_item": structural_item, "axis": axis or [0.0, 0.0, 1.0]}
def execute(self):
if len(self.file.get_inverse(self.settings["structural_item"].Axis)) == 1:
@@ -18,11 +18,21 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, structural_load=None, attributes=None):
"""Edits the attributes of an IfcStructuralLoad
For more information about the attributes and data types of an
IfcStructuralLoad, consult the IFC documentation.
:param structural_load: The IfcStructuralLoad entity you want to edit
:type structural_load: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
"""
self.file = file
self.settings = {"structural_load": None, "attributes": {}}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"structural_load": structural_load, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
@@ -18,11 +18,21 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, load_case=None, attributes=None):
"""Edits the attributes of an IfcStructuralLoadCase
For more information about the attributes and data types of an
IfcStructuralLoadCase, consult the IFC documentation.
:param load_case: The IfcStructuralLoadCase entity you want to edit
:type load_case: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
"""
self.file = file
self.settings = {"load_case": None, "attributes": {}}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"load_case": load_case, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
@@ -18,11 +18,19 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, structural_analysis_model=None):
"""Removes an analysis model
Note that the contents of an analysis model are currently preserved.
:param structural_analysis_model: The IfcStructuralAnalysisModel to
remove.
:type structural_analysis_model: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
"""
self.file = file
self.settings = {"structural_analysis_model": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"structural_analysis_model": structural_analysis_model}
def execute(self):
for rel in self.settings["structural_analysis_model"].IsGroupedBy or []:
@@ -18,11 +18,19 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, connection=None, boundary_condition=None):
"""Removes a condition from a connection, or an orphased boundary condition
:param connection: The IfcStructuralConnection to remove the condition
from. If omitted, it is assumed to be an orphaned condition.
:type connection: ifcopenshell.entity_instance.entity_instance,optional
:param boundary_condition: The IfcBoundaryCondition to remove.
:type boundary_condition: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
"""
self.file = file
self.settings = {"connection": None, "boundary_condition": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"connection": connection, "boundary_condition": boundary_condition}
def execute(self):
if self.settings["connection"]:
@@ -20,11 +20,18 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, relation=None):
"""Removes a relationship between a connection and a condition
The condition and the member itself is preserved.
:param relation: The IfcRelConnectsStructuralMember to remove.
:type relation: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
"""
self.file = file
self.settings = {"relation": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"relation": relation}
def execute(self):
if self.settings["relation"].AppliedCondition:
@@ -18,11 +18,16 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, structural_load=None):
"""Removes a structural load
:param structural_load: The IfcStructuralLoad to remove.
:type structural_load: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
"""
self.file = file
self.settings = {"structural_load": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"structural_load": structural_load}
def execute(self):
self.file.remove(self.settings["structural_load"])
@@ -20,11 +20,16 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, load_case=None):
"""Removes a structural load case
:param load_case: The IfcStructuralLoadCase to remove.
:type load_case: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
"""
self.file = file
self.settings = {"load_case": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"load_case": load_case}
def execute(self):
# TODO: do a deep purge
@@ -20,11 +20,16 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, load_group=None):
"""Removes a structural load group
:param load_group: The IfcStructuralLoadGroup to remove.
:type load_group: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
"""
self.file = file
self.settings = {"load_group": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"load_group": load_group}
def execute(self):
# TODO: do a deep purge
@@ -21,14 +21,22 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, product=None, structural_analysis_model=None):
"""Removes a relationship between a structural element and the analysis model
:param product: The structural element that is part of the analysis.
:type product: ifcopenshell.entity_instance.entity_instance
:param structural_analysis_model: The IfcStructuralAnalysisModel that
the structural element is related to.
:type structural_analysis_model: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
"""
self.file = file
self.settings = {
"product": None,
"structural_analysis_model": None,
"product": product,
"structural_analysis_model": structural_analysis_model,
}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
if not self.settings["structural_analysis_model"].IsGroupedBy: