Support formats via pstoedit

This commit is contained in:
Florian Festi 2016-06-27 09:10:00 +02:00
parent ab1809c42b
commit 9f4e115c9a
3 changed files with 92 additions and 30 deletions

View File

@ -21,7 +21,7 @@ from argparse import ArgumentParser
import re import re
from functools import wraps from functools import wraps
from boxes import edges from boxes import edges
from boxes import svgutil from boxes import formats
### Helpers ### Helpers
@ -169,6 +169,7 @@ class Boxes:
"""Main class -- Generator should sub class this """ """Main class -- Generator should sub class this """
def __init__(self): def __init__(self):
self.formats = formats.Formats()
self.argparser = ArgumentParser(description=self.__doc__) self.argparser = ArgumentParser(description=self.__doc__)
self.argparser.add_argument( self.argparser.add_argument(
"--fingerjointfinger", action="store", type=float, default=1.0, "--fingerjointfinger", action="store", type=float, default=1.0,
@ -185,6 +186,10 @@ class Boxes:
self.argparser.add_argument( self.argparser.add_argument(
"--output", action="store", type=str, default="box.svg", "--output", action="store", type=str, default="box.svg",
help="name of resulting file") help="name of resulting file")
self.argparser.add_argument(
"--format", action="store", type=str, default="svg",
choices=self.formats.getFormats(),
help="format of resulting file")
self.argparser.add_argument( self.argparser.add_argument(
"--debug", action="store", type=bool, default=False, "--debug", action="store", type=bool, default=False,
help="print surrounding boxes for some structures") help="print surrounding boxes for some structures")
@ -203,7 +208,8 @@ class Boxes:
self.fingerHoleEdgeWidth = 1.0 # multitudes of self.thickness self.fingerHoleEdgeWidth = 1.0 # multitudes of self.thickness
self.bedBoltSettings = (3, 5.5, 2, 20, 15) #d, d_nut, h_nut, l, l1 self.bedBoltSettings = (3, 5.5, 2, 20, 15) #d, d_nut, h_nut, l, l1
self.hexHolesSettings = (5, 3, 'circle') # r, dist, style self.hexHolesSettings = (5, 3, 'circle') # r, dist, style
self._init_surface(1000, 1000) self.surface, self.ctx = self.formats.getSurface(self.format, self.output)
self.ctx.set_line_width(2*self.burn)
self._buildObjects() self._buildObjects()
def buildArgParser(self, *l): def buildArgParser(self, *l):
@ -265,6 +271,10 @@ class Boxes:
for key,value in vars(self.argparser.parse_args(args=args)).items(): for key,value in vars(self.argparser.parse_args(args=args)).items():
setattr(self, key, value) setattr(self, key, value)
# Change file ending to format if not given explicitly
if getattr(self, 'output', None) == 'box.svg':
self.output = 'box.' + getattr(self, "format", "svg")
def addPart(self, part, name=None): def addPart(self, part, name=None):
""" """
Add Edge or other part instance to this one and add it as attribute Add Edge or other part instance to this one and add it as attribute
@ -317,30 +327,6 @@ class Boxes:
# Nuts # Nuts
self.addPart(NutHole(self, None)) self.addPart(NutHole(self, None))
def _init_surface(self, width, height):
"""
Initialize cairo canvas
:param width: canvas size
:param height: canvas height
"""
#mm2pt = 90 / 25.4 / 1.25
mm2pt = 1
#width *= mm2pt
#height *= mm2pt #3.543307
self.surface = cairo.SVGSurface(self.output, width, height)
self.ctx = ctx = cairo.Context(self.surface)
ctx.translate(0, height)
ctx.scale(mm2pt, -mm2pt)
#ctx.set_source_rgb(1.0, 1.0, 1.0)
#ctx.rectangle(0, 0, width, height)
#ctx.fill()
ctx.set_source_rgb(0.0, 0.0, 0.0)
ctx.set_line_width(2*self.burn)
def render(self): def render(self):
"""Implement this method in your sub class. """Implement this method in your sub class.
@ -401,9 +387,7 @@ class Boxes:
self.surface.flush() self.surface.flush()
self.surface.finish() self.surface.finish()
svg = svgutil.SVGFile(self.output) self.formats.convert(self.output, self.format)
svg.getEnvelope()
svg.rewriteViewPort()
############################################################ ############################################################
### Turtle graphics commands ### Turtle graphics commands

76
boxes/formats.py Normal file
View File

@ -0,0 +1,76 @@
import subprocess
import tempfile
import os
import cairo
from boxes import svgutil
class Formats:
pstoedit = "/usr/bin/pstoedit"
formats = {
"svg" : None,
"ps" : None,
"dxf" : "-f dxf -mm".split(),
"gcode" : "-f gcode".split(),
"plt" : "-f hpgl".split(),
}
http_headers = {
"svg" : [('Content-type', 'image/svg+xml; charset=utf-8')],
"ps" : [('Content-type', 'application/postscript')],
"dxf" : [('Content-type', 'image/vnd.dxf')],
"plt" : [('Content-type', ' application/vnd.hp-hpgl')],
"gcode" : [('Content-type', 'text/plain; charset=utf-8')],
# "" : [('Content-type', '')],
}
def __init__(self):
pass
def getFormats(self):
if os.path.isfile(self.pstoedit):
return sorted(self.formats.keys())
else:
return ['svg', 'ps']
def getSurface(self, fmt, filename):
width = height = 1000 # mm
if fmt == "svg":
surface = cairo.SVGSurface(filename, width, height)
mm2pt = 1.0
else:
mm2pt = 72 / 25.4
width *= mm2pt
height *= mm2pt #3.543307
surface = cairo.PSSurface(filename, width, height)
ctx = cairo.Context(surface)
ctx.translate(0, height)
ctx.scale(mm2pt, -mm2pt)
ctx.set_source_rgb(0.0, 0.0, 0.0)
return surface, ctx
def convert(self, filename, fmt):
if fmt == 'svg':
svg = svgutil.SVGFile(filename)
svg.getEnvelope()
svg.rewriteViewPort()
elif fmt == "ps":
pass
else:
fd, tmpfile = tempfile.mkstemp()
cmd = [self.pstoedit] + self.formats[fmt] + [filename, tmpfile]
print(cmd)
err = subprocess.call(cmd)
if err:
# XXX show stderr output
raise ValueError("Conversion failed. pstoedit returned %i" % err)
os.rename(tmpfile, filename)

View File

@ -225,7 +225,9 @@ flex cuts, holes and slots for screws and more high level functions.
return self.errorMessage(name, e) return self.errorMessage(name, e)
start_response(status, start_response(status,
[('Content-type', 'image/svg+xml; charset=utf-8')]) box.formats.http_headers.get(
box.format,
[('Content-type', 'application/unknown; charset=utf-8')]))
fd, box.output = tempfile.mkstemp() fd, box.output = tempfile.mkstemp()
box.render() box.render()
result = open(box.output).readlines() result = open(box.output).readlines()