summaryrefslogtreecommitdiffstats
path: root/share/extensions/plotter.py
blob: ebb69e8a1c07142160d026cc258f8785e9f564a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/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