First Commit

This commit is contained in:
2026-05-31 10:17:09 +07:00
commit 17a9c69379
4547 changed files with 1170384 additions and 0 deletions
@@ -0,0 +1,78 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
"""Manage analytical properties for structural simulation
This only handles authoring the analytical model, and does not actually perform
any structural simulation. To perform the simulation, see IFC2CA.
"""
from .. import wrap_usecases
from .add_structural_activity import add_structural_activity
from .add_structural_analysis_model import add_structural_analysis_model
from .add_structural_boundary_condition import add_structural_boundary_condition
from .add_structural_load import add_structural_load
from .add_structural_load_case import add_structural_load_case
from .add_structural_load_group import add_structural_load_group
from .add_structural_member_connection import add_structural_member_connection
from .assign_product import assign_product
from .assign_structural_analysis_model import assign_structural_analysis_model
from .assign_to_building import assign_to_building
from .edit_structural_analysis_model import edit_structural_analysis_model
from .edit_structural_boundary_condition import edit_structural_boundary_condition
from .edit_structural_connection_cs import edit_structural_connection_cs
from .edit_structural_item_axis import edit_structural_item_axis
from .edit_structural_load import edit_structural_load
from .edit_structural_load_case import edit_structural_load_case
from .remove_structural_analysis_model import remove_structural_analysis_model
from .remove_structural_boundary_condition import remove_structural_boundary_condition
from .remove_structural_connection_condition import (
remove_structural_connection_condition,
)
from .remove_structural_load import remove_structural_load
from .remove_structural_load_case import remove_structural_load_case
from .remove_structural_load_group import remove_structural_load_group
from .unassign_structural_analysis_model import unassign_structural_analysis_model
wrap_usecases(__path__, __name__)
__all__ = [
"add_structural_activity",
"add_structural_analysis_model",
"add_structural_boundary_condition",
"add_structural_load",
"add_structural_load_case",
"add_structural_load_group",
"add_structural_member_connection",
"assign_product",
"assign_structural_analysis_model",
"assign_to_building",
"edit_structural_analysis_model",
"edit_structural_boundary_condition",
"edit_structural_connection_cs",
"edit_structural_item_axis",
"edit_structural_load",
"edit_structural_load_case",
"remove_structural_analysis_model",
"remove_structural_boundary_condition",
"remove_structural_connection_condition",
"remove_structural_load",
"remove_structural_load_case",
"remove_structural_load_group",
"unassign_structural_analysis_model",
]
@@ -0,0 +1,67 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
from typing import Literal
import ifcopenshell.api.root
def add_structural_activity(
file: ifcopenshell.file,
applied_load: ifcopenshell.entity_instance,
structural_member: ifcopenshell.entity_instance,
ifc_class: str = "IfcStructuralPlanarAction",
predefined_type: str = "CONST",
global_or_local: Literal["GLOBAL_COORDS", "LOCAL_COORDS"] = "GLOBAL_COORDS",
) -> ifcopenshell.entity_instance:
"""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.
:param predefined_type: View the IFC documentation for what valid
predefined types may be chosen.
: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.
:param applied_load: The IfcStructuralLoad that is applied in this
activity.
:param structural_member: The IfcStructuralMember that the load is
applied to.
:return: The newly created entity based on the ifc_class
"""
activity = ifcopenshell.api.root.create_entity(
file,
ifc_class=ifc_class,
predefined_type=predefined_type,
)
activity.AppliedLoad = applied_load
activity.GlobalOrLocal = global_or_local
rel = ifcopenshell.api.root.create_entity(file, ifc_class="IfcRelConnectsStructuralActivity")
rel.RelatingElement = structural_member
rel.RelatedStructuralActivity = activity
return activity
@@ -0,0 +1,43 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import ifcopenshell.api.root
def add_structural_analysis_model(file: ifcopenshell.file) -> ifcopenshell.entity_instance:
"""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
Example:
.. code:: python
# Create a fresh blank structural analysis
analysis = ifcopenshell.api.structural.add_structural_analysis_model(model)
"""
return ifcopenshell.api.root.create_entity(
file, ifc_class="IfcStructuralAnalysisModel", predefined_type="LOADING_3D"
)
@@ -0,0 +1,70 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
from typing import Optional
import ifcopenshell
def add_structural_boundary_condition(
file: ifcopenshell.file,
name: Optional[str] = None,
connection: Optional[ifcopenshell.entity_instance] = None,
ifc_class: str = "IfcBoundaryNodeCondition",
) -> ifcopenshell.entity_instance:
"""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.
: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.
: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.
:return: The newly created IfcBoundaryCondition
Example:
.. code:: python
ifcopenshell.api.structural.add_structural_boundary_condition(model, connection=connection)
"""
if connection:
# assign boundary condition to a connection
if connection.is_a("IfcRelConnectsStructuralMember"):
related_connection = connection.RelatedStructuralConnection
else:
related_connection = connection
if related_connection.is_a("IfcStructuralPointConnection"):
boundary_class = "IfcBoundaryNodeCondition"
elif related_connection.is_a("IfcStructuralCurveConnection"):
boundary_class = "IfcBoundaryEdgeCondition"
elif related_connection.is_a("IfcStructuralSurfaceConnection"):
boundary_class = "IfcBoundaryFaceCondition"
condition = file.create_entity(boundary_class, Name=name)
connection.AppliedCondition = condition
return condition
else:
# add an orphan boundary condition
return file.create_entity(ifc_class, Name=name)
@@ -0,0 +1,46 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
from typing import Optional
import ifcopenshell.api
def add_structural_load(
file: ifcopenshell.file, name: Optional[str] = None, ifc_class: str = "IfcStructuralLoadLinearForce"
) -> ifcopenshell.entity_instance:
"""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
:param ifc_class: The subtype of IfcStructuralLoad to create. Consult
the IFC documentation to see all the types of loads.
:return: The newly created load entity, depending on the ifc_class
specified.
Example:
.. code:: python
# Create a simple linear load
ifcopenshell.api.structural.add_structural_load(model)
"""
return file.create_entity(ifc_class, Name=name)
@@ -0,0 +1,41 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell.api.root
def add_structural_load_case(
file: ifcopenshell.file, name: str = "Unnamed", action_type: str = "NOTDEFINED", action_source: str = "NOTDEFINED"
) -> ifcopenshell.entity_instance:
"""Adds a new load case, which is a collection of related load groups
:param name: The name of the load case
:param action_type: Choose from EXTRAORDINARY_A, PERMANENT_G,
or VARIABLE_Q, taken from the Eurocode standard.
: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.
:return: The new IfcStructuralLoadCase
"""
load_case = ifcopenshell.api.root.create_entity(
file, ifc_class="IfcStructuralLoadCase", predefined_type="LOAD_CASE", name=name
)
load_case.ActionType = action_type
load_case.ActionSource = action_source
return load_case
@@ -0,0 +1,44 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell.api.root
def add_structural_load_group(
file: ifcopenshell.file, name: str = "Unnamed", action_type: str = "NOTDEFINED", action_source: str = "NOTDEFINED"
) -> ifcopenshell.entity_instance:
"""Adds a new load group, which is a collection of related loads
:param name: The name of the load group
:param action_type: Choose from EXTRAORDINARY_A, PERMANENT_G,
or VARIABLE_Q, taken from the Eurocode standard.
: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.
:return: The new IfcStructuralLoadCase
"""
load_group = ifcopenshell.api.root.create_entity(
file,
ifc_class="IfcStructuralLoadGroup",
predefined_type="LOAD_GROUP",
name=name,
)
load_group.ActionType = action_type
load_group.ActionSource = action_source
return load_group
@@ -0,0 +1,43 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import ifcopenshell.api.root
def add_structural_member_connection(
file: ifcopenshell.file,
relating_structural_member: ifcopenshell.entity_instance,
related_structural_connection: ifcopenshell.entity_instance,
) -> ifcopenshell.entity_instance:
"""Relates a structural member and a structural connection
:param relating_structural_member: The IfcStructuralMember to have a
connection added to it.
:param related_structural_connection: The IfcStructuralConnection to add
to the IfcStructuralMember.
:return: The IfcRelConnectsStructuralMember relationship
"""
for connection in related_structural_connection.ConnectsStructuralMembers or []:
if connection.RelatingStructuralMember == relating_structural_member:
return connection
rel = ifcopenshell.api.root.create_entity(file, ifc_class="IfcRelConnectsStructuralMember")
rel.RelatingStructuralMember = relating_structural_member
rel.RelatedStructuralConnection = related_structural_connection
return rel
@@ -0,0 +1,64 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2026 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
# This file was generated with the assistance of an AI coding tool.
import ifcopenshell
import ifcopenshell.api.root
def assign_product(
file: ifcopenshell.file,
relating_product: ifcopenshell.entity_instance,
related_object: ifcopenshell.entity_instance,
) -> ifcopenshell.entity_instance:
"""Links an object to a product via IfcRelAssignsToProduct
Typically used to associate a physical building element with a structural
analysis member (IfcStructuralSurfaceMember, IfcStructuralCurveMember) so
that analysis results can be traced back to the physical model.
:param relating_product: The IfcProduct that the object is assigned to,
typically an IfcStructuralMember.
:param related_object: The IfcObjectDefinition being assigned, typically
a physical building element such as an IfcWall or IfcSlab.
:return: The IfcRelAssignsToProduct relationship.
Example:
.. code:: python
wall = ifcopenshell.api.root.create_entity(model, ifc_class="IfcWall")
member = ifcopenshell.api.root.create_entity(
model, ifc_class="IfcStructuralSurfaceMember")
ifcopenshell.api.structural.assign_product(model,
relating_product=member, related_object=wall)
"""
for rel in relating_product.ReferencedBy or []:
if not rel.is_a("IfcRelAssignsToProduct"):
continue
if related_object in rel.RelatedObjects:
return rel
related_objects = list(rel.RelatedObjects)
related_objects.append(related_object)
rel.RelatedObjects = related_objects
return rel
rel = ifcopenshell.api.root.create_entity(file, ifc_class="IfcRelAssignsToProduct")
rel.RelatingProduct = relating_product
rel.RelatedObjects = [related_object]
return rel
@@ -0,0 +1,37 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
from typing import Union
import ifcopenshell
import ifcopenshell.api.group
def assign_structural_analysis_model(
file: ifcopenshell.file,
products: list[ifcopenshell.entity_instance],
structural_analysis_model: ifcopenshell.entity_instance,
) -> Union[ifcopenshell.entity_instance, None]:
"""Assigns a load or structural member to an analysis model
:param products: The structural elements that is part of the analysis.
:param structural_analysis_model: The IfcStructuralAnalysisModel that
the structural element is related to.
:return: The IfcRelAssignsToGroup relationship
"""
return ifcopenshell.api.group.assign_group(file, products, structural_analysis_model)
@@ -0,0 +1,64 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2026 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
# This file was generated with the assistance of an AI coding tool.
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
def assign_to_building(
file: ifcopenshell.file,
structural_analysis_model: ifcopenshell.entity_instance,
building: ifcopenshell.entity_instance,
) -> ifcopenshell.entity_instance:
"""Associates a structural analysis model with a building via IfcRelServicesBuildings
The existing :func:`assign_structural_analysis_model` handles
IfcRelAssignsToGroup (linking structural members to the analysis model).
This function handles the separate model-to-building relationship, which
records which building the structural analysis model serves.
:param structural_analysis_model: The IfcStructuralAnalysisModel to
associate with the building.
:param building: The IfcBuilding (or other IfcSpatialStructureElement)
that the structural analysis model serves.
:return: The IfcRelServicesBuildings relationship.
Example:
.. code:: python
building = ifcopenshell.util.selector.filter_elements(model, "IfcBuilding")[0]
model_ = ifcopenshell.api.structural.add_structural_analysis_model(model)
ifcopenshell.api.structural.assign_to_building(model,
structural_analysis_model=model_, building=building)
"""
for rel in structural_analysis_model.ServicesBuildings or []:
if building in rel.RelatedBuildings:
return rel
rel.RelatedBuildings = list(rel.RelatedBuildings) + [building]
return rel
return file.create_entity(
"IfcRelServicesBuildings",
ifcopenshell.guid.new(),
OwnerHistory=ifcopenshell.api.owner.create_owner_history(file),
RelatingSystem=structural_analysis_model,
RelatedBuildings=[building],
)
@@ -0,0 +1,36 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
from typing import Any
import ifcopenshell
def edit_structural_analysis_model(
file: ifcopenshell.file, structural_analysis_model: ifcopenshell.entity_instance, attributes: dict[str, Any]
) -> 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
:param attributes: a dictionary of attribute names and values.
:return: None
"""
for name, value in attributes.items():
setattr(structural_analysis_model, name, value)
@@ -0,0 +1,53 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
from typing import Any, Literal, TypedDict, Union
import ifcopenshell
class AttributeDict(TypedDict):
type: Union[
Literal["string", "null"],
str, # IFC Class.
]
value: Any
def edit_structural_boundary_condition(
file: ifcopenshell.file,
condition: ifcopenshell.entity_instance,
attributes: dict[str, AttributeDict],
) -> 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
:param attributes: a dictionary of attribute names and values.
Each value is represented by a dictionary.
:return: None
"""
for name, data in attributes.items():
if data["type"] == "string" or data["type"] == "null":
value = data["value"]
elif data["type"] == "IfcBoolean":
value = file.createIfcBoolean(data["value"])
else:
value = file.create_entity(data["type"], data["value"])
setattr(condition, name, value)
@@ -0,0 +1,48 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
from ifcopenshell.util.shape_builder import VectorType, ifc_safe_vector_type
def edit_structural_connection_cs(
file: ifcopenshell.file,
structural_item: ifcopenshell.entity_instance,
axis: VectorType = (0.0, 0.0, 1.0),
ref_direction: VectorType = (1.0, 0.0, 0.0),
) -> None:
"""Edits the coordinate system of a structural connection
:param structural_item: The IfcStructuralItem you want to modify.
:param axis: The unit Z axis vector defined as a list of 3 floats.
Defaults to (0., 0., 1.).
:param ref_direction: The unit X axis vector defined as a list of 3
floats. Defaults to (1., 0., 0.).
:return: None
"""
if structural_item.ConditionCoordinateSystem is None:
point = file.createIfcCartesianPoint((0.0, 0.0, 0.0))
ccs = file.createIfcAxis2Placement3D(point, None, None)
structural_item.ConditionCoordinateSystem = ccs
ccs = structural_item.ConditionCoordinateSystem
if (current_axis := ccs.Axis) and file.get_total_inverses(current_axis) == 1:
file.remove(current_axis)
ccs.Axis = file.create_entity("IfcDirection", ifc_safe_vector_type(axis))
if (prev_ref_direction := ccs.RefDirection) and file.get_total_inverses(prev_ref_direction) == 1:
file.remove(prev_ref_direction)
ccs.RefDirection = file.create_entity("IfcDirection", ifc_safe_vector_type(ref_direction))
@@ -0,0 +1,36 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
from ifcopenshell.util.shape_builder import VectorType, ifc_safe_vector_type
def edit_structural_item_axis(
file: ifcopenshell.file,
structural_item: ifcopenshell.entity_instance,
axis: VectorType = (0.0, 0.0, 1.0),
) -> None:
"""Edits the coordinate system of a structural connection
:param structural_item: The IfcStructuralItem you want to modify.
:param axis: The unit Z axis vector defined as a list of 3 floats.
Defaults to (0., 0., 1.).
:return: None
"""
if file.get_total_inverses(axis_dir := structural_item.Axis) == 1:
file.remove(axis_dir)
structural_item.Axis = file.create_entity("IfcDirection", ifc_safe_vector_type(axis))
@@ -0,0 +1,36 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
from typing import Any
import ifcopenshell
def edit_structural_load(
file: ifcopenshell.file, structural_load: ifcopenshell.entity_instance, attributes: dict[str, Any]
) -> 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
:param attributes: a dictionary of attribute names and values.
:return: None
"""
for name, value in attributes.items():
setattr(structural_load, name, value)
@@ -0,0 +1,36 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
from typing import Any
import ifcopenshell
def edit_structural_load_case(
file: ifcopenshell.file, load_case: ifcopenshell.entity_instance, attributes: dict[str, Any]
) -> 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
:param attributes: a dictionary of attribute names and values.
:return: None
"""
for name, value in attributes.items():
setattr(load_case, name, value)
@@ -0,0 +1,42 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import ifcopenshell.util.element
def remove_structural_analysis_model(
file: ifcopenshell.file, structural_analysis_model: ifcopenshell.entity_instance
) -> None:
"""Removes an analysis model
Note that the contents of an analysis model are currently preserved.
:param structural_analysis_model: The IfcStructuralAnalysisModel to
remove.
:return: None
"""
for rel in structural_analysis_model.IsGroupedBy or []:
history = rel.OwnerHistory
file.remove(rel)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
history = structural_analysis_model.OwnerHistory
file.remove(structural_analysis_model)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
@@ -0,0 +1,49 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
from typing import Optional
import ifcopenshell
def remove_structural_boundary_condition(
file: ifcopenshell.file,
connection: Optional[ifcopenshell.entity_instance] = None,
boundary_condition: Optional[ifcopenshell.entity_instance] = None,
) -> None:
"""Removes a condition from a connection, or an orphaned boundary condition
:param connection: The IfcStructuralConnection to remove the condition
from. If omitted, it is assumed to be an orphaned condition.
:param boundary_condition: The IfcBoundaryCondition to remove.
:return: None
"""
if connection:
# remove boundary condition from a connection
if not connection.AppliedCondition:
return
applied_condition = connection.AppliedCondition
if file.get_total_inverses(applied_condition) == 1:
file.remove(applied_condition)
connection.AppliedCondition = None
else:
assert boundary_condition, "Either connection or boundary_condition must be provided."
# remove the boundary condition
for conn in file.get_inverse(boundary_condition):
conn.AppliedCondition = None
file.remove(boundary_condition)
@@ -0,0 +1,40 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import ifcopenshell.api.structural
import ifcopenshell.util.element
def remove_structural_connection_condition(file: ifcopenshell.file, relation: ifcopenshell.entity_instance) -> None:
"""Removes a relationship between a connection and a condition
The condition and the member itself is preserved.
:param relation: The IfcRelConnectsStructuralMember to remove.
:return: None
"""
if relation.AppliedCondition:
ifcopenshell.api.structural.remove_structural_boundary_condition(
file,
connection=relation.RelatedStructuralConnection,
)
history = relation.OwnerHistory
file.remove(relation)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
@@ -0,0 +1,27 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
def remove_structural_load(file: ifcopenshell.file, structural_load: ifcopenshell.entity_instance) -> None:
"""Removes a structural load
:param structural_load: The IfcStructuralLoad to remove.
:return: None
"""
file.remove(structural_load)
@@ -0,0 +1,37 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import ifcopenshell.util.element
def remove_structural_load_case(file: ifcopenshell.file, load_case: ifcopenshell.entity_instance) -> None:
"""Removes a structural load case
:param load_case: The IfcStructuralLoadCase to remove.
:return: None
"""
# TODO: do a deep purge
for rel in load_case.IsGroupedBy or []:
history = rel.OwnerHistory
file.remove(rel)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
history = load_case.OwnerHistory
file.remove(load_case)
ifcopenshell.util.element.remove_deep2(file, history)
@@ -0,0 +1,39 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import ifcopenshell.util.element
def remove_structural_load_group(file: ifcopenshell.file, load_group: ifcopenshell.entity_instance) -> None:
"""Removes a structural load group
:param load_group: The IfcStructuralLoadGroup to remove.
:return: None
"""
# TODO: do a deep purge
for inverse in file.get_inverse(load_group):
if inverse.is_a("IfcRelAssignsToGroup") and len(inverse.RelatedObjects) == 1:
history = inverse.OwnerHistory
file.remove(inverse)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
history = load_group.OwnerHistory
file.remove(load_group)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
@@ -0,0 +1,35 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import ifcopenshell.api.group
def unassign_structural_analysis_model(
file: ifcopenshell.file,
products: list[ifcopenshell.entity_instance],
structural_analysis_model: ifcopenshell.entity_instance,
) -> None:
"""Removes a relationship between a structural element and the analysis model
:param products: The structural elements that is part of the analysis.
:param structural_analysis_model: The IfcStructuralAnalysisModel that
the structural element is related to.
:return: None
"""
ifcopenshell.api.group.unassign_group(file, products, structural_analysis_model)