Merge remote-tracking branch 'origin/v0.8.0' into datamodel-v1.0

This commit is contained in:
Thomas Krijnen
2026-04-18 20:15:28 +02:00
1655 changed files with 105534 additions and 46934 deletions
@@ -53,14 +53,16 @@ Example:
for wall in walls:
print(wall.Name)
"""
from __future__ import annotations
import os
import sys
import zipfile
import tempfile
from pathlib import Path
from typing import Optional, Union, TYPE_CHECKING, Any, overload, Literal
import zipfile
from collections.abc import Generator, Sequence
from pathlib import Path
from typing import TYPE_CHECKING, Any, Literal, Optional, Union, overload
if TYPE_CHECKING:
import ifcopenshell.express.schema_class
@@ -88,12 +90,10 @@ except Exception:
# `_file`, `_stream` is used only for annotations inside this file,
# see https://github.com/microsoft/pyright/discussions/9065.
from .ifcopenshell_wrapper import file as _file
from .ifcopenshell_wrapper import file
from .file import rocksdb_lazy_instance
from . import guid
from .ifcopenshell_wrapper import entity_instance
from .entity_instance import entity_instance
from .file import file, rocksdb_lazy_instance
from .file import file as _file
from .sql import sqlite, sqlite_entity
# explicitly specify available imported symbols
@@ -103,6 +103,7 @@ __all__ = [
"file",
"guid",
"ifcopenshell_wrapper",
"rocksdb_lazy_instance",
"sqlite",
"sqlite_entity",
"stream",
@@ -110,8 +111,8 @@ __all__ = [
]
try:
from .stream import stream as _stream, stream_entity
from .stream import stream
from .stream import stream, stream_entity # ty: ignore[possibly-missing-import]
from .stream import stream as _stream # ty: ignore[possibly-missing-import]
except:
pass
@@ -130,17 +131,21 @@ class SchemaError(Error):
@overload
def open(
path: Union[os.PathLike, str], format: Optional[str] = None, *, should_stream: Literal[False] = False
path: Union[os.PathLike, str], format: SupportedFormat = None, *, should_stream: Literal[False] = False
) -> Union[_file, sqlite]: ...
@overload
def open(path: Union[os.PathLike, str], format: Optional[str] = None, *, should_stream: Literal[True]) -> _stream: ...
def open(path: Union[os.PathLike, str], format: SupportedFormat = None, *, should_stream: Literal[True]) -> _stream: ...
@overload
def open(
path: Union[os.PathLike, str], format: Optional[str] = None, *, should_stream: bool = False, readonly: bool = False
path: Union[os.PathLike, str],
format: SupportedFormat = None,
*,
should_stream: bool = False,
readonly: bool = False,
) -> Union[_file, sqlite, _stream]: ...
def open(
path: Union[os.PathLike, str],
format: Optional[str] = None,
format: SupportedFormat = None,
should_stream: bool = False,
readonly: bool = False,
mmap: bool = False,
@@ -152,8 +157,7 @@ def open(
for reading large files.
You can specify a file format. If no format is given, it is guessed from
its extension. Currently supported specified format: .ifc | .ifcZIP |
.ifcXML.
its extension.
You can then filter by element ID, class, etc, and subscript by id or guid.
@@ -199,11 +203,13 @@ def open(
for ty in bypass_types:
f.bypass_type(ty)
if mmap:
f.initialize(str(path.absolute()), mmap=mmap)
# mmap parameter is only available for builds with USE_MMAP, not used in our main builds
f.initialize(str(path.absolute()), mmap=mmap) # ty: ignore[unknown-argument]
else:
f.initialize(str(path.absolute()))
elif mmap:
f = ifcopenshell_wrapper.open(str(path.absolute()), mmap=mmap)
# mmap parameter is only available for builds with USE_MMAP, not used in our main builds
f = ifcopenshell_wrapper.open(str(path.absolute()), mmap=mmap) # ty: ignore[unknown-argument]
else:
f = ifcopenshell_wrapper.open(str(path.absolute()))
@@ -284,7 +290,10 @@ def schema_by_name(
return ifcopenshell_wrapper.schema_by_name(schema)
def guess_format(path: Path) -> Literal[".ifc", ".ifcZIP", ".ifcXML", ".ifcJSON", ".ifcSQLite", None]:
SupportedFormat = Literal[".ifc", ".ifcZIP", ".ifcXML", ".ifcJSON", ".ifcSQLite", "rocksdb", None]
def guess_format(path: Path) -> SupportedFormat:
"""Guesses the IFC format using file extension
IFCs may be serialised as different formats. The most common is a ``.ifc``
@@ -38,13 +38,15 @@ Also see how to `create a simple model from scratch
<https://docs.ifcopenshell.org/ifcopenshell-python/code_examples.html#create-a-simple-model-from-scratch>`_.
"""
import json
import numpy
import inspect
import importlib
import inspect
import json
from collections.abc import Callable
from typing import TYPE_CHECKING, Any, Optional
import numpy
import ifcopenshell
from typing import Callable, Any, Optional, TYPE_CHECKING
from functools import partial
if TYPE_CHECKING:
import ifcopenshell.api
@@ -87,11 +89,7 @@ def renamed_arguments_deprecation(
# "group.add_group": partial(
# renamed_arguments_deprecation, arguments_remapped={"Name": "name", "Description": "description"}
# ),
ARGUMENTS_DEPRECATION: dict[str, Callable[[str, dict[str, Any]], tuple[str, dict[str, Any]]]] = {
"control.assign_control": partial(
batching_argument_deprecation, prev_argument="related_object", new_argument="related_objects"
),
}
ARGUMENTS_DEPRECATION: dict[str, Callable[[str, dict[str, Any]], tuple[str, dict[str, Any]]]] = {}
CACHED_USECASE_CLASSES: dict[str, Callable] = {}
@@ -186,8 +184,8 @@ def remove_all_listeners():
def extract_docs(module: str, usecase: str) -> dict[str, Any]:
import typing
import collections
import typing
inputs = collections.OrderedDict()
@@ -303,8 +301,8 @@ def wrap_usecase(usecase_path, usecase):
def wrap_usecases(path, name):
"""This developer feature wraps an API module's usecases with listeners."""
import sys
import pkgutil
import sys
module_name = name.split(".")[-1]
module = sys.modules[name]
@@ -16,14 +16,15 @@
# 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.geometry
import ifcopenshell.api.owner
import ifcopenshell.api.spatial
import ifcopenshell.api.geometry
import ifcopenshell.guid
import ifcopenshell.util.element
import ifcopenshell.util.placement
from typing import Union
def assign_object(
@@ -47,45 +47,48 @@ Future versions of this API may support:
5. Adding a segment at any location along a curve
"""
from ._get_segment_start_point_label import register_referent_name_callback
from .add_stationing_referent import add_stationing_referent
from .add_vertical_layout import add_vertical_layout
from .add_zero_length_segment import add_zero_length_segment
from .create_layout_segment import create_layout_segment
from .create import create
from .create_as_offset_curve import create_as_offset_curve
from .create_as_polyline import create_as_polyline
from .create_by_pi_method import create_by_pi_method
from .create_from_csv import create_from_csv
from .create_segment_representations import create_segment_representations
from .create_layout_segment import create_layout_segment
from .create_representation import create_representation
from .create_segment_representations import create_segment_representations
from .distance_along_from_station import distance_along_from_station
from .get_alignment import get_alignment
from .get_alignment_layout_nest import get_alignment_layout_nest
from .get_alignment_layouts import get_alignment_layouts
from .get_alignment_segment_nest import get_alignment_segment_nest
from .get_alignment_start_station import get_alignment_start_station
from .get_curve_segment_transition_code import get_curve_segment_transition_code
from .get_layout_segments import get_layout_segments
from .get_horizontal_layout import get_horizontal_layout
from .get_vertical_layout import get_vertical_layout
from .get_cant_layout import get_cant_layout
from .get_alignment_layouts import get_alignment_layouts
from .get_axis_subcontext import get_axis_subcontext
from .get_basis_curve import get_basis_curve
from .get_cant_layout import get_cant_layout
from .get_child_alignments import get_child_alignments
from .get_curve import get_curve
from .get_curve_segment_transition_code import get_curve_segment_transition_code
from .get_horizontal_layout import get_horizontal_layout
from .get_layout_curve import get_layout_curve
from .get_layout_segments import get_layout_segments
from .get_mapped_segments import get_mapped_segments
from .get_parent_alignment import get_parent_alignment
from .get_referent_nest import get_referent_nest
from .get_vertical_layout import get_vertical_layout
from .has_zero_length_segment import has_zero_length_segment
from .layout_horizontal_alignment_by_pi_method import layout_horizontal_alignment_by_pi_method
from .layout_vertical_alignment_by_pi_method import layout_vertical_alignment_by_pi_method
from .layout_horizontal_alignment_by_pi_method import (
layout_horizontal_alignment_by_pi_method,
)
from .layout_vertical_alignment_by_pi_method import (
layout_vertical_alignment_by_pi_method,
)
from .name_segments import name_segments
from .update_fallback_position import update_fallback_position
from .util import *
from ._get_segment_start_point_label import register_referent_name_callback
__all__ = [
"add_stationing_referent",
"add_vertical_layout",
@@ -122,4 +125,5 @@ __all__ = [
"name_segments",
"register_referent_name_callback",
"update_fallback_position",
"get_mapped_segments",
]
@@ -16,19 +16,26 @@
# 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 numpy as np
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.alignment
import ifcopenshell.geom
import ifcopenshell.util.unit
import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
import numpy as np
import ifcopenshell.util.unit
from ifcopenshell import entity_instance
from ifcopenshell.api.alignment._update_curve_segment_transition_code import _update_curve_segment_transition_code
from ifcopenshell.api.alignment._map_alignment_horizontal_segment import _map_alignment_horizontal_segment
from ifcopenshell.api.alignment._map_alignment_vertical_segment import _map_alignment_vertical_segment
from ifcopenshell.api.alignment._map_alignment_cant_segment import _map_alignment_cant_segment
from ifcopenshell.api.alignment._map_alignment_cant_segment import (
_map_alignment_cant_segment,
)
from ifcopenshell.api.alignment._map_alignment_horizontal_segment import (
_map_alignment_horizontal_segment,
)
from ifcopenshell.api.alignment._map_alignment_vertical_segment import (
_map_alignment_vertical_segment,
)
from ifcopenshell.api.alignment._update_curve_segment_transition_code import (
_update_curve_segment_transition_code,
)
def _add_curve_segment_to_composite_curve(
@@ -16,6 +16,10 @@
# 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 math
import numpy as np
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.api.nest
@@ -23,14 +27,11 @@ import ifcopenshell.api.pset
import ifcopenshell.geom
import ifcopenshell.util.alignment
import ifcopenshell.util.unit
from ifcopenshell import ifcopenshell_wrapper
import numpy as np
import math
from ifcopenshell import entity_instance
from collections.abc import Sequence
from ifcopenshell import entity_instance, ifcopenshell_wrapper
from ifcopenshell.api.alignment._add_segment_to_curve import _add_segment_to_curve
from ifcopenshell.api.alignment._get_segment_start_point_label import _get_segment_start_point_label
from ifcopenshell.api.alignment._get_segment_start_point_label import (
_get_segment_start_point_label,
)
def _add_segment_to_layout(file: ifcopenshell.file, layout: entity_instance, segment: entity_instance) -> None:
@@ -18,11 +18,11 @@
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.util
import ifcopenshell.util.alignment
from ifcopenshell import entity_instance
from ifcopenshell.api.alignment._get_segment_start_point_label import _get_segment_start_point_label
from ifcopenshell.api.alignment._get_segment_start_point_label import (
_get_segment_start_point_label,
)
def _add_zero_length_segment(file: ifcopenshell.file, layout: entity_instance) -> None:
@@ -16,14 +16,12 @@
# 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.alignment
import ifcopenshell.api.geometry
from ifcopenshell import entity_instance
import math
from collections.abc import Sequence
def _create_geometric_representation(file: ifcopenshell.file, alignment: entity_instance) -> None:
"""
@@ -16,20 +16,19 @@
# 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 collections.abc import Sequence
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.api.geometry
from ifcopenshell import entity_instance
import math
from collections.abc import Sequence
def _create_offset_curve_representation(
file: ifcopenshell.file, alignment: entity_instance, offsets: Sequence[entity_instance]
) -> None:
"""
Create geometric representation for the alignment based on an IfcPolyline
Create geometric representation for the alignment based on an IfcOffsetByDistances curve
:param alignment: The alignment for which the representation is being created
:return: None
@@ -38,6 +37,11 @@ def _create_offset_curve_representation(
if not alignment.is_a(expected_type):
raise TypeError(f"Expected {expected_type} but got {alignment.is_a()}")
expected_type = "IfcPointByDistanceExpression"
for offset in offsets:
if not offset.is_a(expected_type):
raise TypeError(f"Expected {expected_type} but got {offset.is_a()}")
axis_geom_subcontext = ifcopenshell.api.alignment.get_axis_subcontext(file)
basis_curve = offsets[0].BasisCurve # IfcPointByDistanceExpression.BasisCurve
@@ -16,14 +16,13 @@
# 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 collections.abc import Sequence
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.api.geometry
from ifcopenshell import entity_instance
import math
from collections.abc import Sequence
def _create_polyline_representation(
file: ifcopenshell.file, alignment: entity_instance, points: Sequence[entity_instance]
@@ -16,13 +16,9 @@
# 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.alignment
import ifcopenshell.api.geometry
from ifcopenshell import entity_instance
import math
from collections.abc import Sequence
import ifcopenshell.api.alignment
from ifcopenshell import entity_instance
def _get_cant_segment(horizontal_segment: entity_instance) -> entity_instance:
@@ -16,10 +16,8 @@
# 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 import entity_instance
from collections.abc import Sequence
from ifcopenshell import entity_instance
_horizontal_callback = None
_vertical_callback = None
@@ -16,11 +16,11 @@
# 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 math
from collections.abc import Sequence
import ifcopenshell
from ifcopenshell import entity_instance
from ifcopenshell.api.alignment import get_axis_subcontext
from collections.abc import Sequence
import math
def _get_axis(file: ifcopenshell.file, Ds: float, rail_head_distance: float) -> entity_instance:
@@ -16,14 +16,13 @@
# 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 import entity_instance
import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
import ifcopenshell.util
import ifcopenshell.util.unit
from collections.abc import Sequence
import math
from collections.abc import Sequence
import ifcopenshell
import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
import ifcopenshell.util.unit
from ifcopenshell import entity_instance
from ifcopenshell.api.alignment._get_cant_segment import _get_cant_segment
@@ -16,11 +16,11 @@
# 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 import ifcopenshell_wrapper
from ifcopenshell import entity_instance
from collections.abc import Sequence
import math
from collections.abc import Sequence
import ifcopenshell
from ifcopenshell import entity_instance
def _polynomial_length(A: float, B: float, C: float, L: float) -> float:
@@ -16,13 +16,9 @@
# 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.alignment
from ifcopenshell import ifcopenshell_wrapper
import ifcopenshell.geom
from ifcopenshell import entity_instance
import numpy as np
import math
def _update_curve_segment_transition_code(prev_segment: entity_instance, segment: entity_instance) -> None:
@@ -16,17 +16,16 @@
# 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 numpy as np
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.api.nest
import ifcopenshell.api.pset
import ifcopenshell.geom
import ifcopenshell.guid
import ifcopenshell.util.element
import ifcopenshell.util.unit
from ifcopenshell import entity_instance
from ifcopenshell import ifcopenshell_wrapper
import numpy as np
from ifcopenshell import entity_instance, ifcopenshell_wrapper
def add_stationing_referent(
@@ -24,9 +24,7 @@ import ifcopenshell.api.nest
import ifcopenshell.guid
import ifcopenshell.util.element
import ifcopenshell.util.representation
import ifcopenshell.api
from ifcopenshell import entity_instance
from ifcopenshell.api.alignment._add_zero_length_segment import _add_zero_length_segment
@@ -16,21 +16,30 @@
# 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 math
import numpy as np
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.api.nest
import ifcopenshell.geom
import ifcopenshell.util.alignment
from ifcopenshell import entity_instance
import ifcopenshell.ifcopenshell_wrapper as wrapper
import ifcopenshell.util.alignment
import ifcopenshell.util.unit
import numpy as np
import math
from ifcopenshell.api.alignment._get_segment_start_point_label import _get_segment_start_point_label
from ifcopenshell.api.alignment._map_alignment_horizontal_segment import _map_alignment_horizontal_segment
from ifcopenshell.api.alignment._map_alignment_vertical_segment import _map_alignment_vertical_segment
from ifcopenshell.api.alignment._update_curve_segment_transition_code import _update_curve_segment_transition_code
from ifcopenshell import entity_instance
from ifcopenshell.api.alignment._get_segment_start_point_label import (
_get_segment_start_point_label,
)
from ifcopenshell.api.alignment._map_alignment_horizontal_segment import (
_map_alignment_horizontal_segment,
)
from ifcopenshell.api.alignment._map_alignment_vertical_segment import (
_map_alignment_vertical_segment,
)
from ifcopenshell.api.alignment._update_curve_segment_transition_code import (
_update_curve_segment_transition_code,
)
def add_zero_length_segment(file: ifcopenshell.file, layout: entity_instance, include_referent: bool = True) -> bool:
@@ -21,11 +21,11 @@ import ifcopenshell.api.aggregate
import ifcopenshell.api.alignment
import ifcopenshell.api.nest
import ifcopenshell.util.alignment
from ifcopenshell import entity_instance
from ifcopenshell.api.alignment._create_geometric_representation import _create_geometric_representation
from ifcopenshell.api.alignment._add_zero_length_segment import _add_zero_length_segment
from ifcopenshell.api.alignment._create_geometric_representation import (
_create_geometric_representation,
)
def create(
@@ -16,17 +16,14 @@
# 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 collections.abc import Sequence
import ifcopenshell
import ifcopenshell.api.aggregate
import ifcopenshell.api.alignment
import ifcopenshell.api.nest
import ifcopenshell.util.alignment
from ifcopenshell import entity_instance
from ifcopenshell.api.alignment._create_offset_curve_representation import _create_offset_curve_representation
from collections.abc import Sequence
from ifcopenshell.api.alignment._create_offset_curve_representation import (
_create_offset_curve_representation,
)
def create_as_offset_curve(
@@ -42,7 +39,7 @@ def create_as_offset_curve(
:param file:
:param name: name assigned to IfcAlignment.Name
:param offsets: offsets from the basis curve that defines the offset curve, expected to be IfcOffsetCurveByDistances.
:param offsets: offsets from the basis curve that defines the offset curve, expected to be IfcPointByDistanceExpression.
:param start_station: station value at the start of the alignment
:return: Returns an IfcAlignment
"""
@@ -16,18 +16,18 @@
# 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 math
from collections.abc import Sequence
import ifcopenshell
import ifcopenshell.api.aggregate
import ifcopenshell.api.alignment
import ifcopenshell.api.nest
import ifcopenshell.util.alignment
from ifcopenshell import entity_instance
from ifcopenshell.api.alignment._create_polyline_representation import _create_polyline_representation
import math
from collections.abc import Sequence
from ifcopenshell.api.alignment._create_polyline_representation import (
_create_polyline_representation,
)
def _create_layout(file: ifcopenshell.file, alignment: entity_instance, points: Sequence[entity_instance]):
@@ -16,13 +16,12 @@
# 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.aggregate
import ifcopenshell.api.alignment
import ifcopenshell.api.nest
from ifcopenshell import entity_instance
from collections.abc import Sequence
import ifcopenshell
import ifcopenshell.api.alignment
from ifcopenshell import entity_instance
def create_by_pi_method(
file: ifcopenshell.file,
@@ -16,15 +16,11 @@
# 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 csv
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.api
from ifcopenshell import entity_instance
from ifcopenshell.api.alignment import get_axis_subcontext
from collections.abc import Sequence
import csv
def create_from_csv(file: ifcopenshell.file, filepath: str) -> entity_instance:
@@ -16,15 +16,14 @@
# 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 numpy as np
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.geom
from ifcopenshell import entity_instance
import math
from ifcopenshell import ifcopenshell_wrapper
import numpy as np
from typing import Union
from ifcopenshell import entity_instance, ifcopenshell_wrapper
from ifcopenshell.api.alignment._add_segment_to_layout import _add_segment_to_layout
@@ -19,9 +19,10 @@
import ifcopenshell
import ifcopenshell.api.alignment
from ifcopenshell import entity_instance
from ifcopenshell.api.alignment._create_geometric_representation import _create_geometric_representation
from ifcopenshell.api.alignment._add_segment_to_curve import _add_segment_to_curve
from ifcopenshell.api.alignment._create_geometric_representation import (
_create_geometric_representation,
)
def create_representation(
@@ -17,9 +17,9 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.util.element
import ifcopenshell.util.representation
import ifcopenshell.api.alignment
from ifcopenshell import entity_instance
@@ -16,7 +16,6 @@
# 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 import entity_instance
@@ -16,12 +16,9 @@
# 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
from ifcopenshell import entity_instance
from collections.abc import Sequence
import ifcopenshell.util.representation
from ifcopenshell import entity_instance
def get_alignment_layouts(alignment: entity_instance) -> Sequence[entity_instance]:
@@ -16,7 +16,6 @@
# 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 import entity_instance
@@ -17,8 +17,8 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import ifcopenshell.util.representation
import ifcopenshell.api.context
import ifcopenshell.util.representation
from ifcopenshell import entity_instance
@@ -16,11 +16,8 @@
# 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
from ifcopenshell import entity_instance
import ifcopenshell.util.representation
from ifcopenshell import entity_instance
def get_basis_curve(alignment: entity_instance) -> entity_instance:
@@ -16,12 +16,9 @@
# 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
from ifcopenshell import entity_instance
from collections.abc import Sequence
import ifcopenshell.util.element
from ifcopenshell import entity_instance
def get_child_alignments(alignment: entity_instance) -> Sequence[entity_instance]:
@@ -16,11 +16,8 @@
# 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
from ifcopenshell import entity_instance
import ifcopenshell.util.representation
from ifcopenshell import entity_instance
def get_curve(alignment: entity_instance) -> entity_instance:
@@ -16,13 +16,11 @@
# 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
from ifcopenshell import ifcopenshell_wrapper
import ifcopenshell.geom
from ifcopenshell import entity_instance
import numpy as np
import math
import ifcopenshell.geom
from ifcopenshell import entity_instance, ifcopenshell_wrapper
def get_curve_segment_transition_code(
@@ -16,7 +16,6 @@
# 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.alignment
from ifcopenshell import entity_instance
@@ -16,12 +16,9 @@
# 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
from ifcopenshell import entity_instance
from collections.abc import Sequence
import ifcopenshell.util.element
from ifcopenshell import entity_instance
def get_layout_segments(layout: entity_instance) -> Sequence[entity_instance]:
@@ -16,10 +16,10 @@
# 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 collections.abc import Sequence
import ifcopenshell.api.alignment
from ifcopenshell import entity_instance
from collections.abc import Sequence
def _get_curve_segment_count(segment: entity_instance) -> int:
@@ -16,12 +16,8 @@
# 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
from ifcopenshell import entity_instance
import ifcopenshell.util.representation
def get_parent_alignment(alignment: entity_instance) -> entity_instance:
"""
@@ -16,9 +16,6 @@
# 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.alignment
import ifcopenshell.util.element
from ifcopenshell import entity_instance
@@ -16,15 +16,13 @@
# 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.alignment
from ifcopenshell import entity_instance
import math
from collections.abc import Sequence
import ifcopenshell.util
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.util.unit
from ifcopenshell import entity_instance
def layout_horizontal_alignment_by_pi_method(
@@ -16,13 +16,13 @@
# 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 math
from collections.abc import Sequence
import ifcopenshell
import ifcopenshell.api.alignment
from ifcopenshell import entity_instance
import math
from collections.abc import Sequence
def layout_vertical_alignment_by_pi_method(
file: ifcopenshell.file, layout: entity_instance, vpoints: Sequence[Sequence[float]], lengths: Sequence[float]
@@ -16,7 +16,6 @@
# 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 import entity_instance
@@ -16,10 +16,11 @@
# 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 numpy as np
import ifcopenshell
import ifcopenshell.util.placement
from ifcopenshell import entity_instance
import numpy as np
def update_fallback_position(file: ifcopenshell.file, lp: entity_instance):
@@ -16,20 +16,12 @@
# 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.alignment
import math
import numpy as np
import ifcopenshell
import ifcopenshell.geom
import ifcopenshell.guid
import ifcopenshell.template
from ifcopenshell import entity_instance
from ifcopenshell import ifcopenshell_wrapper
import ifcopenshell.util
import ifcopenshell.util.alignment
from ifcopenshell import entity_instance, ifcopenshell_wrapper
def evaluate_representation(shape_rep: entity_instance, dist_along: float) -> np.ndarray:
@@ -16,15 +16,11 @@
# 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 sys
import ifcopenshell.api.owner
import ifcopenshell.util.element
from types import EllipsisType
from typing import Any, Union
if sys.version_info >= (3, 10):
from types import EllipsisType
else:
EllipsisType = type(...)
import ifcopenshell.api.owner
import ifcopenshell.util.element
def edit_attributes(file: ifcopenshell.file, product: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
@@ -16,10 +16,12 @@
# 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.util.unit
from typing import Optional
import numpy as np
import numpy.typing as npt
from typing import Optional
import ifcopenshell.util.unit
from ifcopenshell.util.shape_builder import SequenceOfVectors, V, ifc_safe_vector_type
@@ -106,7 +108,7 @@ class Usecase:
self.rel_space_boundary.ConnectionGeometry = connection_geometry
def create_point(self, point: npt.NDArray) -> ifcopenshell.entity_instance:
return self.file.create_enitty("IfcCartesianPoint", ifc_safe_vector_type(point / self.unit_scale))
return self.file.create_entity("IfcCartesianPoint", ifc_safe_vector_type(point / self.unit_scale))
def close_polyline(
self, points: tuple[ifcopenshell.entity_instance, ...]
@@ -125,7 +127,7 @@ class Usecase:
return self.file.createIfcPlane(
self.file.createIfcAxis2Placement3D(
self.create_point(location),
self.file.createIfcDirection(axis),
self.file.createIfcDirection(ref_direction),
self.file.createIfcDirection(ifc_safe_vector_type(axis)),
self.file.createIfcDirection(ifc_safe_vector_type(ref_direction)),
)
)
@@ -15,9 +15,10 @@
#
# 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 typing import Optional
import ifcopenshell
def edit_attributes(
file: ifcopenshell.file,
@@ -26,12 +27,11 @@ def edit_attributes(
related_building_element: ifcopenshell.entity_instance,
parent_boundary: Optional[ifcopenshell.entity_instance] = None,
corresponding_boundary: Optional[ifcopenshell.entity_instance] = None,
physical_or_virtual: str = "NOTDEFINED",
internal_or_external: str = "NOTDEFINED",
) -> None:
"""Modify the relationships of a space boundary relationship
Currently this function is quite minimal and offers no advantage to
manual assignment of the space boundary attributes.
:param entity: The IfcRelSpaceBoundary to modify
:param relating_space: The IfcSpace or IfcExternalSpatialElement that
the space boundary is related to.
@@ -43,17 +43,18 @@ def edit_attributes(
:param corresponding_boundary: The other IfcRelSpaceBoundary on the
other side of the related element. The pair together represents a
thermal boundary. This only applies to 2nd level boundaries.
:param physical_or_virtual: IfcPhysicalOrVirtualEnum value: "PHYSICAL",
"VIRTUAL", or "NOTDEFINED".
:param internal_or_external: IfcInternalOrExternalEnum value:
"INTERNAL", "EXTERNAL", "EXTERNAL_EARTH", "EXTERNAL_WATER",
"EXTERNAL_FIRE", or "NOTDEFINED".
:return: None
"""
entity = entity
relating_space = relating_space
related_building_element = related_building_element
parent_boundary = parent_boundary
corresponding_boundary = corresponding_boundary
entity.RelatingSpace = relating_space
entity.RelatedBuildingElement = related_building_element
if hasattr(entity, "ParentBoundary"):
entity.ParentBoundary = parent_boundary
if hasattr(entity, "CorrespondingBoundary"):
entity.CorrespondingBoundary = corresponding_boundary
entity.PhysicalOrVirtualBoundary = physical_or_virtual
entity.InternalOrExternalBoundary = internal_or_external
@@ -16,11 +16,12 @@
# 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.guid
import ifcopenshell.util.schema
import ifcopenshell.util.date
from typing import Union, Any
import ifcopenshell.util.schema
def add_classification(
@@ -16,12 +16,13 @@
# 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, Optional, Union
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
import ifcopenshell.util.element
import ifcopenshell.util.schema
from typing import Optional, Union, Any
def add_reference(
@@ -15,9 +15,10 @@
#
# 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 typing import Any
import ifcopenshell
def edit_classification(
file: ifcopenshell.file, classification: ifcopenshell.entity_instance, attributes: dict[str, Any]
@@ -15,9 +15,10 @@
#
# 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 typing import Any
import ifcopenshell
def edit_reference(
file: ifcopenshell.file, reference: ifcopenshell.entity_instance, attributes: dict[str, Any]
@@ -22,8 +22,8 @@ Coordinate Geometry (cogo) functions primarily for survey points and control mon
from .add_survey_point import add_survey_point
from .assign_survey_point import assign_survey_point
from .edit_survey_point import edit_survey_point
from .bearing2dd import bearing2dd
from .edit_survey_point import edit_survey_point
__all__ = [
"add_survey_point",
@@ -16,11 +16,12 @@
# 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.spatial
import ifcopenshell.util.representation
from ifcopenshell import entity_instance
from typing import Union
def add_survey_point(
@@ -16,9 +16,8 @@
# 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 import entity_instance
import typing
def assign_survey_point(annotation: entity_instance, survey_point: entity_instance):
@@ -16,9 +16,8 @@
# 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 import entity_instance
import typing
def edit_survey_point(annotation: entity_instance, x: float, y: float, z: float = 0.0):
@@ -16,10 +16,11 @@
# 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.owner
import ifcopenshell.guid
from typing import Union
def assign_constraint(
@@ -15,9 +15,10 @@
#
# 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 typing import Any
import ifcopenshell
def edit_metric(file: ifcopenshell.file, metric: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edit the attributes of a metric
@@ -15,9 +15,10 @@
#
# 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 typing import Any
import ifcopenshell
def edit_objective(
file: ifcopenshell.file, objective: ifcopenshell.entity_instance, attributes: dict[str, Any]
@@ -16,9 +16,10 @@
# 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, Optional
import ifcopenshell
import ifcopenshell.util.representation
from typing import Optional, Any
def add_context(
@@ -16,9 +16,10 @@
# 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 typing import Any
import ifcopenshell
def edit_context(file: ifcopenshell.file, context: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcGeometricRepresentationContext
@@ -51,8 +51,10 @@ def remove_context(file: ifcopenshell.file, context: ifcopenshell.entity_instanc
new = context.ParentContext
for inverse in file.get_inverse(context):
if inverse.is_a("IfcCoordinateOperation"):
# Trick to make sure the coordinate operation is not referenced
# by a context so we can delete it safely
inverse.SourceCRS = inverse.TargetCRS
ifcopenshell.util.element.remove_deep(file, inverse)
ifcopenshell.util.element.remove_deep2(file, inverse)
else:
ifcopenshell.util.element.replace_attribute(inverse, context, new)
file.remove(context)
@@ -16,10 +16,11 @@
# 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.owner
import ifcopenshell.guid
from typing import Union
def assign_control(
@@ -16,12 +16,13 @@
# 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.control
import ifcopenshell.api.root
import ifcopenshell.api.nest
import ifcopenshell.guid
from typing import Optional
import ifcopenshell.api.control
import ifcopenshell.api.nest
import ifcopenshell.api.root
import ifcopenshell.guid
def add_cost_item(
file: ifcopenshell.file,
@@ -16,11 +16,12 @@
# 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
import ifcopenshell.api.sequence
from datetime import datetime
from typing import Optional
import ifcopenshell.api.root
import ifcopenshell.api.sequence
def add_cost_schedule(
file: ifcopenshell.file, name: Optional[str] = None, predefined_type: str = "NOTDEFINED"
@@ -16,10 +16,11 @@
# 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.cost
import ifcopenshell.api.control
from typing import Any
import ifcopenshell.api.control
import ifcopenshell.api.cost
def assign_cost_item_quantity(
file: ifcopenshell.file,
@@ -17,7 +17,6 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell.api.cost
import ifcopenshell.util.date
import ifcopenshell.util.resource
@@ -16,10 +16,11 @@
# 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.nest
import ifcopenshell.util.element
from typing import Union
def copy_cost_item(
@@ -16,8 +16,8 @@
# 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.util.element
import ifcopenshell.api.cost
import ifcopenshell.util.element
def copy_cost_item_values(
@@ -15,9 +15,10 @@
#
# 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 typing import Any
import ifcopenshell
def edit_cost_item(
file: ifcopenshell.file, cost_item: ifcopenshell.entity_instance, attributes: dict[str, Any]
@@ -15,9 +15,10 @@
#
# 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 typing import Any
import ifcopenshell
def edit_cost_item_quantity(
file: ifcopenshell.file, physical_quantity: ifcopenshell.entity_instance, attributes: dict[str, Any]
@@ -15,9 +15,10 @@
#
# 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 typing import Any
import ifcopenshell
def edit_cost_schedule(
file: ifcopenshell.file, cost_schedule: ifcopenshell.entity_instance, attributes: dict[str, Any]
@@ -16,11 +16,12 @@
# 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.unit
import ifcopenshell.util.element
from typing import Any
import ifcopenshell
import ifcopenshell.util.element
import ifcopenshell.util.unit
def edit_cost_value(
file: ifcopenshell.file, cost_value: ifcopenshell.entity_instance, attributes: dict[str, Any]
@@ -58,6 +59,6 @@ def edit_cost_value(
value["ValueComponent"],
)
value = file.create_entity("IfcMeasureWithUnit", value_component, value["UnitComponent"])
if old_unit_basis and file.get_total_inverses(old_unit_basis) == 0:
ifcopenshell.util.element.remove_deep(file, old_unit_basis)
if old_unit_basis:
ifcopenshell.util.element.remove_deep2(file, old_unit_basis)
setattr(cost_value, name, value)
@@ -16,12 +16,11 @@
# 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
import ifcopenshell.api.cost
import ifcopenshell.util.cost
import ifcopenshell.util.unit
import ifcopenshell.util.element
from typing import Any
def edit_cost_value_formula(file: ifcopenshell.file, cost_value: ifcopenshell.entity_instance, formula: str) -> None:
@@ -16,11 +16,12 @@
# 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.guid
import ifcopenshell.api.owner
from typing import Optional
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
def add_information(
file: ifcopenshell.file, parent: Optional[ifcopenshell.entity_instance] = None
@@ -16,11 +16,12 @@
# 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.owner
import ifcopenshell.guid
import ifcopenshell.util.element
from typing import Union
def assign_document(
@@ -15,9 +15,10 @@
#
# 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 typing import Any
import ifcopenshell
def edit_information(
file: ifcopenshell.file,
@@ -15,9 +15,10 @@
#
# 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 typing import Any
import ifcopenshell
def edit_reference(
file: ifcopenshell.file,
@@ -15,9 +15,10 @@
#
# 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 typing import Any
import ifcopenshell
def edit_text_literal(
file: ifcopenshell.file, text_literal: ifcopenshell.entity_instance, attributes: dict[str, Any]
@@ -17,9 +17,9 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.api.geometry
import ifcopenshell.api.aggregate
import ifcopenshell.api.geometry
import ifcopenshell.api.owner
import ifcopenshell.guid
import ifcopenshell.util.element
import ifcopenshell.util.placement
@@ -16,17 +16,19 @@
# 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
import ifcopenshell.api.aggregate
import ifcopenshell.api.root
import ifcopenshell.util.element
def remove_feature(file: ifcopenshell.file, feature: ifcopenshell.entity_instance) -> None:
"""Remove a feature
"""Permanently delete a feature element and its void or projection relationship.
Fillings are retained as orphans. Featured elements remain. Features
cannot exist by themselves, so not only is the relationship removed, the
feature is also removed.
The feature entity (e.g. IfcOpeningElement) is removed from the model
along with its IfcRelVoidsElement or IfcRelProjectsElement relationship.
The host element (wall, slab, etc.) is unaffected. Any fillings (windows,
doors) that occupied the opening become orphaned and must be separately
deleted via root.remove_product.
:param feature: The IfcFeatureElement to remove.
@@ -25,7 +25,10 @@ geometry extrusions).
from .. import wrap_usecases
from .add_axis_representation import add_axis_representation
from .add_topology_representation import add_topology_representation
from .add_boolean import add_boolean
from .clip_solid import clip_solid
from .clip_solid_bounded import clip_solid_bounded
from .add_door_representation import add_door_representation
from .add_footprint_representation import add_footprint_representation
from .add_mesh_representation import add_mesh_representation
@@ -50,6 +53,7 @@ from .disconnect_element import disconnect_element
from .disconnect_path import disconnect_path
from .edit_object_placement import edit_object_placement
from .map_representation import map_representation
from .copy_representation import copy_representation
from .regenerate_wall_representation import regenerate_wall_representation
from .remove_boolean import remove_boolean
from .remove_representation import remove_representation
@@ -60,7 +64,11 @@ wrap_usecases(__path__, __name__)
__all__ = [
"add_axis_representation",
"add_topology_representation",
"add_boolean",
"clip_solid",
"clip_solid_bounded",
"copy_representation",
"add_door_representation",
"add_footprint_representation",
"add_mesh_representation",
@@ -16,8 +16,9 @@
# 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, Union
import ifcopenshell.util.unit
from typing import Union, Any
COORD = Union[tuple[float, float], tuple[float, float, float]]
@@ -17,9 +17,11 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import ifcopenshell.util.element
from typing import Literal
import ifcopenshell.util.element
def add_boolean(
file: ifcopenshell.file,
@@ -29,17 +31,6 @@ def add_boolean(
) -> list[ifcopenshell.entity_instance]:
"""Adds a boolean operation to two or more representation items
If an IfcBooleanOperand is part of the top level items in an
IfcShapeRepresentation, it will be removed from that level whilst being
added to the IfcBooleanResult. This is because it is generally intuitive
that an item is either participating in a boolean operation, or being an
item in its own right, but not both.
However, if an IfcBooleanOperand is part of another boolean operation
already, it will not be removed from the existing operation. A new
operation will be created, and therefore it will participate in two
operations.
This function protects against recursive booleans.
After a boolean operation is made, since the items of
@@ -99,9 +90,6 @@ def add_boolean(
booleans = []
for second_item in second_items:
for inverse in file.get_inverse(second_item):
if inverse.is_a("IfcShapeRepresentation"):
inverse.Items = list(set(inverse.Items) - {second_item})
if first.is_a("IfcTesselatedFaceSet"):
first.Closed = True # For now, trust the user to do the right thing.
if second_item.is_a("IfcTesselatedFaceSet"):
@@ -17,18 +17,17 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import sys
import ifcopenshell.util.unit
import ifcopenshell.api.geometry
import dataclasses
import numpy as np
from ifcopenshell.util.shape_builder import ShapeBuilder, V
from ifcopenshell.api.geometry.add_window_representation import create_ifc_window
from math import cos, radians
from typing import Any, Optional, Literal, Union, get_args, overload
from typing import Any, Literal, Optional, Union, get_args, overload
DATACLASS_SLOTS = {} if sys.version_info < (3, 10) else {"slots": True}
import numpy as np
import ifcopenshell.api.geometry
import ifcopenshell.util.unit
from ifcopenshell.api.geometry.add_window_representation import create_ifc_window
from ifcopenshell.util.shape_builder import ShapeBuilder, V
DOOR_TYPE = Literal[
"SINGLE_SWING_LEFT",
@@ -99,7 +98,7 @@ def create_ifc_box(
# we use dataclass as we need default values for arguments
# it's okay to use slots since we don't need dynamic attributes
@dataclasses.dataclass(**DATACLASS_SLOTS)
@dataclasses.dataclass(slots=True)
class DoorLiningProperties:
LiningDepth: Optional[float] = None
"""Optional, defaults to 50mm."""
@@ -173,7 +172,7 @@ class DoorLiningProperties:
setattr(self, attr, default_value * si_conversion)
@dataclasses.dataclass(**DATACLASS_SLOTS)
@dataclasses.dataclass(slots=True)
class DoorPanelProperties:
PanelDepth: Optional[float] = None
"""Frame thickness by Y axis. Optional, defaults to 35 mm."""
@@ -16,11 +16,13 @@
# 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.util.unit
from typing import Optional, TypeVar
import numpy as np
import numpy.typing as npt
from ifcopenshell.util.shape_builder import ShapeBuilder, SequenceOfVectors, VectorType
from typing import Optional, TypeVar
import ifcopenshell.util.unit
from ifcopenshell.util.shape_builder import SequenceOfVectors, ShapeBuilder, VectorType
T = TypeVar("T")
COORD_3D = tuple[float, float, float]
@@ -16,12 +16,13 @@
# 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, Optional, Union, get_args
import ifcopenshell.geom
import ifcopenshell.util.element
import ifcopenshell.util.shape
import ifcopenshell.util.unit
from ifcopenshell.util.data import Clipping
from typing import Any, Union, Optional, Literal, get_args
VECTOR_3D = tuple[float, float, float]
CardinalPointNumeric = Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
@@ -16,24 +16,26 @@
# 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 math import cos, pi, radians, sin, tan
from typing import Any, Literal, Optional
import numpy as np
from typing_extensions import assert_never
import ifcopenshell.util.unit
from ifcopenshell.util.shape_builder import (
SequenceOfVectors,
ShapeBuilder,
V,
SequenceOfVectors,
is_x,
np_angle,
np_angle_signed,
np_normalized,
np_to_3d,
np_normal,
np_intersect_line_line,
np_lerp,
np_normal,
np_normalized,
np_to_3d,
)
from math import pi, cos, sin, tan, radians
from typing import Literal, Optional, Any
from typing_extensions import assert_never
def mm(x: float) -> float:
@@ -16,16 +16,19 @@
# 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 __future__ import annotations
import bpy.types
import math
import bmesh
import ifcopenshell.util.shape_builder
import ifcopenshell.util.unit
from typing import TYPE_CHECKING, Any, Literal, Optional, Union
import bmesh # pyright: ignore[reportMissingImports] # ty:ignore[unresolved-import]
import bpy # pyright: ignore[reportMissingImports] # ty:ignore[unresolved-import]
import numpy as np
import numpy.typing as npt
from mathutils import Vector, Matrix
from typing import Union, Optional, Literal, Any, TYPE_CHECKING
from ifcopenshell.util.shape_builder import ifc_safe_vector_type, VectorType
from mathutils import Matrix, Vector # pyright: ignore[reportMissingImports] # ty:ignore[unresolved-import]
import ifcopenshell.util.shape_builder
import ifcopenshell.util.unit
from ifcopenshell.util.shape_builder import ifc_safe_vector_type
if TYPE_CHECKING:
import bonsai.tool as tool
@@ -16,9 +16,10 @@
# 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 typing import Optional
import ifcopenshell
def add_shape_aspect(
file: ifcopenshell.file,
@@ -16,11 +16,12 @@
# 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 math import cos, sin
from typing import Optional, Union
import ifcopenshell.util.element
import ifcopenshell.util.unit
from ifcopenshell.util.data import Clipping
from math import sin, cos
from typing import Any, Optional, Union
def add_slab_representation(
@@ -0,0 +1,97 @@
# 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.
from typing import Optional
import ifcopenshell
_ITEM_TYPE_TO_REP_TYPE = {
"IfcVertex": "Vertex",
"IfcVertexPoint": "Vertex",
"IfcEdge": "Edge",
"IfcOrientedEdge": "Edge",
"IfcEdgeCurve": "Edge",
"IfcEdgeLoop": "Edge",
"IfcPath": "Edge",
"IfcFace": "Face",
"IfcFaceSurface": "Face",
"IfcAdvancedFace": "Face",
"IfcClosedShell": "Face",
"IfcOpenShell": "Face",
"IfcConnectedFaceSet": "Face",
}
def add_topology_representation(
file: ifcopenshell.file,
context: ifcopenshell.entity_instance,
item: ifcopenshell.entity_instance,
representation_identifier: Optional[str] = None,
representation_type: Optional[str] = None,
) -> ifcopenshell.entity_instance:
"""Adds an IfcTopologyRepresentation for a structural element
Structural analysis elements (IfcStructuralSurfaceMember,
IfcStructuralCurveMember) use topology representations rather than solid
geometry. This is analogous to :func:`add_axis_representation` and
:func:`add_profile_representation` but produces an
IfcTopologyRepresentation instead of an IfcShapeRepresentation.
The representation type ("Face", "Edge", "Vertex") is inferred from the
item's IFC class if not provided explicitly.
:param context: The IfcGeometricRepresentationContext for the
representation, typically a Reference context.
:param item: The IfcTopologicalRepresentationItem (e.g. IfcFaceSurface,
IfcEdge) to include in the representation.
:param representation_identifier: The RepresentationIdentifier string.
Defaults to the context's ContextIdentifier.
:param representation_type: The RepresentationType string ("Face",
"Edge", "Vertex"). Inferred from item class if not given.
:return: The newly created IfcTopologyRepresentation entity.
Example:
.. code:: python
context = ifcopenshell.util.representation.get_context(
model, "Model", "Reference", "GRAPH_VIEW")
face = model.createIfcFaceSurface(bounds, surface, True)
rep = ifcopenshell.api.geometry.add_topology_representation(
model, context=context, item=face)
ifcopenshell.api.geometry.assign_representation(
model, product=member, representation=rep)
"""
if representation_identifier is None:
representation_identifier = context.ContextIdentifier
if representation_type is None:
for ifc_class, rep_type in _ITEM_TYPE_TO_REP_TYPE.items():
if item.is_a(ifc_class):
representation_type = rep_type
break
else:
representation_type = "Undefined"
return file.createIfcTopologyRepresentation(
context,
representation_identifier,
representation_type,
[item],
)
@@ -16,10 +16,11 @@
# 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 math import cos, sin
from typing import Any, Optional, Union
import ifcopenshell.util.element
import ifcopenshell.util.unit
from math import sin, cos, pi
from typing import Optional, Union, Any
from ifcopenshell.util.data import Clipping
@@ -46,7 +47,9 @@ def add_wall_representation(
:param thickness: The thickness of the wall in meters.
:param x_angle: The slope angle along the wall's X-axis, in radians.
:param clippings: List of clipping definitions. Clippings can be `Clipping` objects
or dictionaries of arguments for `Clipping.parse`.
or dictionaries of arguments for `Clipping.parse`. Each clipping has a
``normal`` that points toward the removed material (the discarded side),
not toward the kept material; see :func:`clip_solid` for details.
:param booleans: List of any existing IfcBooleanResults.
:return: IfcShapeRepresentation.
"""
@@ -17,17 +17,16 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import sys
import numpy as np
import dataclasses
from itertools import chain
from typing import Any, Literal, Optional, Union, overload
import numpy as np
import ifcopenshell.api.geometry
import ifcopenshell.util.unit
from itertools import chain
from ifcopenshell.util.shape_builder import ShapeBuilder, V
from typing import Any, Optional, Literal, Union, overload
DATACLASS_SLOTS = {} if sys.version_info < (3, 10) else {"slots": True}
ZIP_STRICT = {} if sys.version_info < (3, 10) else {"strict": True}
# SCHEMAS describe panels setup
# where:
@@ -169,7 +168,7 @@ def window_l_shape_check(
"""`lining_thickness` and `lining_to_panel_offset_x` expected to be defined as a list,
similarly to `create_ifc_window_frame_simple` `thickness` argument"""
l_shape_check = lining_to_panel_offset_y_full < lining_depth and any(
x_offset < th for th, x_offset in zip(lining_thickness, lining_to_panel_offset_x, **ZIP_STRICT)
x_offset < th for th, x_offset in zip(lining_thickness, lining_to_panel_offset_x, strict=True)
)
return l_shape_check
@@ -211,7 +210,7 @@ def create_ifc_window(
second_lining_size = lining_size.copy()
second_lining_size[np_Y] = lining_size[np_Y] - lining_to_panel_offset_y_full
second_lining_position = V(0, lining_to_panel_offset_y_full, 0)
second_lining_thickness = [min(th, x_offset) for th, x_offset in zip(lining_thickness, x_offsets, **ZIP_STRICT)]
second_lining_thickness = [min(th, x_offset) for th, x_offset in zip(lining_thickness, x_offsets, strict=True)]
second_lining_items = create_ifc_window_frame_simple(
builder, second_lining_size, second_lining_thickness, second_lining_position
@@ -241,7 +240,7 @@ def create_ifc_window(
# we use dataclass as we need default values for arguments
# it's okay to use slots since we don't need dynamic attributes
@dataclasses.dataclass(**DATACLASS_SLOTS)
@dataclasses.dataclass(slots=True)
class WindowLiningProperties:
LiningDepth: Optional[float] = None
"""Optional, defaults to 50mm."""
@@ -324,7 +323,7 @@ class WindowLiningProperties:
setattr(self, attr, default_value * si_conversion)
@dataclasses.dataclass(**DATACLASS_SLOTS)
@dataclasses.dataclass(slots=True)
class WindowPanelProperties:
FrameDepth: Optional[float] = None
"""Frame thickness by Y axis. Optional, defaults to 35 mm."""
@@ -16,10 +16,10 @@
# 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.owner
import ifcopenshell.api.geometry
import ifcopenshell.api.owner
import ifcopenshell.util.element
from typing import Any
def assign_representation(
@@ -0,0 +1,86 @@
# 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/>.
from __future__ import annotations
import json
from typing import Optional, Sequence
import ifcopenshell.api.pset
import ifcopenshell.util.element
import ifcopenshell.util.unit
from ifcopenshell.util.data import Clipping
def clip_solid(
file: ifcopenshell.file,
item: ifcopenshell.entity_instance,
location: Sequence[float],
normal: Sequence[float],
element: Optional[ifcopenshell.entity_instance] = None,
) -> ifcopenshell.entity_instance:
"""Clip a solid with a half-space plane, returning an IfcBooleanClippingResult.
Convenience wrapper around :class:`ifcopenshell.util.data.Clipping` for
use with any solid. This is the same convention used by the ``clippings``
parameter of :func:`add_wall_representation`.
.. warning::
The ``normal`` points toward the **removed** material (the discarded
side), not toward the kept material. For a slope clip the normal
points upward into the removed wedge above the slope line. For a
side mitre the normal points outward away from the wall body.
After clipping, set the parent ``IfcShapeRepresentation``
``RepresentationType`` to ``"Clipping"``.
Example trim an extruded solid to a lean-to slope (removed material is
above the slope)::
bcr = ifcopenshell.api.run(
"geometry.clip_solid", model,
item=extrusion,
location=[0.0, 0.0, 3.26],
normal=[0.419, 0.0, 0.908], # points UP toward removed material
)
:param item: The solid to clip (``IfcSweptAreaSolid``, ``IfcSweptDiskSolid``,
or ``IfcBooleanClippingResult``).
:param location: A point on the clipping plane in the representation's
local coordinate system.
:param normal: Plane normal pointing toward the material to be removed
(see warning above).
:param element: If provided, the resulting ``IfcBooleanClippingResult`` is
registered in the element's ``BBIM_Boolean`` property set so that
:func:`regenerate_wall_representation` preserves it during regeneration.
:return: The resulting ``IfcBooleanClippingResult``.
"""
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(file)
clipping = Clipping(location=tuple(location), normal=tuple(normal))
result = clipping.apply(file, item, unit_scale)
if element is not None:
pset_data = ifcopenshell.util.element.get_pset(element, "BBIM_Boolean")
if pset_data:
pset = file.by_id(pset_data["id"])
data = list(set(json.loads(pset_data["Data"]) + [result.id()]))
else:
pset = ifcopenshell.api.pset.add_pset(file, product=element, name="BBIM_Boolean")
data = [result.id()]
ifcopenshell.api.pset.edit_pset(file, pset=pset, properties={"Data": json.dumps(data)})
return result
@@ -0,0 +1,116 @@
# 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/>.
from __future__ import annotations
import json
from typing import Optional, Sequence
import numpy as np
import ifcopenshell.api.pset
import ifcopenshell.util.element
import ifcopenshell.util.unit
from ifcopenshell.util.shape_builder import ShapeBuilder
def clip_solid_bounded(
file: ifcopenshell.file,
item: ifcopenshell.entity_instance,
location: Sequence[float],
normal: Sequence[float],
boundary_points: Sequence[Sequence[float]],
boundary_position: Sequence[float] = (0.0, 0.0, 0.0),
element: Optional[ifcopenshell.entity_instance] = None,
) -> ifcopenshell.entity_instance:
"""Clip a solid with a polygonally bounded half-space, returning an IfcBooleanClippingResult.
Like :func:`clip_solid`, but the boolean subtraction is restricted to the
region enclosed by ``boundary_points`` rather than extending across the
entire half-space. The clipping plane is still infinite, but material is
only removed within the extruded footprint of the polygon.
The ``normal`` convention is the same as :func:`clip_solid`: it points
toward the **removed** material.
After clipping, set the parent ``IfcShapeRepresentation``
``RepresentationType`` to ``"Clipping"``.
Example::
bcr = ifcopenshell.api.run(
"geometry.clip_solid_bounded", model,
item=extrusion,
location=[2.5, 0.0, 2.0],
normal=[0.6, 0.0, 0.8],
boundary_points=[[2.0, 0.0], [3.0, 0.0], [3.0, 2.0], [2.0, 2.0]],
)
:param item: The solid to clip (``IfcSweptAreaSolid``, ``IfcSweptDiskSolid``,
or ``IfcBooleanClippingResult``).
:param location: A point on the clipping plane in the representation's
local coordinate system.
:param normal: Plane normal pointing toward the material to be removed.
:param boundary_points: 2D ``[x, y]`` points defining the closed polygonal
boundary in the coordinate system of ``boundary_position``. The polygon
is automatically closed do not repeat the first point.
:param boundary_position: 3D origin of the boundary coordinate system
(axes default to the global X/Y/Z directions). Defaults to the origin.
:param element: If provided, the resulting ``IfcBooleanClippingResult`` is
registered in the element's ``BBIM_Boolean`` property set so that
:func:`regenerate_wall_representation` preserves it during regeneration.
:return: The resulting ``IfcBooleanClippingResult``.
"""
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(file)
builder = ShapeBuilder(file)
normal_arr = np.array(normal)
if np.allclose(normal_arr, [0.0, 0.0, 1.0], atol=1e-2) or np.allclose(normal_arr, [0.0, 0.0, -1.0], atol=1e-2):
arbitrary_vector = np.array([0.0, 1.0, 0.0])
else:
arbitrary_vector = np.array([0.0, 0.0, 1.0])
x_axis = np.cross(normal_arr, arbitrary_vector)
x_axis /= np.linalg.norm(x_axis)
scaled_location = [i / unit_scale for i in location]
plane_placement = builder.create_axis2_placement_3d(scaled_location, normal, x_axis)
plane = file.create_entity("IfcPlane", plane_placement)
scaled_boundary_position = [i / unit_scale for i in boundary_position]
boundary_pos_entity = file.create_entity(
"IfcAxis2Placement3D",
file.create_entity("IfcCartesianPoint", scaled_boundary_position),
)
scaled_pts = [[p[0] / unit_scale, p[1] / unit_scale] for p in boundary_points]
scaled_pts.append(scaled_pts[0]) # close the polygon
ifc_pts = [file.create_entity("IfcCartesianPoint", p) for p in scaled_pts]
boundary = file.createIfcPolyline(ifc_pts)
half_space = file.create_entity("IfcPolygonalBoundedHalfSpace", plane, False, boundary_pos_entity, boundary)
result = file.create_entity("IfcBooleanClippingResult", "DIFFERENCE", item, half_space)
if element is not None:
pset_data = ifcopenshell.util.element.get_pset(element, "BBIM_Boolean")
if pset_data:
pset = file.by_id(pset_data["id"])
data = list(set(json.loads(pset_data["Data"]) + [result.id()]))
else:
pset = ifcopenshell.api.pset.add_pset(file, product=element, name="BBIM_Boolean")
data = [result.id()]
ifcopenshell.api.pset.edit_pset(file, pset=pset, properties={"Data": json.dumps(data)})
return result
@@ -16,11 +16,12 @@
# 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
import ifcopenshell.api.owner
import ifcopenshell.guid
import ifcopenshell.util.element
from typing import Optional
def connect_element(
@@ -16,11 +16,12 @@
# 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
import ifcopenshell.api.owner
import ifcopenshell.guid
import ifcopenshell.util.element
from typing import Optional
def connect_path(
@@ -30,6 +31,7 @@ def connect_path(
relating_connection: str = "NOTDEFINED",
related_connection: str = "NOTDEFINED",
description: Optional[str] = None,
connection_geometry: Optional[ifcopenshell.entity_instance] = None,
) -> ifcopenshell.entity_instance:
incompatible_connections: list[ifcopenshell.entity_instance] = []
for rel in relating_element.ConnectedTo:
@@ -72,6 +74,7 @@ def connect_path(
ifcopenshell.guid.new(),
OwnerHistory=ifcopenshell.api.owner.create_owner_history(file),
Description=description,
ConnectionGeometry=connection_geometry,
RelatingElement=relating_element,
RelatedElement=related_element,
RelatingConnectionType=relating_connection,
@@ -16,13 +16,15 @@
# 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 numpy as np
import ifcopenshell
import ifcopenshell.api.geometry
import ifcopenshell.util.placement
import ifcopenshell.util.representation
import ifcopenshell.util.shape_builder
from typing import Optional
def connect_wall(

Some files were not shown because too many files have changed in this diff Show More