build123d compatibility improvements for file exporting

Removes the need to use .wrapped for the CQ-editor file exporter to work correctly. Also ran file through black formatter.
This commit is contained in:
jdegenstein
2023-01-09 12:16:49 -06:00
committed by GitHub
parent 7b49f25f94
commit a144b2e60a

View File

@@ -8,8 +8,11 @@ from types import SimpleNamespace
from OCP.XCAFPrs import XCAFPrs_AISObject from OCP.XCAFPrs import XCAFPrs_AISObject
from OCP.TopoDS import TopoDS_Shape from OCP.TopoDS import TopoDS_Shape
from OCP.AIS import AIS_InteractiveObject, AIS_Shape from OCP.AIS import AIS_InteractiveObject, AIS_Shape
from OCP.Quantity import \ from OCP.Quantity import (
Quantity_TOC_RGB as TOC_RGB, Quantity_Color, Quantity_NOC_GOLD as GOLD Quantity_TOC_RGB as TOC_RGB,
Quantity_Color,
Quantity_NOC_GOLD as GOLD,
)
from OCP.Graphic3d import Graphic3d_NOM_JADE, Graphic3d_MaterialAspect from OCP.Graphic3d import Graphic3d_NOM_JADE, Graphic3d_MaterialAspect
from PyQt5.QtGui import QColor from PyQt5.QtGui import QColor
@@ -17,29 +20,57 @@ from PyQt5.QtGui import QColor
DEFAULT_FACE_COLOR = Quantity_Color(GOLD) DEFAULT_FACE_COLOR = Quantity_Color(GOLD)
DEFAULT_MATERIAL = Graphic3d_MaterialAspect(Graphic3d_NOM_JADE) DEFAULT_MATERIAL = Graphic3d_MaterialAspect(Graphic3d_NOM_JADE)
def find_cq_objects(results : dict):
return {k:SimpleNamespace(shape=v,options={}) for k,v in results.items() if isinstance(v,cq.Workplane)} def find_cq_objects(results: dict):
def to_compound(obj : Union[cq.Workplane, List[cq.Workplane], cq.Shape, List[cq.Shape], cq.Sketch]): return {
k: SimpleNamespace(shape=v, options={})
for k, v in results.items()
if isinstance(v, cq.Workplane)
}
def to_compound(
obj: Union[cq.Workplane, List[cq.Workplane], cq.Shape, List[cq.Shape], cq.Sketch]
):
vals = [] vals = []
print(obj)
print(dir(obj))
if isinstance(obj,cq.Workplane): if isinstance(obj, cq.Workplane):
vals.extend(obj.vals()) vals.extend(obj.vals())
elif isinstance(obj,cq.Shape): elif isinstance(obj, cq.Shape):
vals.append(obj) vals.append(obj)
elif isinstance(obj,list) and isinstance(obj[0],cq.Workplane): elif isinstance(obj, list) and isinstance(obj[0], cq.Workplane):
for o in obj: vals.extend(o.vals()) for o in obj:
elif isinstance(obj,list) and isinstance(obj[0],cq.Shape): vals.extend(o.vals())
elif isinstance(obj, list) and isinstance(obj[0], cq.Shape):
vals.extend(obj) vals.extend(obj)
elif isinstance(obj, TopoDS_Shape): elif isinstance(obj, TopoDS_Shape):
vals.append(cq.Shape.cast(obj)) vals.append(cq.Shape.cast(obj))
elif isinstance(obj,list) and isinstance(obj[0],TopoDS_Shape): elif isinstance(obj, list) and isinstance(obj[0], TopoDS_Shape):
vals.extend(cq.Shape.cast(o) for o in obj) vals.extend(cq.Shape.cast(o) for o in obj)
elif hasattr(obj, "wrapped") and isinstance(obj.wrapped, TopoDS_Shape): elif hasattr(obj, "wrapped") and isinstance(obj.wrapped, TopoDS_Shape):
vals.append(cq.Shape.cast(obj.wrapped)) vals.append(cq.Shape.cast(obj.wrapped))
elif hasattr(obj, "_obj") and hasattr(obj._obj, "wrapped") and isinstance(obj._obj.wrapped, TopoDS_Shape): elif (
isinstance(obj, list)
and hasattr(obj[0], "wrapped")
and isinstance(obj[0].wrapped, TopoDS_Shape)
):
vals.extend(o for o in obj)
elif (
hasattr(obj, "_obj")
and hasattr(obj._obj, "wrapped")
and isinstance(obj._obj.wrapped, TopoDS_Shape)
):
vals.append(cq.Shape.cast(obj._obj.wrapped))
elif (
isinstance(obj, list)
and hasattr(obj[0], "_obj")
and hasattr(obj[0]._obj, "wrapped")
and isinstance(obj[0]._obj.wrapped, TopoDS_Shape)
):
vals.append(cq.Shape.cast(obj._obj.wrapped)) vals.append(cq.Shape.cast(obj._obj.wrapped))
elif isinstance(obj, cq.Sketch): elif isinstance(obj, cq.Sketch):
if obj._faces: if obj._faces:
@@ -47,19 +78,32 @@ def to_compound(obj : Union[cq.Workplane, List[cq.Workplane], cq.Shape, List[cq.
else: else:
vals.extend(obj._edges) vals.extend(obj._edges)
else: else:
raise ValueError(f'Invalid type {type(obj)}') raise ValueError(f"Invalid type {type(obj)}")
return cq.Compound.makeCompound(vals) return cq.Compound.makeCompound(vals)
def to_workplane(obj : cq.Shape):
rv = cq.Workplane('XY') def to_workplane(obj: cq.Shape):
rv.objects = [obj,]
rv = cq.Workplane("XY")
rv.objects = [
obj,
]
return rv return rv
def make_AIS(obj : Union[cq.Workplane, List[cq.Workplane], cq.Shape, List[cq.Shape], cq.Assembly, AIS_InteractiveObject],
options={}): def make_AIS(
obj: Union[
cq.Workplane,
List[cq.Workplane],
cq.Shape,
List[cq.Shape],
cq.Assembly,
AIS_InteractiveObject,
],
options={},
):
shape = None shape = None
@@ -75,29 +119,32 @@ def make_AIS(obj : Union[cq.Workplane, List[cq.Workplane], cq.Shape, List[cq.Sha
set_material(ais, DEFAULT_MATERIAL) set_material(ais, DEFAULT_MATERIAL)
set_color(ais, DEFAULT_FACE_COLOR) set_color(ais, DEFAULT_FACE_COLOR)
if 'alpha' in options: if "alpha" in options:
set_transparency(ais, options['alpha']) set_transparency(ais, options["alpha"])
if 'color' in options: if "color" in options:
set_color(ais, to_occ_color(options['color'])) set_color(ais, to_occ_color(options["color"]))
if 'rgba' in options: if "rgba" in options:
r,g,b,a = options['rgba'] r, g, b, a = options["rgba"]
set_color(ais, to_occ_color((r,g,b))) set_color(ais, to_occ_color((r, g, b)))
set_transparency(ais, a) set_transparency(ais, a)
return ais,shape return ais, shape
def export(obj : Union[cq.Workplane, List[cq.Workplane]], type : str,
file, precision=1e-1): def export(
obj: Union[cq.Workplane, List[cq.Workplane]], type: str, file, precision=1e-1
):
comp = to_compound(obj) comp = to_compound(obj)
if type == 'stl': if type == "stl":
comp.exportStl(file, tolerance=precision) comp.exportStl(file, tolerance=precision)
elif type == 'step': elif type == "step":
comp.exportStep(file) comp.exportStep(file)
elif type == 'brep': elif type == "brep":
comp.exportBrep(file) comp.exportBrep(file)
def to_occ_color(color) -> Quantity_Color: def to_occ_color(color) -> Quantity_Color:
if not isinstance(color, QColor): if not isinstance(color, QColor):
@@ -107,16 +154,14 @@ def to_occ_color(color) -> Quantity_Color:
elif isinstance(color[0], float): elif isinstance(color[0], float):
color = QColor.fromRgbF(*color) color = QColor.fromRgbF(*color)
else: else:
raise ValueError('Unknown color format') raise ValueError("Unknown color format")
else: else:
color = QColor(color) color = QColor(color)
return Quantity_Color(color.redF(), return Quantity_Color(color.redF(), color.greenF(), color.blueF(), TOC_RGB)
color.greenF(),
color.blueF(),
TOC_RGB)
def get_occ_color(obj : Union[AIS_InteractiveObject, Quantity_Color]) -> QColor:
def get_occ_color(obj: Union[AIS_InteractiveObject, Quantity_Color]) -> QColor:
if isinstance(obj, AIS_InteractiveObject): if isinstance(obj, AIS_InteractiveObject):
color = Quantity_Color() color = Quantity_Color()
@@ -126,7 +171,8 @@ def get_occ_color(obj : Union[AIS_InteractiveObject, Quantity_Color]) -> QColor:
return QColor.fromRgbF(color.Red(), color.Green(), color.Blue()) return QColor.fromRgbF(color.Red(), color.Green(), color.Blue())
def set_color(ais : AIS_Shape, color : Quantity_Color) -> AIS_Shape:
def set_color(ais: AIS_Shape, color: Quantity_Color) -> AIS_Shape:
drawer = ais.Attributes() drawer = ais.Attributes()
drawer.SetupOwnShadingAspect() drawer.SetupOwnShadingAspect()
@@ -134,7 +180,8 @@ def set_color(ais : AIS_Shape, color : Quantity_Color) -> AIS_Shape:
return ais return ais
def set_material(ais : AIS_Shape, material: Graphic3d_MaterialAspect) -> AIS_Shape:
def set_material(ais: AIS_Shape, material: Graphic3d_MaterialAspect) -> AIS_Shape:
drawer = ais.Attributes() drawer = ais.Attributes()
drawer.SetupOwnShadingAspect() drawer.SetupOwnShadingAspect()
@@ -142,7 +189,8 @@ def set_material(ais : AIS_Shape, material: Graphic3d_MaterialAspect) -> AIS_Sha
return ais return ais
def set_transparency(ais : AIS_Shape, alpha: float) -> AIS_Shape:
def set_transparency(ais: AIS_Shape, alpha: float) -> AIS_Shape:
drawer = ais.Attributes() drawer = ais.Attributes()
drawer.SetupOwnShadingAspect() drawer.SetupOwnShadingAspect()
@@ -150,6 +198,7 @@ def set_transparency(ais : AIS_Shape, alpha: float) -> AIS_Shape:
return ais return ais
def reload_cq(): def reload_cq():
# NB: order of reloads is important # NB: order of reloads is important
@@ -170,13 +219,13 @@ def reload_cq():
reload(cq.occ_impl.exporters.dxf) reload(cq.occ_impl.exporters.dxf)
reload(cq.occ_impl.exporters.amf) reload(cq.occ_impl.exporters.amf)
reload(cq.occ_impl.exporters.json) reload(cq.occ_impl.exporters.json)
#reload(cq.occ_impl.exporters.assembly) # reload(cq.occ_impl.exporters.assembly)
reload(cq.occ_impl.exporters) reload(cq.occ_impl.exporters)
reload(cq.assembly) reload(cq.assembly)
reload(cq) reload(cq)
def is_obj_empty(obj : Union[cq.Workplane,cq.Shape]) -> bool: def is_obj_empty(obj: Union[cq.Workplane, cq.Shape]) -> bool:
rv = False rv = False