def testDXF(self): exporters.export(self._box().section(), "out.dxf") with self.assertRaises(ValueError): exporters.export(self._box().val(), "out.dxf") s1 = (Workplane("XZ").polygon(10, 10).ellipse( 1, 2).extrude(1).edges("|Y").fillet(1).section()) exporters.dxf.exportDXF(s1, "res1.dxf") s1_i = importers.importDXF("res1.dxf") self.assertAlmostEqual(s1.val().Area(), s1_i.val().Area(), 6) self.assertAlmostEqual(s1.edges().size(), s1_i.edges().size()) pts = [(0, 0), (0, 0.5), (1, 1)] s2 = (Workplane().spline(pts).close().extrude(1).edges("|Z").fillet( 0.1).section()) exporters.dxf.exportDXF(s2, "res2.dxf") s2_i = importers.importDXF("res2.dxf") self.assertAlmostEqual(s2.val().Area(), s2_i.val().Area(), 6) self.assertAlmostEqual(s2.edges().size(), s2_i.edges().size()) s3 = (Workplane("XY").ellipseArc( 1, 2, 0, 180).close().extrude(1).edges("|Z").fillet(0.1).section()) exporters.dxf.exportDXF(s3, "res3.dxf") s3_i = importers.importDXF("res3.dxf") self.assertAlmostEqual(s3.val().Area(), s3_i.val().Area(), 6) self.assertAlmostEqual(s3.edges().size(), s3_i.edges().size())
def testTypeHandling(self): with self.assertRaises(ValueError): exporters.export(self._box(), "out.random") with self.assertRaises(ValueError): exporters.export(self._box(), "out.stl", "STP")
def export_stl(self, filename: str, tolerance: Optional[float] = 0.001, angular_tolerance: Optional[float] = 0.1) -> str: """Exports an stl file for the Shape.solid. If the provided filename doesn't end with .stl it will be added Args: filename: the filename of the stl file to be exported tolerance: the deflection tolerance of the faceting angular_tolerance: the angular tolerance, in radians """ path_filename = Path(filename) if path_filename.suffix != ".stl": path_filename = path_filename.with_suffix(".stl") path_filename.parents[0].mkdir(parents=True, exist_ok=True) exporters.export(self.solid, str(path_filename), exportType='STL', tolerance=tolerance, angularTolerance=angular_tolerance) print("Saved file as ", path_filename) return str(path_filename)
def testVTP(self): exporters.export(self._box(), "out.vtp") with open("out.vtp") as f: res = f.read(100) assert res.startswith('<?xml version="1.0"?>\n<VTKFile')
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 convert(build_result, output_file=None, error_file=None, output_opts=None): # Create a temporary file to put the STL output into temp_dir = tempfile.gettempdir() temp_file = os.path.join(temp_dir, "temp_stl.stl") # The exporters will add extra output that we do not want, so suppress it with helpers.suppress_stdout_stderr(): # Put the STEP output into the temp file exporters.export(build_result.results[0].shape, temp_file, exporters.ExportTypes.STL) # Read the STEP output back in with open(temp_file, 'r') as file: step_str = file.read() return step_str
def export_stp(self, filename: Optional[str] = None, units: Optional[str] = 'mm', mode: Optional[str] = 'solid') -> str: """Exports an stp file for the Shape.solid. If the filename provided doesn't end with .stp or .step then .stp will be added. If a filename is not provided and the shape's stp_filename property is not None the stp_filename will be used as the export filename. Args: filename (str): the filename of the stp units (str): the units of the stp file, options are 'cm' or 'mm'. Default is mm. mode (str, optional): the object to export can be either 'solid' which exports 3D solid shapes or the 'wire' which exports the wire edges of the shape. Defaults to 'solid'. """ if filename is not None: path_filename = Path(filename) if path_filename.suffix == ".stp" or path_filename.suffix == ".step": pass else: path_filename = path_filename.with_suffix(".stp") path_filename.parents[0].mkdir(parents=True, exist_ok=True) elif self.stp_filename is not None: path_filename = Path(self.stp_filename) if mode == 'solid': exporters.export(self.solid, str(path_filename), exportType='STEP') elif mode == 'wire': exporters.export(self.wire, str(path_filename), exportType='STEP') else: raise ValueError( "The mode argument for export_stp \ only accepts 'solid' or 'wire'", self) if units == 'cm': _replace(path_filename, 'SI_UNIT(.MILLI.,.METRE.)', 'SI_UNIT(.CENTI.,.METRE.)') print("Saved file as ", path_filename) return str(path_filename)
def testSVGOptions(self): self._exportBox(exporters.ExportTypes.SVG, ["<svg", "<g transform"]) exporters.export( self._box(), "out.svg", opt={ "width": 100, "height": 100, "marginLeft": 10, "marginTop": 10, "showAxes": False, "projectionDir": (0, 0, 1), "strokeWidth": 0.25, "strokeColor": (255, 0, 0), "hiddenColor": (0, 0, 255), "showHidden": True, }, )
def testTJS(self): self._exportBox(exporters.ExportTypes.TJS, ["vertices", "formatVersion", "faces"]) exporters.export(self._box(), "out.tjs")
def testSTEP(self): self._exportBox(exporters.ExportTypes.STEP, ["FILE_SCHEMA"]) exporters.export(self._box(), "out.step")
def testAMF(self): self._exportBox(exporters.ExportTypes.AMF, ["<amf units", "</object>"]) exporters.export(self._box(), "out.amf")
def testSVG(self): self._exportBox(exporters.ExportTypes.SVG, ["<svg", "<g transform"]) exporters.export(self._box(), "out.svg")
def testSTL(self): self._exportBox(exporters.ExportTypes.STL, ["facet normal"]) exporters.export(self._box(), "out.stl")
def testDXF(self): exporters.export(self._box().section(), "out.dxf") with self.assertRaises(ValueError): exporters.export(self._box().val(), "out.dxf") s1 = (Workplane("XZ").polygon(10, 10).ellipse( 1, 2).extrude(1).edges("|Y").fillet(1).section()) exporters.dxf.exportDXF(s1, "res1.dxf") s1_i = importers.importDXF("res1.dxf") self.assertAlmostEqual(s1.val().Area(), s1_i.val().Area(), 6) self.assertAlmostEqual(s1.edges().size(), s1_i.edges().size()) pts = [(0, 0), (0, 0.5), (1, 1)] s2 = (Workplane().spline(pts).close().extrude(1).edges("|Z").fillet( 0.1).section()) exporters.dxf.exportDXF(s2, "res2.dxf") s2_i = importers.importDXF("res2.dxf") self.assertAlmostEqual(s2.val().Area(), s2_i.val().Area(), 6) self.assertAlmostEqual(s2.edges().size(), s2_i.edges().size()) s3 = (Workplane("XY").ellipseArc( 1, 2, 0, 180).close().extrude(1).edges("|Z").fillet(0.1).section()) exporters.dxf.exportDXF(s3, "res3.dxf") s3_i = importers.importDXF("res3.dxf") self.assertAlmostEqual(s3.val().Area(), s3_i.val().Area(), 6) self.assertAlmostEqual(s3.edges().size(), s3_i.edges().size()) cyl = Workplane("XY").circle(22).extrude(10, both=True).translate( (-50, 0, 0)) s4 = Workplane("XY").box(80, 60, 5).cut(cyl).section() exporters.dxf.exportDXF(s4, "res4.dxf") s4_i = importers.importDXF("res4.dxf") self.assertAlmostEqual(s4.val().Area(), s4_i.val().Area(), 6) self.assertAlmostEqual(s4.edges().size(), s4_i.edges().size()) # test periodic spline w = Workplane().spline([(1, 1), (2, 2), (3, 2), (3, 1)], periodic=True) exporters.dxf.exportDXF(w, "res5.dxf") w_i = importers.importDXF("res5.dxf") self.assertAlmostEqual(w.val().Length(), w_i.wires().val().Length(), 6) # test rational spline c = Edge.makeCircle(1) adaptor = c._geomAdaptor() curve = GeomConvert.CurveToBSplineCurve_s(adaptor.Curve().Curve()) e = Workplane().add(Edge(BRepBuilderAPI_MakeEdge(curve).Shape())) exporters.dxf.exportDXF(e, "res6.dxf") e_i = importers.importDXF("res6.dxf") self.assertAlmostEqual(e.val().Length(), e_i.wires().val().Length(), 6) # test non-planar section s5 = (Workplane().spline([ (0, 0), (1, 0), (1, 1), (0, 1) ]).close().extrude(1, both=True).translate((-3, -4, 0))) s5.plane = Plane(origin=(0, 0.1, 0.5), normal=(0.05, 0.05, 1)) s5 = s5.section() exporters.dxf.exportDXF(s5, "res7.dxf") s5_i = importers.importDXF("res7.dxf") self.assertAlmostEqual(s5.val().Area(), s5_i.val().Area(), 4)
# store the times spent on each operation in a dict func_times = {} # modify the panel and time each operation for func in funcs: start = timer() face = func(face) end = timer() func_times[func.__name__] = end - start # turn the 2d face into a 3d panel start = timer() panel = face.intersect(panel) end = timer() func_times["intersect face and panel"] = end - start # export outputs start = timer() for output in output_files: exporters.export(panel, output) end = timer() func_times["export output files"] = end - start # print out a summary of the time spent print("\nTime spent doing each task (seconds):\n") for k, v in func_times.items(): print(f"{(k.replace('_', ' ')): <30}{v:.3f}") print(f"\n{'Total time spent': <30}{sum(func_times.values()):.3f}\n")
def export_svg(self, filename: Optional[str] = 'shape.svg', projectionDir: Tuple[float, float, float] = (-1.75, 1.1, 5), width: Optional[float] = 800, height: Optional[float] = 800, marginLeft: Optional[float] = 100, marginTop: Optional[float] = 100, strokeWidth: Optional[float] = None, strokeColor: Optional[Tuple[int, int, int]] = (0, 0, 0), hiddenColor: Optional[Tuple[int, int, int]] = (100, 100, 100), showHidden: Optional[bool] = True, showAxes: Optional[bool] = False) -> str: """Exports an svg file for the Reactor.solid. If the filename provided doesn't end with .svg it will be added. Args: filename: the filename of the svg file to be exported. Defaults to "reactor.svg". projectionDir: The direction vector to view the geometry from (x, y, z). Defaults to (-1.75, 1.1, 5) width: the width of the svg image produced in pixels. Defaults to 1000 height: the height of the svg image produced in pixels. Defaults to 800 marginLeft: the number of pixels between the left edge of the image and the start of the geometry. marginTop: the number of pixels between the top edge of the image and the start of the geometry. strokeWidth: the width of the lines used to draw the geometry. Defaults to None which automatically selects an suitable width. strokeColor: the color of the lines used to draw the geometry in RGB format with each value between 0 and 255. Defaults to (0, 0, 0) which is black. hiddenColor: the color of the lines used to draw the geometry in RGB format with each value between 0 and 255. Defaults to (100, 100, 100) which is light grey. showHidden: If the edges obscured by geometry should be included in the diagram. Defaults to True. showAxes: If the x, y, z axis should be included in the image. Defaults to False. Returns: str: the svg filename created """ path_filename = Path(filename) if path_filename.suffix != ".svg": path_filename = path_filename.with_suffix(".svg") path_filename.parents[0].mkdir(parents=True, exist_ok=True) opt = { "width": width, "height": height, "marginLeft": marginLeft, "marginTop": marginTop, "showAxes": showAxes, "projectionDir": projectionDir, "strokeColor": strokeColor, "hiddenColor": hiddenColor, "showHidden": showHidden } if strokeWidth is not None: opt["strokeWidth"] = strokeWidth exporters.export(self.solid, str(path_filename), exportType='SVG', opt=opt) print("Saved file as ", path_filename) return str(path_filename)