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

@@ -1,186 +1,235 @@
import cadquery as cq import cadquery as cq
from cadquery.occ_impl.assembly import toCAF from cadquery.occ_impl.assembly import toCAF
from typing import List, Union from typing import List, Union
from imp import reload from imp import reload
from types import SimpleNamespace 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,
from OCP.Graphic3d import Graphic3d_NOM_JADE, Graphic3d_MaterialAspect Quantity_Color,
Quantity_NOC_GOLD as GOLD,
from PyQt5.QtGui import QColor )
from OCP.Graphic3d import Graphic3d_NOM_JADE, Graphic3d_MaterialAspect
DEFAULT_FACE_COLOR = Quantity_Color(GOLD)
DEFAULT_MATERIAL = Graphic3d_MaterialAspect(Graphic3d_NOM_JADE) from PyQt5.QtGui import QColor
def find_cq_objects(results : dict): DEFAULT_FACE_COLOR = Quantity_Color(GOLD)
DEFAULT_MATERIAL = Graphic3d_MaterialAspect(Graphic3d_NOM_JADE)
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]): def find_cq_objects(results: dict):
vals = [] return {
k: SimpleNamespace(shape=v, options={})
if isinstance(obj,cq.Workplane): for k, v in results.items()
vals.extend(obj.vals()) if isinstance(v, cq.Workplane)
elif isinstance(obj,cq.Shape): }
vals.append(obj)
elif isinstance(obj,list) and isinstance(obj[0],cq.Workplane):
for o in obj: vals.extend(o.vals()) def to_compound(
elif isinstance(obj,list) and isinstance(obj[0],cq.Shape): obj: Union[cq.Workplane, List[cq.Workplane], cq.Shape, List[cq.Shape], cq.Sketch]
vals.extend(obj) ):
elif isinstance(obj, TopoDS_Shape):
vals.append(cq.Shape.cast(obj)) vals = []
elif isinstance(obj,list) and isinstance(obj[0],TopoDS_Shape): print(obj)
vals.extend(cq.Shape.cast(o) for o in obj) print(dir(obj))
elif hasattr(obj, "wrapped") and isinstance(obj.wrapped, TopoDS_Shape):
vals.append(cq.Shape.cast(obj.wrapped)) if isinstance(obj, cq.Workplane):
elif hasattr(obj, "_obj") and hasattr(obj._obj, "wrapped") and isinstance(obj._obj.wrapped, TopoDS_Shape): vals.extend(obj.vals())
vals.append(cq.Shape.cast(obj._obj.wrapped)) elif isinstance(obj, cq.Shape):
elif isinstance(obj, cq.Sketch): vals.append(obj)
if obj._faces: elif isinstance(obj, list) and isinstance(obj[0], cq.Workplane):
vals.append(obj._faces) for o in obj:
else: vals.extend(o.vals())
vals.extend(obj._edges) elif isinstance(obj, list) and isinstance(obj[0], cq.Shape):
else: vals.extend(obj)
raise ValueError(f'Invalid type {type(obj)}') elif isinstance(obj, TopoDS_Shape):
vals.append(cq.Shape.cast(obj))
return cq.Compound.makeCompound(vals) elif isinstance(obj, list) and isinstance(obj[0], TopoDS_Shape):
vals.extend(cq.Shape.cast(o) for o in obj)
def to_workplane(obj : cq.Shape): elif hasattr(obj, "wrapped") and isinstance(obj.wrapped, TopoDS_Shape):
vals.append(cq.Shape.cast(obj.wrapped))
rv = cq.Workplane('XY') elif (
rv.objects = [obj,] isinstance(obj, list)
and hasattr(obj[0], "wrapped")
return rv and isinstance(obj[0].wrapped, TopoDS_Shape)
):
def make_AIS(obj : Union[cq.Workplane, List[cq.Workplane], cq.Shape, List[cq.Shape], cq.Assembly, AIS_InteractiveObject], vals.extend(o for o in obj)
options={}): elif (
hasattr(obj, "_obj")
shape = None and hasattr(obj._obj, "wrapped")
and isinstance(obj._obj.wrapped, TopoDS_Shape)
if isinstance(obj, cq.Assembly): ):
label, shape = toCAF(obj) vals.append(cq.Shape.cast(obj._obj.wrapped))
ais = XCAFPrs_AISObject(label) elif (
elif isinstance(obj, AIS_InteractiveObject): isinstance(obj, list)
ais = obj and hasattr(obj[0], "_obj")
else: and hasattr(obj[0]._obj, "wrapped")
shape = to_compound(obj) and isinstance(obj[0]._obj.wrapped, TopoDS_Shape)
ais = AIS_Shape(shape.wrapped) ):
vals.append(cq.Shape.cast(obj._obj.wrapped))
set_material(ais, DEFAULT_MATERIAL) elif isinstance(obj, cq.Sketch):
set_color(ais, DEFAULT_FACE_COLOR) if obj._faces:
vals.append(obj._faces)
if 'alpha' in options: else:
set_transparency(ais, options['alpha']) vals.extend(obj._edges)
if 'color' in options: else:
set_color(ais, to_occ_color(options['color'])) raise ValueError(f"Invalid type {type(obj)}")
if 'rgba' in options:
r,g,b,a = options['rgba'] return cq.Compound.makeCompound(vals)
set_color(ais, to_occ_color((r,g,b)))
set_transparency(ais, a)
def to_workplane(obj: cq.Shape):
return ais,shape
rv = cq.Workplane("XY")
def export(obj : Union[cq.Workplane, List[cq.Workplane]], type : str, rv.objects = [
file, precision=1e-1): obj,
]
comp = to_compound(obj)
return rv
if type == 'stl':
comp.exportStl(file, tolerance=precision)
elif type == 'step': def make_AIS(
comp.exportStep(file) obj: Union[
elif type == 'brep': cq.Workplane,
comp.exportBrep(file) List[cq.Workplane],
cq.Shape,
def to_occ_color(color) -> Quantity_Color: List[cq.Shape],
cq.Assembly,
if not isinstance(color, QColor): AIS_InteractiveObject,
if isinstance(color, tuple): ],
if isinstance(color[0], int): options={},
color = QColor(*color) ):
elif isinstance(color[0], float):
color = QColor.fromRgbF(*color) shape = None
else:
raise ValueError('Unknown color format') if isinstance(obj, cq.Assembly):
else: label, shape = toCAF(obj)
color = QColor(color) ais = XCAFPrs_AISObject(label)
elif isinstance(obj, AIS_InteractiveObject):
return Quantity_Color(color.redF(), ais = obj
color.greenF(), else:
color.blueF(), shape = to_compound(obj)
TOC_RGB) ais = AIS_Shape(shape.wrapped)
def get_occ_color(obj : Union[AIS_InteractiveObject, Quantity_Color]) -> QColor: set_material(ais, DEFAULT_MATERIAL)
set_color(ais, DEFAULT_FACE_COLOR)
if isinstance(obj, AIS_InteractiveObject):
color = Quantity_Color() if "alpha" in options:
obj.Color(color) set_transparency(ais, options["alpha"])
else: if "color" in options:
color = obj set_color(ais, to_occ_color(options["color"]))
if "rgba" in options:
return QColor.fromRgbF(color.Red(), color.Green(), color.Blue()) r, g, b, a = options["rgba"]
set_color(ais, to_occ_color((r, g, b)))
def set_color(ais : AIS_Shape, color : Quantity_Color) -> AIS_Shape: set_transparency(ais, a)
drawer = ais.Attributes() return ais, shape
drawer.SetupOwnShadingAspect()
drawer.ShadingAspect().SetColor(color)
def export(
return ais obj: Union[cq.Workplane, List[cq.Workplane]], type: str, file, precision=1e-1
):
def set_material(ais : AIS_Shape, material: Graphic3d_MaterialAspect) -> AIS_Shape:
comp = to_compound(obj)
drawer = ais.Attributes()
drawer.SetupOwnShadingAspect() if type == "stl":
drawer.ShadingAspect().SetMaterial(material) comp.exportStl(file, tolerance=precision)
elif type == "step":
return ais comp.exportStep(file)
elif type == "brep":
def set_transparency(ais : AIS_Shape, alpha: float) -> AIS_Shape: comp.exportBrep(file)
drawer = ais.Attributes()
drawer.SetupOwnShadingAspect() def to_occ_color(color) -> Quantity_Color:
drawer.ShadingAspect().SetTransparency(alpha)
if not isinstance(color, QColor):
return ais if isinstance(color, tuple):
if isinstance(color[0], int):
def reload_cq(): color = QColor(*color)
elif isinstance(color[0], float):
# NB: order of reloads is important color = QColor.fromRgbF(*color)
reload(cq.types) else:
reload(cq.occ_impl.geom) raise ValueError("Unknown color format")
reload(cq.occ_impl.shapes) else:
reload(cq.occ_impl.importers.dxf) color = QColor(color)
reload(cq.occ_impl.importers)
reload(cq.occ_impl.solver) return Quantity_Color(color.redF(), color.greenF(), color.blueF(), TOC_RGB)
reload(cq.occ_impl.assembly)
reload(cq.occ_impl.sketch_solver)
reload(cq.hull) def get_occ_color(obj: Union[AIS_InteractiveObject, Quantity_Color]) -> QColor:
reload(cq.selectors)
reload(cq.sketch) if isinstance(obj, AIS_InteractiveObject):
reload(cq.occ_impl.exporters.svg) color = Quantity_Color()
reload(cq.cq) obj.Color(color)
reload(cq.occ_impl.exporters.utils) else:
reload(cq.occ_impl.exporters.dxf) color = obj
reload(cq.occ_impl.exporters.amf)
reload(cq.occ_impl.exporters.json) return QColor.fromRgbF(color.Red(), color.Green(), color.Blue())
#reload(cq.occ_impl.exporters.assembly)
reload(cq.occ_impl.exporters)
reload(cq.assembly) def set_color(ais: AIS_Shape, color: Quantity_Color) -> AIS_Shape:
reload(cq)
drawer = ais.Attributes()
drawer.SetupOwnShadingAspect()
def is_obj_empty(obj : Union[cq.Workplane,cq.Shape]) -> bool: drawer.ShadingAspect().SetColor(color)
rv = False return ais
if isinstance(obj, cq.Workplane):
rv = True if isinstance(obj.val(), cq.Vector) else False def set_material(ais: AIS_Shape, material: Graphic3d_MaterialAspect) -> AIS_Shape:
return rv drawer = ais.Attributes()
drawer.SetupOwnShadingAspect()
drawer.ShadingAspect().SetMaterial(material)
return ais
def set_transparency(ais: AIS_Shape, alpha: float) -> AIS_Shape:
drawer = ais.Attributes()
drawer.SetupOwnShadingAspect()
drawer.ShadingAspect().SetTransparency(alpha)
return ais
def reload_cq():
# NB: order of reloads is important
reload(cq.types)
reload(cq.occ_impl.geom)
reload(cq.occ_impl.shapes)
reload(cq.occ_impl.importers.dxf)
reload(cq.occ_impl.importers)
reload(cq.occ_impl.solver)
reload(cq.occ_impl.assembly)
reload(cq.occ_impl.sketch_solver)
reload(cq.hull)
reload(cq.selectors)
reload(cq.sketch)
reload(cq.occ_impl.exporters.svg)
reload(cq.cq)
reload(cq.occ_impl.exporters.utils)
reload(cq.occ_impl.exporters.dxf)
reload(cq.occ_impl.exporters.amf)
reload(cq.occ_impl.exporters.json)
# reload(cq.occ_impl.exporters.assembly)
reload(cq.occ_impl.exporters)
reload(cq.assembly)
reload(cq)
def is_obj_empty(obj: Union[cq.Workplane, cq.Shape]) -> bool:
rv = False
if isinstance(obj, cq.Workplane):
rv = True if isinstance(obj.val(), cq.Vector) else False
return rv