""" Tests basic workplane functionality """ # core modules import os import io from pathlib import Path import re import pytest # my modules from cadquery import * from cadquery import exporters, importers from tests import BaseTest from OCP.GeomConvert import GeomConvert from OCP.BRepBuilderAPI import BRepBuilderAPI_MakeEdge @pytest.fixture(scope="module") def tmpdir(tmp_path_factory): return tmp_path_factory.mktemp("out") @pytest.fixture() def box123(): return Workplane().box(1, 2, 3) def test_step_options(tmpdir): """ Exports a box using the options to decrease STEP file size and then imports that STEP to validate it. """ # Use a temporary directory box_path = os.path.join(tmpdir, "out.step") # Simple object to export box = Workplane().box(1, 1, 1) # Export the STEP with the size-saving options and then import it back in box.val().exportStep(box_path, write_pcurves=False, precision_mode=0) w = importers.importStep(box_path) # Make sure there was a valid box in the exported file assert w.solids().size() == 1 assert w.faces().size() == 6 class TestExporters(BaseTest): def _exportBox(self, eType, stringsToFind, tolerance=0.1, angularTolerance=0.1): """ Exports a test object, and then looks for all of the supplied strings to be in the result returns the result in case the case wants to do more checks also """ p = Workplane("XY").box(1, 2, 3) if eType == exporters.ExportTypes.AMF: s = io.BytesIO() else: s = io.StringIO() exporters.exportShape( p, eType, s, tolerance=tolerance, angularTolerance=angularTolerance ) result = "{}".format(s.getvalue()) for q in stringsToFind: self.assertTrue(result.find(q) > -1) return result def _box(self): return Workplane().box(1, 1, 1) def testSTL(self): # New STL tests have been added; Keep this to test deprecated exportShape self._exportBox(exporters.ExportTypes.STL, ["facet normal"]) def testSVG(self): self._exportBox(exporters.ExportTypes.SVG, [""]) exporters.export(self._box(), "out.amf") def testSTEP(self): self._exportBox(exporters.ExportTypes.STEP, ["FILE_SCHEMA"]) exporters.export(self._box(), "out.step") def testTJS(self): self._exportBox( exporters.ExportTypes.TJS, ["vertices", "formatVersion", "faces"] ) exporters.export(self._box(), "out.tjs") def testVRML(self): exporters.export(self._box(), "out.vrml") with open("out.vrml") as f: res = f.read(10) assert res.startswith("#VRML V2.0") # export again to trigger all paths in the code exporters.export(self._box(), "out.vrml") def testVTP(self): exporters.export(self._box(), "out.vtp") with open("out.vtp") as f: res = f.read(100) assert res.startswith('\n -1: foundmatch = True break assert foundmatch @pytest.mark.parametrize( "id, opt, matchvals", [ (0, None, ["solid", "facet normal"]), (1, {"unknown_opt": 1}, ["solid", "facet normal"]), (2, {"unknown_opt": 1, "ascii": True}, ["solid", "facet normal"]), (3, {"ascii": True}, ["solid", "facet normal"]), ], ) def test_stl_ascii(tmpdir, box123, id, opt, matchvals): """ :param tmpdir: temporary directory fixture :param box123: box fixture :param id: The index or id; output filename is _.stl :param opt: The export opt dict :param matchval: List of strings to match at start of file """ fpath = tmpdir.joinpath(f"stl_ascii_{id}.stl").resolve() assert not fpath.exists() assert matchvals exporters.export(box123, str(fpath), None, 0.1, 0.1, opt) with open(fpath, "r") as f: for i, line in enumerate(f): if i > len(matchvals) - 1: break assert line.find(matchvals[i]) > -1 @pytest.mark.parametrize( "id, opt, matchval", [ (0, {"ascii": False}, b"STL Exported by OpenCASCADE"), (1, {"ASCII": False}, b"STL Exported by OpenCASCADE"), (2, {"ASCII": False, "ascii": True}, b"STL Exported by OpenCASCADE"), (3, {"unknown_opt": 1, "ascii": False}, b"STL Exported by OpenCASCADE"), ], ) def test_stl_binary(tmpdir, box123, id, opt, matchval): """ :param tmpdir: temporary directory fixture :param box123: box fixture :param id: The index or id; output filename is _.stl :param opt: The export opt dict :param matchval: Check that the file starts with the specified value """ fpath = tmpdir.joinpath(f"stl_{id}.stl").resolve() assert not fpath.exists() assert matchval exporters.export(box123, str(fpath), None, 0.1, 0.1, opt) with open(fpath, "rb") as f: r = f.read(len(matchval)) assert r == matchval def test_assy_vtk_rotation(tmpdir): v0 = Vertex.makeVertex(1, 0, 0) assy = Assembly() assy.add( v0, name="v0", loc=Location(Vector(0, 0, 0), Vector(1, 0, 0), 90), ) fwrl = Path(tmpdir, "v0.wrl") assert not fwrl.exists() assy.save(str(fwrl), "VRML") assert fwrl.exists() matched_rot = False with open(fwrl) as f: pat_rot = re.compile("""rotation 1 0 0 1.5707963267""") for line in f: if m := re.search(pat_rot, line): matched_rot = True break assert matched_rot