# -*- coding: utf-8 -*- """ $Id$ Copyright 2009 Lode Leroy This file is part of PyCAM. PyCAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. PyCAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with PyCAM. If not, see <http://www.gnu.org/licenses/>. """ # Inkscape uses a fixed resolution of 90 dpi SVG_OUTPUT_DPI = 90 class SVGExporter(object): def __init__(self, output, unit="mm", maxx=None, maxy=None): if isinstance(output, basestring): # a filename was given self.output = file(output,"w") else: # a stream was given self.output = output if unit == "mm": dots_per_px = SVG_OUTPUT_DPI / 25.4 else: dots_per_px = SVG_OUTPUT_DPI if maxx is None: width = 640 else: width = dots_per_px * maxx if width <= 0: width = 640 if maxy is None: height = 800 else: height = dots_per_px * maxy if height <= 0: height = 800 self.output.write("""<?xml version='1.0'?> <svg xmlns='http://www.w3.org/2000/svg' width='%f' height='%f'> <g transform='translate(0,%f) scale(%.10f)' stroke-width='0.05' font-size='0.2'> """ % (width, height, height, dots_per_px)) self._fill = 'none' self._stroke = 'black' def close(self, close_stream=True): self.output.write("""</g> </svg> """) if close_stream: self.output.close() def stroke(self, stroke): self._stroke = stroke def fill(self, fill): self._fill = fill def AddDot(self, x, y): l = "<circle fill='" + self._fill +"'" + (" cx='%g'" % x) \ + (" cy='%g'" % -y) + " r='0.04'/>\n" self.output.write(l) def AddText(self, x, y, text): l = "<text fill='" + self._fill +"'" + (" x='%g'" % x) \ + (" y='%g'" % -y) + " dx='0.07'>" + text + "</text>\n" self.output.write(l) def AddLine(self, x1, y1, x2, y2): l = "<line fill='" + self._fill +"' stroke='" + self._stroke + "'" \ + (" x1='%.8f'" % x1) + (" y1='%.8f'" % -y1) + (" x2='%.8f'" % x2) \ + (" y2='%.8f'" % -y2) + " />\n" self.output.write(l) def AddPoint(self, p): self.AddDot(p[0], p[1]) def AddPath(self, path): self.AddLines(path.points) def AddLines(self, points): l = "<path fill='" + self._fill +"' stroke='" + self._stroke + "' d='" for i in range(0, len(points)): p = points[i] if i == 0: l += "M " else: l += " L " l += "%.8f %.8f" % (p[0], -p[1]) l += "'/>\n" self.output.write(l) def AddPathList(self, pathlist): for path in pathlist: self.AddPath(path) #TODO: we need to create a unified "Exporter" interface and base class class SVGExporterContourModel(object): def __init__(self, model, unit="mm", **kwargs): self.model = model self.unit = unit def write(self, stream): writer = SVGExporter(stream, unit=self.unit, maxx=self.model.maxx, maxy=self.model.maxy) for polygon in self.model.get_polygons(): points = polygon.get_points() if polygon.is_closed: points.append(points[0]) writer.AddLines(points) writer.close(close_stream=False)