diff --git a/src/ifcopenshell-python/ifcopenshell/geom/main.py b/src/ifcopenshell-python/ifcopenshell/geom/main.py index fc9430bf8a..29ba26e92b 100644 --- a/src/ifcopenshell-python/ifcopenshell/geom/main.py +++ b/src/ifcopenshell-python/ifcopenshell/geom/main.py @@ -28,7 +28,10 @@ from ..entity_instance import entity_instance from . import has_occ -from typing import TypeVar, Union, Optional, Generator, Any, Literal, overload +from typing import TypeVar, Union, Optional, Generator, Any, Literal, overload, TYPE_CHECKING + +if TYPE_CHECKING: + from OCC.Core import TopoDS T = TypeVar("T") ShapeElementType = Union[ @@ -356,7 +359,7 @@ def create_shape( inst: entity_instance, repr: Optional[entity_instance] = None, geometry_library: GEOMETRY_LIBRARY = "opencascade", -) -> Union[ShapeType, ShapeElementType, ifcopenshell_wrapper.Transformation]: +) -> Union[ShapeType, ShapeElementType, ifcopenshell_wrapper.Transformation, utils.shape_tuple, TopoDS.TopoDS_Shape]: """ Return a geometric representation from STEP-based IFCREPRESENTATIONSHAPE or @@ -368,14 +371,18 @@ def create_shape( :raises RuntimeError: If failed to process shape. You can turn detailed logging to get more details. :return: - - `inst` is IfcProduct and `repr` provided / None -> ShapeElementType - - `inst` is IfcRepresentation and `repr` is None -> ShapeType - - `inst` is IfcRepresentationItem and `repr` is None -> ShapeType - - `inst` is IfcProfileDef and `repr` is None -> ShapeType - - `inst` is IfcPlacement / IfcObjectPlacement -> Transformation - - `inst` is IfcTypeProduct and `repr` is None -> None + - `inst` is IfcProduct and `repr` provided / None -> ShapeElementType\n + - `inst` is IfcRepresentation and `repr` is None -> ShapeType\n + - `inst` is IfcRepresentationItem and `repr` is None -> ShapeType\n + - `inst` is IfcProfileDef and `repr` is None -> ShapeType\n + - `inst` is IfcPlacement / IfcObjectPlacement -> Transformation\n + - `inst` is IfcTypeProduct and `repr` is None -> None\n - `inst` is IfcTypeProduct and `repr` is provided -> RuntimeError - (for IfcTypeProducts provide just IfcRepresentation as `inst`). + (for IfcTypeProducts provide just IfcRepresentation as `inst`).\n + + If 'use-python-opencascade' is enabled in settings then\n + - instead of ShapeElementType it returns shape_tuple, \n + - instead of ShapeType it returns TopoDS.TopoDS_Shape. Example: diff --git a/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py b/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py index 2b230a4168..b5e8b1ccae 100644 --- a/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py +++ b/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py @@ -17,11 +17,14 @@ # along with IfcOpenShell. If not, see . +from __future__ import annotations import random import operator import warnings +import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper -from collections import namedtuple +from typing import NamedTuple, Any, Union +from typing_extensions import assert_never from collections.abc import Iterable import OCC @@ -35,7 +38,13 @@ except ImportError: USE_OCCT_HANDLE = True -shape_tuple = namedtuple("shape_tuple", ("data", "geometry", "styles", "style_ids")) + +class shape_tuple(NamedTuple): + data: Union[ifcopenshell_wrapper.SerializedElement, ifcopenshell_wrapper.Serialization] + geometry: TopoDS.TopoDS_Shape + styles: tuple[tuple[float, float, float, float], ...] + style_ids: tuple[int, ...] + handle, main_loop, add_menu, add_function_to_menu = None, None, None, None @@ -217,22 +226,26 @@ def serialize_shape(shape): return shapes.WriteToString() -def create_shape_from_serialization(brep_object): +def create_shape_from_serialization( + brep_object: Union[ifcopenshell_wrapper.SerializedElement, ifcopenshell_wrapper.Serialization] +) -> Union[shape_tuple, TopoDS.TopoDS_Shape]: brep_data, occ_shape, styles, style_ids = None, None, (), () is_product_shape = True - try: + if isinstance(brep_object, ifcopenshell_wrapper.SerializedElement): brep_data = brep_object.geometry.brep_data styles = brep_object.geometry.surface_styles style_ids = brep_object.geometry.surface_style_ids - except BaseException: + elif isinstance(brep_object, ifcopenshell_wrapper.Serialization): try: brep_data = brep_object.brep_data styles = brep_object.surface_styles style_ids = brep_object.surface_style_ids is_product_shape = False - except BaseException: - pass + except BaseException as e: + print("Error occurred creating a shape:", e) + else: + assert_never(brep_object) styles = tuple(styles[i : i + 4] for i in range(0, len(styles), 4))