plotter.py revision 5bf6bf536c7233edb2913dbc4102e946a88c9851
#!/usr/bin/env python
# coding=utf-8
'''
Copyright (C) 2013 Sebastian Wüst, sebi@timewaster.de, http://www.timewasters-place.com/
This program 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 2 of the License, or
(at your option) any later version.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
'''
# standard library
import sys
# local library
import gettext, hpgl_decoder, hpgl_encoder, inkex
inkex.localize()
class MyEffect(inkex.Effect):
def __init__(self):
inkex.Effect.__init__(self)
self.OptionParser.add_option("--tab", action="store", type="string", dest="tab")
self.OptionParser.add_option("--resolutionX", action="store", type="float", dest="resolutionX", default=1016.0, help="Resolution X (dpi)")
self.OptionParser.add_option("--resolutionY", action="store", type="float", dest="resolutionY", default=1016.0, help="Resolution Y (dpi)")
self.OptionParser.add_option("--pen", action="store", type="int", dest="pen", default=1, help="Pen number")
self.OptionParser.add_option("--orientation", action="store", type="string", dest="orientation", default="90", help="orientation")
self.OptionParser.add_option("--mirrorX", action="store", type="inkbool", dest="mirrorX", default="FALSE", help="Mirror X-axis")
self.OptionParser.add_option("--mirrorY", action="store", type="inkbool", dest="mirrorY", default="FALSE", help="Mirror Y-axis")
self.OptionParser.add_option("--center", action="store", type="inkbool", dest="center", default="FALSE", help="Center zero point")
self.OptionParser.add_option("--flat", action="store", type="float", dest="flat", default=1.2, help="Curve flatness")
self.OptionParser.add_option("--useOvercut", action="store", type="inkbool", dest="useOvercut", default="TRUE", help="Use overcut")
self.OptionParser.add_option("--overcut", action="store", type="float", dest="overcut", default=1.0, help="Overcut (mm)")
self.OptionParser.add_option("--useToolOffset", action="store", type="inkbool", dest="useToolOffset", default="TRUE", help="Correct tool offset")
self.OptionParser.add_option("--toolOffset", action="store", type="float", dest="toolOffset", default=0.25, help="Tool offset (mm)")
self.OptionParser.add_option("--toolOffsetReturn", action="store", type="float", dest="toolOffsetReturn", default=2.5, help="Return factor")
self.OptionParser.add_option("--precut", action="store", type="inkbool", dest="precut", default="TRUE", help="Use precut")
self.OptionParser.add_option("--offsetX", action="store", type="float", dest="offsetX", default=0.0, help="X offset (mm)")
self.OptionParser.add_option("--offsetY", action="store", type="float", dest="offsetY", default=0.0, help="Y offset (mm)")
self.OptionParser.add_option("--serialPort", action="store", type="string", dest="serialPort", default="COM1", help="Serial port")
self.OptionParser.add_option("--serialBaudRate", action="store", type="string", dest="serialBaudRate", default="9600", help="Serial Baud rate")
def effect(self):
# gracefully exit script when pySerial is missing
try:
import serial
except ImportError, e:
inkex.errormsg(_("pySerial is not installed."
+ "\n\n1. Download pySerial here: http://pypi.python.org/pypi/pyserial"
+ "\n2. Extract the \"serial\" subfolder from the zip to the following folder: \"C:\\Program Files (x86)\\inkscape\\python\\Lib\\\" (Or wherever your Inkscape is installed to)"
+ "\n3. Restart Inkscape."))
return
# get hpgl data
myHpglEncoder = hpgl_encoder.hpglEncoder(self.document.getroot(), self.options)
try:
self.hpgl = myHpglEncoder.getHpgl()
except Exception as inst:
if inst.args[0] == 'NO_PATHS':
# issue error if no paths found
inkex.errormsg(_("No paths where found. Please convert all objects you want to plot into paths."))
return 1
else:
raise Exception(inst)
# TODO:2013-07-13:Sebastian Wüst:Get preview to work. This requires some work on the C++ side to be able to determine if it is a preview or a final run.
'''
# reparse data for preview
self.options.showMovements = True
self.options.docWidth = float(inkex.unittouu(self.document.getroot().get('width')))
self.options.docHeight = float(inkex.unittouu(self.document.getroot().get('height')))
myHpglDecoder = hpgl_decoder.hpglDecoder(self.hpgl, self.options)
try:
doc, warnings = myHpglDecoder.getSvg()
# deliver document to inkscape
self.document = doc
except Exception as inst:
if inst.args[0] == 'NO_HPGL_DATA':
# do nothing
else:
raise Exception(inst)
'''
# send data to plotter
# TODO:2013-07-13:Sebastian Wüst:Somehow slow down sending to avoid buffer overruns in the plotter on very large drawings.
mySerial = serial.Serial(port=self.options.serialPort, baudrate=self.options.serialBaudRate, timeout=0.1, writeTimeout=None)
mySerial.write(self.hpgl)
# Read back 2 chars to avoid plotter not plotting last command (I have no idea why this is necessary)
mySerial.read(2)
mySerial.close()
if __name__ == '__main__':
# Raise recursion limit to avoid exceptions on big documents
sys.setrecursionlimit(20000);
# start extension
e = MyEffect()
e.affect()
# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99