diff --git a/src/ifcopenshell-python/ifcopenshell/geom/main.py b/src/ifcopenshell-python/ifcopenshell/geom/main.py index 92d57f005f..677b52139e 100644 --- a/src/ifcopenshell-python/ifcopenshell/geom/main.py +++ b/src/ifcopenshell-python/ifcopenshell/geom/main.py @@ -30,11 +30,19 @@ from ..entity_instance import entity_instance def has_occ(): + try: + import OCC.Core.BRepTools + return True + except ModuleNotFoundError: + pass + try: import OCC.BRepTools - except BaseException: - return False - return True + return True + except ModuleNotFoundError: + pass + + return False has_occ = has_occ() @@ -47,6 +55,11 @@ def wrap_shape_creation(settings, shape): if has_occ: from . import occ_utils as utils + try: + from OCC.Core import TopoDS + except ModuleNotFoundError: + from OCC import TopoDS + def wrap_shape_creation(settings, shape): return utils.create_shape_from_serialization(shape) if getattr(settings, 'use_python_opencascade', False) else shape @@ -118,8 +131,7 @@ class tree(ifcopenshell_wrapper.tree): if isinstance(value, entity_instance): args.append(kwargs.get("completely_within", False)) elif has_occ: - import OCC.TopoDS - if isinstance(value, OCC.TopoDS.TopoDS_Shape): + if isinstance(value, TopoDS.TopoDS_Shape): args[1] = utils.serialize_shape(value) return [entity_instance(e) for e in ifcopenshell_wrapper.tree.select(*args)] @@ -183,10 +195,8 @@ def make_shape_function(fn): return None if e is None else entity_instance(e) if has_occ: - import OCC.TopoDS - def _(string_or_shape, *args): - if isinstance(string_or_shape, OCC.TopoDS.TopoDS_Shape): + if isinstance(string_or_shape, TopoDS.TopoDS_Shape): string_or_shape = utils.serialize_shape(string_or_shape) return entity_instance_or_none(fn(string_or_shape, *args)) else: diff --git a/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py b/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py index 2b78455868..a702de9b44 100644 --- a/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py +++ b/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py @@ -23,8 +23,15 @@ from __future__ import print_function import random import operator +import warnings + from collections import namedtuple, Iterable +try: + from OCC.Core import V3d, TopoDS, gp, AIS, Quantity, BRepTools, Graphic3d +except ModuleNotFoundError: + from OCC import V3d, TopoDS, gp, AIS, Quantity, BRepTools, Graphic3d + shape_tuple = namedtuple('shape_tuple', ('data', 'geometry', 'styles')) handle, main_loop, add_menu, add_function_to_menu = None, None, None, None @@ -46,7 +53,6 @@ DEFAULT_STYLES = { def initialize_display(): - import OCC.V3d import OCC.Display.SimpleGui global handle, main_loop, add_menu, add_function_to_menu @@ -71,7 +77,7 @@ def initialize_display(): viewer.DelLight(l) for dir in [(3, 2, 1), (-1, -2, -3)]: - light = OCC.V3d.V3d_DirectionalLight(viewer_handle) + light = V3d.V3d_DirectionalLight(viewer_handle) light.SetDirection(*dir) viewer.SetLightOn(light.GetHandle()) @@ -80,19 +86,13 @@ def initialize_display(): def yield_subshapes(shape): - import OCC.TopoDS - - it = OCC.TopoDS.TopoDS_Iterator(shape) + it = TopoDS.TopoDS_Iterator(shape) while it.More(): yield it.Value() it.Next() def display_shape(shape, clr=None, viewer_handle=None): - import OCC.gp - import OCC.AIS - import OCC.Quantity - if viewer_handle is None: viewer_handle = handle @@ -101,7 +101,7 @@ def display_shape(shape, clr=None, viewer_handle=None): else: representation = None - material = OCC.Graphic3d.Graphic3d_MaterialAspect(OCC.Graphic3d.Graphic3d_NOM_PLASTER) + material = Graphic3d.Graphic3d_MaterialAspect(Graphic3d.Graphic3d_NOM_PLASTER) material.SetDiffuse(1) if representation and not clr: @@ -111,20 +111,20 @@ def display_shape(shape, clr=None, viewer_handle=None): clr = DEFAULT_STYLES.get(representation.data.type, DEFAULT_STYLES["DEFAULT"]) if clr: - ais = OCC.AIS.AIS_Shape(shape) + ais = AIS.AIS_Shape(shape) ais.SetMaterial(material) if isinstance(clr, str): - qclr = getattr(OCC.Quantity, "Quantity_NOC_%s" % clr.upper(), - getattr(OCC.Quantity, "Quantity_NOC_%s1" % clr.upper(), None)) + qclr = getattr(Quantity, "Quantity_NOC_%s" % clr.upper(), + getattr(Quantity, "Quantity_NOC_%s1" % clr.upper(), None)) if qclr is None: raise Exception("No color named '%s'" % clr.upper()) elif isinstance(clr, Iterable): clr = tuple(clr) if len(clr) < 3 or len(clr) > 4: raise Exception("Need 3 or 4 color components. Got '%r'." % len(clr)) - qclr = OCC.Quantity.Quantity_Color(clr[0], clr[1], clr[2], OCC.Quantity.Quantity_TOC_RGB) - elif isinstance(clr, OCC.Quantity.Quantity_Color): + qclr = Quantity.Quantity_Color(clr[0], clr[1], clr[2], Quantity.Quantity_TOC_RGB) + elif isinstance(clr, Quantity.Quantity_Color): qclr = clr else: raise Exception("Object of type %r cannot be used as a color." % type(clr)) @@ -133,23 +133,22 @@ def display_shape(shape, clr=None, viewer_handle=None): if isinstance(clr, tuple) and len(clr) == 4 and clr[3] < 1.: ais.SetTransparency(1. - clr[3]) - elif representation and hasattr(OCC.AIS, "AIS_MultipleConnectedShape"): + elif representation and hasattr(AIS, "AIS_MultipleConnectedShape"): default_style_applied = None - ais = OCC.AIS.AIS_MultipleConnectedShape(shape) + ais = AIS.AIS_MultipleConnectedShape(shape) subshapes = list(yield_subshapes(shape)) lens = len(representation.styles), len(subshapes) if lens[0] != lens[1]: - import warnings warnings.warn("Unable to assign styles to subshapes. Encountered %d styles for %d shapes." % lens) else: for shp, stl in zip(subshapes, representation.styles): - subshape = OCC.AIS.AIS_Shape(shp) + subshape = AIS.AIS_Shape(shp) if min(stl) < 0. or max(stl) > 1.: default_style_applied = stl = DEFAULT_STYLES.get(representation.data.type, DEFAULT_STYLES["DEFAULT"]) - subshape.SetColor(OCC.Quantity.Quantity_Color(stl[0], stl[1], stl[2], OCC.Quantity.Quantity_TOC_RGB)) + subshape.SetColor(Quantity.Quantity_Color(stl[0], stl[1], stl[2], Quantity.Quantity_TOC_RGB)) subshape.SetMaterial(material) if len(stl) == 4 and stl[3] < 1.: subshape.SetTransparency(1. - stl[3]) @@ -170,13 +169,13 @@ def display_shape(shape, clr=None, viewer_handle=None): ais.SetTransparency(1.) else: - ais = OCC.AIS.AIS_Shape(shape) + ais = AIS.AIS_Shape(shape) ais.SetMaterial(material) def r(): return random.random() * 0.3 + 0.7 - clr = OCC.Quantity.Quantity_Color(r(), r(), r(), OCC.Quantity.Quantity_TOC_RGB) + clr = Quantity.Quantity_Color(r(), r(), r(), Quantity.Quantity_TOC_RGB) ais.SetColor(clr) ais_handle = ais.GetHandle() @@ -190,25 +189,19 @@ def set_shape_transparency(ais, t): def get_bounding_box_center(bbox): - import OCC.gp - bbmin = [0.] * 3 bbmax = [0.] * 3 bbmin[0], bbmin[1], bbmin[2], bbmax[0], bbmax[1], bbmax[2] = bbox.Get() - return OCC.gp.gp_Pnt(*map(lambda xy: (xy[0] + xy[1]) / 2., zip(bbmin, bbmax))) + return gp.gp_Pnt(*map(lambda xy: (xy[0] + xy[1]) / 2., zip(bbmin, bbmax))) def serialize_shape(shape): - import OCC.BRepTools - - shapes = OCC.BRepTools.BRepTools_ShapeSet() + shapes = BRepTools.BRepTools_ShapeSet() shapes.Add(shape) return shapes.WriteToString() def create_shape_from_serialization(brep_object): - import OCC.BRepTools - brep_data, occ_shape, styles = None, None, () is_product_shape = True @@ -229,7 +222,7 @@ def create_shape_from_serialization(brep_object): return shape_tuple(brep_object, None, styles) try: - ss = OCC.BRepTools.BRepTools_ShapeSet() + ss = BRepTools.BRepTools_ShapeSet() ss.ReadFromString(brep_data) occ_shape = ss.Shape(ss.NbShapes()) except BaseException: