Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions cadquery/assembly.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import os

from functools import reduce
from typing import (
Union,
Expand Down Expand Up @@ -37,7 +39,7 @@
)
from .occ_impl.importers.assembly import importStep as _importStep, importXbf, importXml

from .types import UnitLiterals
from .types import PathLike, UnitLiterals

from .selectors import _expression_grammar as _selector_grammar
from .utils import deprecate, BiDict, instance_of
Expand Down Expand Up @@ -536,7 +538,7 @@ def solve(self, verbosity: int = 0) -> Self:
@deprecate()
def save(
self,
path: str,
path: PathLike,
exportType: Optional[ExportLiterals] = None,
mode: STEPExportModeLiterals = "default",
tolerance: float = 0.1,
Expand All @@ -563,7 +565,7 @@ def save(

def export(
self,
path: str,
path: PathLike,
exportType: Optional[ExportLiterals] = None,
mode: STEPExportModeLiterals = "default",
tolerance: float = 0.1,
Expand Down Expand Up @@ -596,6 +598,8 @@ def export(
if mode not in get_args(STEPExportModeLiterals):
raise ValueError(f"Unknown assembly export mode {mode} for STEP")

path = os.fspath(path)

if exportType is None:
t = path.split(".")[-1].upper()
if t in ("STEP", "XML", "XBF", "VRML", "VTKJS", "GLTF", "GLB", "STL"):
Expand Down Expand Up @@ -628,7 +632,7 @@ def export(
return self

@classmethod
def importStep(cls, path: str, unit: UnitLiterals = "MM") -> Self:
def importStep(cls, path: PathLike, unit: UnitLiterals = "MM") -> Self:
"""
Reads an assembly from a STEP file.

Expand All @@ -642,14 +646,16 @@ def importStep(cls, path: str, unit: UnitLiterals = "MM") -> Self:
@classmethod
def load(
cls,
path: str,
path: PathLike,
importType: Optional[ImportLiterals] = None,
unit: UnitLiterals = "MM",
) -> Self:
"""
Load step, xbf or xml. Only STEP supports unit conversion on loading.
"""

path = os.fspath(path)

if importType is None:
t = path.split(".")[-1].upper()
if t in ("STEP", "XML", "XBF"):
Expand Down
6 changes: 3 additions & 3 deletions cadquery/cq.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
from .occ_impl.exporters import export

from .utils import deprecate, deprecate_kwarg_name, get_arity
from .types import UnitLiterals
from .types import PathLike, UnitLiterals

from .selectors import (
Selector,
Expand Down Expand Up @@ -1040,7 +1040,7 @@ def toSvg(self, opts: Any = None) -> str:
"""
return getSVG(self.val(), opts)

def exportSvg(self, fileName: str) -> None:
def exportSvg(self, fileName: PathLike) -> None:
"""
Exports the first item on the stack as an SVG file

Expand Down Expand Up @@ -4525,7 +4525,7 @@ def invoke(

def export(
self: T,
fname: str,
fname: PathLike,
tolerance: float = 0.1,
angularTolerance: float = 0.1,
unit: UnitLiterals = "MM",
Expand Down
6 changes: 4 additions & 2 deletions cadquery/occ_impl/exporters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from ...utils import deprecate
from ..shapes import Shape, compound
from ...types import UnitLiterals
from ...types import PathLike, UnitLiterals

from .svg import getSVG
from .json import JsonMesh
Expand Down Expand Up @@ -40,7 +40,7 @@ class ExportTypes:

def export(
w: Union[Shape, Iterable[Shape]],
fname: str,
fname: PathLike,
exportType: Optional[ExportLiterals] = None,
tolerance: float = 0.1,
angularTolerance: float = 0.1,
Expand Down Expand Up @@ -69,6 +69,8 @@ def export(
shape: Shape
f: IO

fname = os.fspath(fname)

if not opt:
opt = {}

Expand Down
26 changes: 19 additions & 7 deletions cadquery/occ_impl/exporters/assembly.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
from ..assembly import AssemblyProtocol, toCAF, toVTK, toFusedCAF
from ..geom import Location
from ..shapes import Shape, Compound
from ...types import UnitLiterals
from ...types import PathLike, UnitLiterals


class ExportModes:
Expand All @@ -61,7 +61,7 @@ class ExportModes:

def exportAssembly(
assy: AssemblyProtocol,
path: str,
path: PathLike,
mode: STEPExportModeLiterals = "default",
unit: UnitLiterals = "MM",
outputUnit: Optional[UnitLiterals] = None,
Expand Down Expand Up @@ -99,6 +99,8 @@ def exportAssembly(
:type name_geometries: bool
"""

path = os.fspath(path)

# Handle the extra settings for the STEP export
pcurves = 1
if "write_pcurves" in kwargs and not kwargs["write_pcurves"]:
Expand Down Expand Up @@ -168,7 +170,7 @@ def exportAssembly(

def exportStepMeta(
assy: AssemblyProtocol,
path: str,
path: PathLike,
write_pcurves: bool = True,
precision_mode: int = 0,
unit: UnitLiterals = "MM",
Expand Down Expand Up @@ -202,6 +204,8 @@ def exportStepMeta(

# Initialize the XCAF document that will allow the STEP export
app = XCAFApp_Application.GetApplication_s()
path = os.fspath(path)

doc = TDocStd_Document(TCollection_ExtendedString("XmlOcaf"))
app.InitDocument(doc)

Expand Down Expand Up @@ -344,11 +348,13 @@ def _process_assembly(
return status == IFSelect_ReturnStatus.IFSelect_RetDone


def exportCAF(assy: AssemblyProtocol, path: str, binary: bool = False) -> bool:
def exportCAF(assy: AssemblyProtocol, path: PathLike, binary: bool = False) -> bool:
"""
Export an assembly to an XCAF xml or xbf file (internal OCCT formats).
"""

path = os.fspath(path)

folder, fname = os.path.split(path)
name, ext = os.path.splitext(fname)
ext = ext[1:] if ext[0] == "." else ext
Expand Down Expand Up @@ -405,11 +411,13 @@ def _vtkRenderWindow(
return renderWindow


def exportVTKJS(assy: AssemblyProtocol, path: str):
def exportVTKJS(assy: AssemblyProtocol, path: PathLike):
"""
Export an assembly to a zipped vtkjs. NB: .zip extensions is added to path.
"""

path = os.fspath(path)

renderWindow = _vtkRenderWindow(assy)

with TemporaryDirectory() as tmpdir:
Expand All @@ -423,14 +431,16 @@ def exportVTKJS(assy: AssemblyProtocol, path: str):

def exportVRML(
assy: AssemblyProtocol,
path: str,
path: PathLike,
tolerance: float = 1e-3,
angularTolerance: float = 0.1,
):
"""
Export an assembly to a vrml file using vtk.
"""

path = os.fspath(path)

exporter = vtkVRMLExporter()
exporter.SetFileName(path)
exporter.SetRenderWindow(_vtkRenderWindow(assy, tolerance, angularTolerance))
Expand All @@ -439,7 +449,7 @@ def exportVRML(

def exportGLTF(
assy: AssemblyProtocol,
path: str,
path: PathLike,
binary: Optional[bool] = None,
tolerance: float = 1e-3,
angularTolerance: float = 0.1,
Expand All @@ -448,6 +458,8 @@ def exportGLTF(
Export an assembly to a gltf file.
"""

path = os.fspath(path)

# If the caller specified the binary option, respect it
if binary is None:
# Handle the binary option for GLTF export based on file extension
Expand Down
4 changes: 3 additions & 1 deletion cadquery/occ_impl/exporters/dxf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
)

import ezdxf

from ...types import PathLike
from ezdxf import units, zoom
from ezdxf.entities import factory
from OCP.GeomConvert import GeomConvert
Expand Down Expand Up @@ -366,7 +368,7 @@ def _dxf_spline(cls, edge: Edge, plane: Plane) -> DxfEntityAttributes:

def exportDXF(
w: Union[WorkplaneLike, Shape, Iterable[Shape]],
fname: str,
fname: PathLike,
approx: Optional[ApproxOptions] = None,
tolerance: float = 1e-3,
*,
Expand Down
3 changes: 2 additions & 1 deletion cadquery/occ_impl/exporters/svg.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import io as StringIO

from ..shapes import Shape, Compound, TOLERANCE
from ...types import PathLike
from ..geom import BoundBox


Expand Down Expand Up @@ -308,7 +309,7 @@ def getSVG(shape, opts=None):
return svg


def exportSVG(shape, fileName: str, opts=None):
def exportSVG(shape, fileName: PathLike, opts=None):
"""
Accept a cadquery shape, and export it to the provided file
TODO: should use file-like objects, not a fileName, and/or be able to return a string instead
Expand Down
10 changes: 8 additions & 2 deletions cadquery/occ_impl/exporters/vtk.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
VTK_POLY_LINE,
)

import os

from ..shapes import Shape
from ...types import PathLike


def extractEdgesFaces(data: vtkPolyData) -> tuple[vtkPolyData, vtkPolyData]:
Expand Down Expand Up @@ -41,11 +44,14 @@ def extractEdgesFaces(data: vtkPolyData) -> tuple[vtkPolyData, vtkPolyData]:


def exportVTP(
shape: Shape, fname: str, tolerance: float = 0.1, angularTolerance: float = 0.1
shape: Shape,
fname: PathLike,
tolerance: float = 0.1,
angularTolerance: float = 0.1,
):

writer = vtkXMLPolyDataWriter()
writer.SetFileName(fname)
writer.SetFileName(os.fspath(fname))
writer.SetInputData(shape.toVtkPolyData(tolerance, angularTolerance))
writer.Write()

Expand Down
21 changes: 13 additions & 8 deletions cadquery/occ_impl/importers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import os

from math import pi
from typing import List, Literal

Expand All @@ -8,7 +10,7 @@
from ... import cq
from ..shapes import Shape
from .dxf import _importDXF
from ...types import UnitLiterals
from ...types import PathLike, UnitLiterals

RAD2DEG = 360.0 / (2 * pi)

Expand All @@ -27,7 +29,7 @@ class UNITS:

def importShape(
importType: Literal["STEP", "DXF", "BREP", "BIN"],
fileName: str,
fileName: PathLike,
unit: UnitLiterals = "MM",
*args,
**kwargs,
Expand All @@ -54,7 +56,7 @@ def importShape(
raise RuntimeError("Unsupported import type: {!r}".format(importType))


def importBrep(fileName: str) -> "cq.Workplane":
def importBrep(fileName: PathLike) -> "cq.Workplane":
"""
Loads the BREP file as a single shape into a cadquery Workplane.

Expand All @@ -71,7 +73,7 @@ def importBrep(fileName: str) -> "cq.Workplane":
return cq.Workplane("XY").newObject([shape])


def importBin(fileName: str) -> "cq.Workplane":
def importBin(fileName: PathLike) -> "cq.Workplane":
"""
Loads the binary BREP file as a single shape into a cadquery Workplane.

Expand All @@ -83,7 +85,7 @@ def importBin(fileName: str) -> "cq.Workplane":
return cq.Workplane("XY").newObject([shape])


def _importStep(fileName: str, unit: UnitLiterals = "MM") -> list["Shape"]:
def _importStep(fileName: PathLike, unit: UnitLiterals = "MM") -> list["Shape"]:
"""
Private helper for implementing different STEP importers.
"""
Expand All @@ -93,7 +95,7 @@ def _importStep(fileName: str, unit: UnitLiterals = "MM") -> list["Shape"]:

# Now read and return the shape
reader = STEPControl_Reader()
readStatus = reader.ReadFile(fileName)
readStatus = reader.ReadFile(os.fspath(fileName))
if readStatus != OCP.IFSelect.IFSelect_RetDone:
raise ValueError("STEP File could not be loaded")
for i in range(reader.NbRootsForTransfer()):
Expand All @@ -105,7 +107,7 @@ def _importStep(fileName: str, unit: UnitLiterals = "MM") -> list["Shape"]:


# Loads a STEP file into a CQ.Workplane object
def importStep(fileName: str, unit: UnitLiterals = "MM") -> "cq.Workplane":
def importStep(fileName: PathLike, unit: UnitLiterals = "MM") -> "cq.Workplane":
"""
Accepts a file name and loads the STEP file into a cadquery Workplane

Expand All @@ -119,7 +121,10 @@ def importStep(fileName: str, unit: UnitLiterals = "MM") -> "cq.Workplane":


def importDXF(
filename: str, tol: float = 1e-6, exclude: List[str] = [], include: List[str] = []
filename: PathLike,
tol: float = 1e-6,
exclude: List[str] = [],
include: List[str] = [],
) -> "cq.Workplane":
"""
Loads a DXF file into a Workplane.
Expand Down
Loading