diff options
| author | Sebastian Wüst <sebi@timewaster.de> | 2013-10-03 18:26:22 +0000 |
|---|---|---|
| committer | Sebastian Wüst <sebi@timewaster.de> | 2013-10-03 18:26:22 +0000 |
| commit | 0cccda91e5b2d2ab5d21a6cc1365aa1c73d5bc9c (patch) | |
| tree | 301ec59074358fdfc402ca2e99511eb14477dab8 | |
| parent | small changes + fixes (diff) | |
| download | inkscape-0cccda91e5b2d2ab5d21a6cc1365aa1c73d5bc9c.tar.gz inkscape-0cccda91e5b2d2ab5d21a6cc1365aa1c73d5bc9c.zip | |
parser can now work with multiple pens, better exception handling
(bzr r12417.1.15)
| -rw-r--r-- | share/extensions/hpgl_decoder.py | 78 | ||||
| -rw-r--r-- | share/extensions/hpgl_encoder.py | 9 | ||||
| -rw-r--r-- | share/extensions/hpgl_input.py | 8 | ||||
| -rwxr-xr-x | share/extensions/hpgl_output.py | 3 | ||||
| -rw-r--r-- | share/extensions/plotter.inx | 2 | ||||
| -rw-r--r-- | share/extensions/plotter.py | 36 |
6 files changed, 81 insertions, 55 deletions
diff --git a/share/extensions/hpgl_decoder.py b/share/extensions/hpgl_decoder.py index 977d1bd06..fde81cf39 100644 --- a/share/extensions/hpgl_decoder.py +++ b/share/extensions/hpgl_decoder.py @@ -38,51 +38,71 @@ class hpglDecoder: self.scaleY = options.resolutionY / 90.0 # dots/inch to dots/pixels
self.warnings = []
- def getSvg(self):
- # parse hpgl data
+ def getSvg(self): # parse hpgl data
+ # prepare document
+ self.doc = inkex.etree.parse(StringIO('<svg xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" width="%s" height="%s"></svg>' % (self.options.docWidth, self.options.docHeight)))
+ actualLayer = 0;
+ self.layers = {}
+ if self.options.showMovements:
+ self.layers[0] = inkex.etree.SubElement(self.doc.getroot(), 'g', {inkex.addNS('groupmode','inkscape'):'layer', inkex.addNS('label','inkscape'):'Movements'})
+ # parse paths
# TODO:2013-07-13:Sebastian Wüst:Try to parse all the different HPGL formats correctly.
hpglData = self.hpglString.split(';')
- if hpglData[-1].strip() == '':
- hpglData.pop()
if len(hpglData) < 3:
raise Exception('NO_HPGL_DATA')
- # prepare document
- doc = inkex.etree.parse(StringIO('<svg xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" width="%s" height="%s"></svg>' % (self.options.docWidth, self.options.docHeight)))
- layerDrawing = inkex.etree.SubElement(doc.getroot(), 'g', {inkex.addNS('groupmode','inkscape'):'layer', inkex.addNS('label','inkscape'):'Drawing'})
- if self.options.showMovements:
- layerMovements = inkex.etree.SubElement(doc.getroot(), 'g', {inkex.addNS('groupmode','inkscape'):'layer', inkex.addNS('label','inkscape'):'Movements'})
- # parse paths
oldCoordinates = (0.0, self.options.docHeight)
path = ''
for i, command in enumerate(hpglData):
if command.strip() != '':
- # TODO:2013-07-13:Sebastian Wüst:Implement the HP-GL commands.
+ # TODO:2013-07-13:Sebastian Wüst:Implement all the HP-GL commands.
if command[:2] == 'PU': # if Pen Up command
- if ' L' in path:
- # TODO:2013-07-13:Sebastian Wüst:Make a method for adding a SubElement.
- inkex.etree.SubElement(layerDrawing, 'path', {'d':path, 'style':'stroke:#000000; stroke-width:0.3; fill:none;'})
+ if ' L ' in path:
+ self.addPathToLayer(path, actualLayer)
if self.options.showMovements and i != len(hpglData) - 1:
path = 'M %f,%f' % oldCoordinates
- path += ' L %f,%f' % self.getCoordinates(command[2:])
- inkex.etree.SubElement(layerMovements, 'path', {'d':path, 'style':'stroke:#ff0000; stroke-width:0.3; fill:none;'})
- path = 'M %f,%f' % self.getCoordinates(command[2:])
+ path += ' L %f,%f' % self.getParameters(command[2:])
+ self.addPathToLayer(path, 0)
+ path = 'M %f,%f' % self.getParameters(command[2:])
elif command[:2] == 'PD': # if Pen Down command
- path += ' L %f,%f' % self.getCoordinates(command[2:])
- oldCoordinates = self.getCoordinates(command[2:])
- elif command[:2] == 'IN': # if Initialize command
+ path += ' L %f,%f' % self.getParameters(command[2:])
+ oldCoordinates = self.getParameters(command[2:])
+ elif command[:2] == 'IN': # if Initialize command, ignore
pass
elif command[:2] == 'SP': # if Select Pen command
- # TODO:2013-07-13:Sebastian Wüst:Every pen number should go to a different layer.
- pass
+ actualLayer = command[2:]
+ self.createLayer(actualLayer)
else:
self.warnings.append('UNKNOWN_COMMANDS')
- if ' L' in path:
- inkex.etree.SubElement(layerDrawing, 'path', {'d':path, 'style':'stroke:#000000; stroke-width:0.3; fill:none;'})
- return (doc, self.warnings)
-
- def getCoordinates(self, coord):
- # process coordinates
- (x, y) = coord.split(',')
+ if ' L ' in path:
+ self.addPathToLayer(path, actualLayer)
+ return (self.doc, self.warnings)
+
+ def createLayer(self, layerNumber):
+ self.layers[layerNumber] = inkex.etree.SubElement(self.doc.getroot(), 'g', {inkex.addNS('groupmode','inkscape'):'layer', inkex.addNS('label','inkscape'):'Drawing Pen ' + layerNumber})
+
+ def addPathToLayer(self, path, layerNumber):
+ if layerNumber == 0:
+ lineColor = 'ff0000'
+ else:
+ lineColor = '000000'
+ inkex.etree.SubElement(self.layers[layerNumber], 'path', {'d':path, 'style':'stroke:#' + lineColor + '; stroke-width:0.4; fill:none;'})
+
+ def getParameters(self, parameterString): # process coordinates
+ if parameterString.strip() == '':
+ return []
+ # remove command delimiter
+ parameterString = parameterString.replace(';', '').strip()
+ # correct parameter delimiter
+ parameterString = parameterString.replace(' ', ',')
+ parameterString = parameterString.replace('+', ',')
+ parameterString = parameterString.replace('-', ',-')
+ while ',,' in parameterString:
+ parameterString = parameterString.replace(',,', ',')
+ # split parameter
+ parameterString = parameterString.split(',')
+ return self.correctAbsoluteCoordinates(parameterString[0], parameterString[1])
+
+ def correctAbsoluteCoordinates(self, x, y):
x = float(x) / self.scaleX; # convert to pixels coordinate system
y = self.options.docHeight - float(y) / self.scaleY; # convert to pixels coordinate system, flip vertically for inkscape coordinate system
return (x, y)
diff --git a/share/extensions/hpgl_encoder.py b/share/extensions/hpgl_encoder.py index fa7c1bf3f..8790ade89 100644 --- a/share/extensions/hpgl_encoder.py +++ b/share/extensions/hpgl_encoder.py @@ -137,7 +137,7 @@ class hpglEncoder: mat = simpletransform.composeTransform(mat, simpletransform.parseTransform(trans))
simpletransform.applyTransformToPath(mat, paths)
cspsubdiv.cspsubdiv(paths, self.options.flat)
- # break path into HPGL commands
+ # path to HPGL commands
oldPosX = ''
oldPosY = ''
for singlePath in paths:
@@ -208,9 +208,9 @@ class hpglEncoder: # check if tool offset correction is needed (if the angle is big enough)
if self.vData[2][0] == 'PD' and self.vData[3][0] == 'PD':
# TODO:2013-07-13:Sebastian Wüst:Is this necessary?
- if self.getLength(self.vData[2][1], self.vData[2][2], self.vData[3][1], self.vData[3][2]) < self.options.toolOffset:
- self.storeData(self.vData[2][0], self.vData[2][1], self.vData[2][2])
- return
+ #if self.getLength(self.vData[2][1], self.vData[2][2], self.vData[3][1], self.vData[3][2]) < self.options.toolOffset:
+ # self.storeData(self.vData[2][0], self.vData[2][1], self.vData[2][2])
+ # return
if self.getAlpha(self.vData[1][1], self.vData[1][2], self.vData[2][1], self.vData[2][2], self.vData[3][1], self.vData[3][2]) > 2.748893:
self.storeData(self.vData[2][0], self.vData[2][1], self.vData[2][2])
return
@@ -240,7 +240,6 @@ class hpglEncoder: # TODO:2013-07-13:Sebastian Wüst:Fix that sucker! (number of points in the circle has to be calculated)
alpha1 = math.atan2(pointThreeY - self.vData[2][2], pointThreeX - self.vData[2][1])
alpha2 = math.atan2(pointFourY - self.vData[2][2], pointFourX - self.vData[2][1])
- inkex.errormsg(str(math.fabs(alpha2 - alpha1)))
step = (2 * math.pi - math.fabs(alpha2 - alpha1)) * 6 + 1
#inkex.errormsg(str(alpha1) + ' | ' + str(alpha2))
for alpha in range(int(step), 101, int(step)):
diff --git a/share/extensions/hpgl_input.py b/share/extensions/hpgl_input.py index 3bd698082..e841e1138 100644 --- a/share/extensions/hpgl_input.py +++ b/share/extensions/hpgl_input.py @@ -1,8 +1,6 @@ #!/usr/bin/env python # coding=utf-8 ''' -hpgl_input.py - input a HP Graphics Language file - 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 @@ -21,9 +19,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ''' # standard library +import sys from StringIO import StringIO # local library -import hpgl_decoder, inkex +import hpgl_decoder, inkex, sys inkex.localize() @@ -62,6 +61,7 @@ except Exception as inst: inkex.errormsg(_("No HPGL data found.")) print 1 else: - raise Exception(inst) + type, value, traceback = sys.exc_info() + raise ValueError, ("", type, value), traceback # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99
\ No newline at end of file diff --git a/share/extensions/hpgl_output.py b/share/extensions/hpgl_output.py index 4c3217d63..adee92cae 100755 --- a/share/extensions/hpgl_output.py +++ b/share/extensions/hpgl_output.py @@ -58,7 +58,8 @@ class MyEffect(inkex.Effect): inkex.errormsg(_("No paths where found. Please convert all objects you want to save into paths.")) self.hpgl = 1 else: - raise Exception(inst) + type, value, traceback = sys.exc_info() + raise ValueError, ("", type, value), traceback def output(self): # print to file diff --git a/share/extensions/plotter.inx b/share/extensions/plotter.inx index ebf675a85..c837e1926 100644 --- a/share/extensions/plotter.inx +++ b/share/extensions/plotter.inx @@ -51,7 +51,9 @@ <param name="useToolOffset" type="boolean" _gui-text="Use tool offset correction" _gui-description="Check this to use the tool offset correction, if not checked the 'Tool offset', 'Return Factor' and 'Precut' parameters are unused (Default: Checked)">true</param> <param name="toolOffset" type="float" min="0.0" max="20.0" precision="2" _gui-text="Tool offset (mm)" _gui-description="The offset from the tool tip to the tool axis in mm (Default: 0.25)">0.25</param> <param name="toolOffsetReturn" type="float" min="1.0" max="10.0" precision="2" _gui-text="Return factor" _gui-description="The return factor multiplied by the tool offset is the length that is used to guide the tool back to the original path after an overcut is performed, you can only determine this value by experimentation (Default: 2.50)">2.50</param> + <param name="space" type="description"> </param> <param name="precut" type="boolean" _gui-text="Use precut" _gui-description="Check this to cut a small line before the real drawing to align the tool orientation for the first cut (Default: Checked)">true</param> + <param name="space" type="description"> </param> <_param name="offsetNote" type="description">Please note that using the tool offset correction will move your drawing away from the zero point on both axes by the tool offset specified.</_param> </page> <page name="misc" _gui-text="Miscellaneous"> diff --git a/share/extensions/plotter.py b/share/extensions/plotter.py index 4556e9058..0c802ddc9 100644 --- a/share/extensions/plotter.py +++ b/share/extensions/plotter.py @@ -68,25 +68,29 @@ class MyEffect(inkex.Effect): 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. + type, value, traceback = sys.exc_info() + raise ValueError, ("", type, value), traceback + # 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. (Remember to set <effect needs-live-preview="false"> to true) ''' - # 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) + # 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 + pass + else: + type, value, traceback = sys.exc_info() + raise ValueError, ("", type, value), traceback ''' # send data to plotter + # TODO:2013-07-13:Sebastian Wüst:Slow down sending to prevent buffer overflow (Somewhat esotherical) 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) |
