From 9f503d09129da83aa5fd830eabbbe5c33a9240c1 Mon Sep 17 00:00:00 2001 From: Roipoussiere Date: Thu, 14 Nov 2024 21:14:58 +0100 Subject: [PATCH] use pathlib to manage path names in import/export functions --- src/build123d/exporters.py | 14 +++++++------- src/build123d/exporters3d.py | 26 ++++++++++++++------------ src/build123d/importers.py | 35 +++++++++++++++++------------------ 3 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/build123d/exporters.py b/src/build123d/exporters.py index 4e66b1f2..17e3587d 100644 --- a/src/build123d/exporters.py +++ b/src/build123d/exporters.py @@ -30,6 +30,7 @@ # pylint: disable=no-name-in-module, import-error # pylint: disable=too-many-lines +from pathlib import Path import math import xml.etree.ElementTree as ET from enum import Enum, auto @@ -633,14 +634,13 @@ def _add_single_shape(self, shape: Shape, layer: str = ""): # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - def write(self, file_name: str): + def write(self, file_path: Path): """write - Writes the DXF data to the specified file name. + Writes the DXF data to the specified file path. Args: - file_name (str): The file name (including path) where the DXF data will - be written. + file_path (Path): The file path where the DXF data will be written. """ # Reset the main CAD viewport of the model space to the # extents of its entities. @@ -648,7 +648,7 @@ def write(self, file_name: str): # exposing viewport control to the user. zoom.extents(self._modelspace) - self._document.saveas(file_name) + self._document.saveas(str(file_path)) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1428,7 +1428,7 @@ def _color_attribs(c: Color) -> Tuple[str, str]: # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - def write(self, path: str): + def write(self, file_path: Path): """write Writes the SVG data to the specified file path. @@ -1478,4 +1478,4 @@ def write(self, path: str): xml = ET.ElementTree(svg) ET.indent(xml, " ") - xml.write(path, encoding="utf-8", xml_declaration=True, default_namespace=False) + xml.write(file_path, encoding="utf-8", xml_declaration=True, default_namespace=False) diff --git a/src/build123d/exporters3d.py b/src/build123d/exporters3d.py index 3250678d..190f7e15 100644 --- a/src/build123d/exporters3d.py +++ b/src/build123d/exporters3d.py @@ -30,6 +30,7 @@ # pylint: disable=no-name-in-module, import-error import warnings +from pathlib import Path from io import BytesIO from typing import Union @@ -153,25 +154,26 @@ def _create_xde(to_export: Shape, unit: Unit = Unit.MM) -> TDocStd_Document: return doc -def export_brep(to_export: Shape, file_path: Union[str, BytesIO]) -> bool: +def export_brep(to_export: Shape, file_path: Union[Path, BytesIO]) -> bool: """Export this shape to a BREP file Args: to_export (Shape): object or assembly - file_path: Union[str, BytesIO]: brep file path or memory buffer + file_path: Union[Path, BytesIO]: brep file path or memory buffer Returns: bool: write status """ - return_value = BRepTools.Write_s(to_export.wrapped, file_path) + output = file_path if isinstance(file_path, BytesIO) else str(file_path) + return_value = BRepTools.Write_s(to_export.wrapped, output) return True if return_value is None else return_value def export_gltf( to_export: Shape, - file_path: str, + file_path: Path, unit: Unit = Unit.MM, binary: bool = False, linear_deflection: float = 0.001, @@ -187,7 +189,7 @@ def export_gltf( Args: to_export (Shape): object or assembly - file_path (str): glTF file path + file_path (Path): glTF file path unit (Unit, optional): shape units. Defaults to Unit.MM. binary (bool, optional): output format. Defaults to False. linear_deflection (float, optional): A linear deflection setting which limits @@ -223,7 +225,7 @@ def export_gltf( # Write the glTF file writer = RWGltf_CafWriter( - theFile=TCollection_AsciiString(file_path), theIsBinary=binary + theFile=TCollection_AsciiString(str(file_path)), theIsBinary=binary ) writer.SetParallel(True) index_map = TColStd_IndexedDataMapOfStringString() @@ -249,7 +251,7 @@ def export_gltf( def export_step( to_export: Shape, - file_path: str, + file_path: Path, unit: Unit = Unit.MM, write_pcurves: bool = True, precision_mode: PrecisionMode = PrecisionMode.AVERAGE, @@ -262,7 +264,7 @@ def export_step( Args: to_export (Shape): object or assembly - file_path (str): step file path + file_path (Path): step file path unit (Unit, optional): shape units. Defaults to Unit.MM. write_pcurves (bool, optional): write parametric curves to the STEP file. Defaults to True. @@ -308,7 +310,7 @@ def export_step( Interface_Static.SetIVal_s("write.precision.mode", precision_mode.value) writer.Transfer(doc, STEPControl_StepModelType.STEPControl_AsIs) - status = writer.Write(file_path) == IFSelect_ReturnStatus.IFSelect_RetDone + status = writer.Write(str(file_path)) == IFSelect_ReturnStatus.IFSelect_RetDone if not status: raise RuntimeError("Failed to write STEP file") @@ -317,7 +319,7 @@ def export_step( def export_stl( to_export: Shape, - file_path: str, + file_path: Path, tolerance: float = 1e-3, angular_tolerance: float = 0.1, ascii_format: bool = False, @@ -328,7 +330,7 @@ def export_stl( Args: to_export (Shape): object or assembly - file_path (str): The path and file name to write the STL output to. + file_path (Path): The path and file name to write the STL output to. tolerance (float, optional): A linear deflection setting which limits the distance between a curve and its tessellation. Setting this value too low will result in large meshes that can consume computing resources. Setting the value too high can @@ -354,4 +356,4 @@ def export_stl( else: writer.ASCIIMode = False - return writer.Write(to_export.wrapped, file_path) + return writer.Write(to_export.wrapped, str(file_path)) diff --git a/src/build123d/importers.py b/src/build123d/importers.py index 552b3561..a484cc5d 100644 --- a/src/build123d/importers.py +++ b/src/build123d/importers.py @@ -29,7 +29,6 @@ # pylint has trouble with the OCP imports # pylint: disable=no-name-in-module, import-error -import os from math import degrees from pathlib import Path from typing import TextIO, Union, Optional @@ -92,11 +91,11 @@ } -def import_brep(file_name: str) -> Shape: +def import_brep(file_path: Path) -> Shape: """Import shape from a BREP file Args: - file_name (str): brep file + file_path (Path): brep file path Raises: ValueError: file not found @@ -107,21 +106,21 @@ def import_brep(file_name: str) -> Shape: shape = TopoDS_Shape() builder = BRep_Builder() - BRepTools.Read_s(shape, file_name, builder) + BRepTools.Read_s(shape, str(file_path), builder) if shape.IsNull(): - raise ValueError(f"Could not import {file_name}") + raise ValueError(f"Could not import {file_path}") return Shape.cast(shape) -def import_step(filename: str) -> Compound: +def import_step(file_path: Path) -> Compound: """import_step Extract shapes from a STEP file and return them as a Compound object. Args: - file_name (str): file path of STEP file to import + file_path (Path): STEP file path Raises: ValueError: can't open file @@ -203,8 +202,8 @@ def build_assembly(parent_tdf_label: Optional[TDF_Label] = None) -> list[Shape]: sub_shapes.append(sub_shape) return sub_shapes - if not os.path.exists(filename): - raise FileNotFoundError(filename) + if not Path(file_path).is_file(): + raise FileNotFoundError(file_path) fmt = TCollection_ExtendedString("XCAF") doc = TDocStd_Document(fmt) @@ -214,7 +213,7 @@ def build_assembly(parent_tdf_label: Optional[TDF_Label] = None) -> list[Shape]: reader.SetNameMode(True) reader.SetColorMode(True) reader.SetLayerMode(True) - reader.ReadFile(filename) + reader.ReadFile(str(file_path)) reader.Transfer(doc) root = Compound() @@ -227,7 +226,7 @@ def build_assembly(parent_tdf_label: Optional[TDF_Label] = None) -> list[Shape]: return root -def import_stl(file_name: str) -> Face: +def import_stl(file_path: Path) -> Face: """import_stl Extract shape from an STL file and return it as a Face reference object. @@ -237,7 +236,7 @@ def import_stl(file_name: str) -> Face: of the STL file. Args: - file_name (str): file path of STL file to import + file_path (Path): STL file path Raises: ValueError: Could not import file @@ -246,20 +245,20 @@ def import_stl(file_name: str) -> Face: Face: STL model """ # Read and return the shape - reader = RWStl.ReadFile_s(file_name) + reader = RWStl.ReadFile_s(str(file_path)) face = TopoDS_Face() BRep_Builder().MakeFace(face, reader) stl_obj = Face.cast(face) return stl_obj -def import_svg_as_buildline_code(file_name: str) -> tuple[str, str]: +def import_svg_as_buildline_code(file_path: Path) -> tuple[str, str]: """translate_to_buildline_code Translate the contents of the given svg file into executable build123d/BuildLine code. Args: - file_name (str): svg file name + file_path (Path): svg file path Returns: tuple[str, str]: code, builder instance name @@ -280,10 +279,10 @@ def import_svg_as_buildline_code(file_name: str) -> tuple[str, str]: "sweep", ], } - paths_info = svg2paths(file_name) + file_path = Path(file_path) + paths_info = svg2paths(file_path) paths, _path_attributes = paths_info[0], paths_info[1] - builder_name = os.path.basename(file_name).split(".")[0] - builder_name = builder_name if builder_name.isidentifier() else "builder" + builder_name = file_path.stem if file_path.stem.isidentifier() else "builder" buildline_code = [ "from build123d import *", f"with BuildLine() as {builder_name}:",