From 0d8d57a42c58775cba4774bf5b48675d9837957b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20W=C3=BCst?= Date: Thu, 26 Dec 2013 01:20:21 +0100 Subject: added force and speed options and support for KNK Zing plotters (bzr r12858) --- share/extensions/hpgl_decoder.py | 21 ++-- share/extensions/hpgl_encoder.py | 65 ++++++++++-- share/extensions/hpgl_input.inx | 6 +- share/extensions/hpgl_output.inx | 35 ++++--- share/extensions/hpgl_output.py | 34 ++++--- share/extensions/plotter.inx | 50 +++++----- share/extensions/plotter.py | 208 ++++++++++++++++++++++----------------- 7 files changed, 253 insertions(+), 166 deletions(-) diff --git a/share/extensions/hpgl_decoder.py b/share/extensions/hpgl_decoder.py index 96571df94..2401a5612 100644 --- a/share/extensions/hpgl_decoder.py +++ b/share/extensions/hpgl_decoder.py @@ -19,8 +19,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ''' # standard libraries -from StringIO import StringIO import math +from StringIO import StringIO # local library import inkex @@ -60,8 +60,8 @@ class hpglDecoder: path = '' for i, command in enumerate(hpglData): if command.strip() != '': - if command[:2] == 'IN': - # if Initialize command, ignore + if command[:2] == 'IN' or command[:2] == 'FS' or command[:2] == 'VS': + # if Initialize, force or speed command, ignore pass elif command[:2] == 'SP': # if Select Pen command @@ -71,7 +71,7 @@ class hpglDecoder: # if Pen Up command if ' L ' in path: self.addPathToLayer(path, actualLayer) - if self.options.showMovements and i != len(hpglData) - 1: + if self.options.showMovements and oldCoordinates != self.getParameters(command[2:]): path = 'M %f,%f' % oldCoordinates path += ' L %f,%f' % self.getParameters(command[2:]) self.addPathToLayer(path, 0) @@ -83,14 +83,14 @@ class hpglDecoder: if parameterString.strip() != '': parameterString = parameterString.replace(';', '').strip() parameter = parameterString.split(',') - oldCoordinates = (float(parameter[-2]) / self.scaleX, self.options.docHeight - float(parameter[-1]) / self.scaleX) for i, param in enumerate(parameter): if i % 2 == 0: parameter[i] = str(float(param) / self.scaleX) else: - parameter[i] = str(self.options.docHeight - float(param) / self.scaleY) + parameter[i] = str(self.options.docHeight - (float(param) / self.scaleY)) parameterString = ','.join(parameter) path += ' L %s' % parameterString + oldCoordinates = (float(parameter[-2]), float(parameter[-1])) else: self.warning = 'UNKNOWN_COMMANDS' if ' L ' in path: @@ -98,8 +98,11 @@ class hpglDecoder: return (self.doc, self.warning) def createLayer(self, layerNumber): - self.layers[layerNumber] = inkex.etree.SubElement(self.doc.getroot(), 'g', - {inkex.addNS('groupmode', 'inkscape'): 'layer', inkex.addNS('label', 'inkscape'): self.textPenNumber + layerNumber}) + try: + self.layers[layerNumber] + except KeyError: + self.layers[layerNumber] = inkex.etree.SubElement(self.doc.getroot(), 'g', + {inkex.addNS('groupmode', 'inkscape'): 'layer', inkex.addNS('label', 'inkscape'): self.textPenNumber + layerNumber}) def addPathToLayer(self, path, layerNumber): lineColor = '000000' @@ -116,6 +119,6 @@ class hpglDecoder: # split parameter parameter = parameterString.split(',') # convert to svg coordinate system and return - return (float(parameter[0]) / self.scaleX, self.options.docHeight - float(parameter[1]) / self.scaleY) + return (float(parameter[0]) / self.scaleX, self.options.docHeight - (float(parameter[1]) / self.scaleY)) # 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_encoder.py b/share/extensions/hpgl_encoder.py index ba9412bde..db8a0f0a5 100644 --- a/share/extensions/hpgl_encoder.py +++ b/share/extensions/hpgl_encoder.py @@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # standard libraries import math +import re import string # local libraries import bezmisc @@ -35,12 +36,19 @@ import simpletransform class hpglEncoder: PI = math.pi TWO_PI = PI * 2 + # a dictionary of arbitrary unit to user unit conversion factors + # in = Inch; pt = PostScript Point; px = Pixel; mm = Millimeter; cm = Centimeter; + # km = Kilometer; pc = PostScript Pica; yd = Yard; ft = Feet; m = Meter + __USER_UNIT_CONVERSION = {'in':90.0, 'pt':1.25, 'px':1, 'mm':3.5433070866, 'cm':35.433070866, + 'km':3543307.0866, 'pc':15.0, 'yd':3240 , 'ft':1080, 'm':3543.3070866} def __init__(self, effect): ''' options: "resolutionX":float "resolutionY":float "pen":int + "force:int + "speed:int "orientation":string // "0", "90", "-90", "180" "mirrorX":bool "mirrorY":bool @@ -53,22 +61,28 @@ class hpglEncoder: "precut":bool "offsetX":float "offsetY":float + "debug":bool ''' self.doc = effect.document.getroot() self.options = effect.options + self.documentUnit = self.doc.xpath('//sodipodi:namedview/@inkscape:document-units', namespaces=inkex.NSS) + if self.documentUnit: + self.documentUnit = self.documentUnit[0] + else: + self.documentUnit = 'px' self.divergenceX = 'False' self.divergenceY = 'False' self.sizeX = 'False' self.sizeY = 'False' self.dryRun = True self.lastPoint = [0, 0, 0] - self.scaleX = self.options.resolutionX / effect.unittouu("1.0in") # dots per inch to dots per user unit - self.scaleY = self.options.resolutionY / effect.unittouu("1.0in") # dots per inch to dots per user unit + self.scaleX = self.options.resolutionX / self.unitToUserUnit("1.0in") # dots per inch to dots per user unit + self.scaleY = self.options.resolutionY / self.unitToUserUnit("1.0in") # dots per inch to dots per user unit scaleXY = (self.scaleX + self.scaleY) / 2 - self.offsetX = effect.unittouu(str(self.options.offsetX) + "mm") * self.scaleX # mm to dots (plotter coordinate system) - self.offsetY = effect.unittouu(str(self.options.offsetY) + "mm") * self.scaleY # mm to dots - self.overcut = effect.unittouu(str(self.options.overcut) + "mm") * scaleXY # mm to dots - self.toolOffset = effect.unittouu(str(self.options.toolOffset) + "mm") * scaleXY # mm to dots + self.offsetX = self.unitToUserUnit(str(self.options.offsetX) + "mm") * self.scaleX # mm to dots (plotter coordinate system) + self.offsetY = self.unitToUserUnit(str(self.options.offsetY) + "mm") * self.scaleY # mm to dots + self.overcut = self.unitToUserUnit(str(self.options.overcut) + "mm") * scaleXY # mm to dots + self.toolOffset = self.unitToUserUnit(str(self.options.toolOffset) + "mm") * scaleXY # mm to dots self.flat = self.options.flat / (1016 / ((self.options.resolutionX + self.options.resolutionY) / 2)) # scale flatness to resolution self.toolOffsetFlat = self.flat / self.toolOffset * 4.5 # scale flatness to offset self.mirrorX = 1.0 @@ -77,15 +91,25 @@ class hpglEncoder: self.mirrorY = -1.0 if self.options.mirrorY: self.mirrorY = 1.0 + if self.options.debug: + self.debugValues = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # process viewBox attribute to correct page scaling viewBox = self.doc.get('viewBox') self.viewBoxTransformX = 1 self.viewBoxTransformY = 1 + if self.options.debug: + self.debugValues[0] = self.unitToUserUnit(self.doc.get('width'), True) + self.debugValues[1] = self.unitToUserUnit(self.doc.get('height'), True) if viewBox: viewBox = string.split(viewBox, ' ') if viewBox[2] and viewBox[3]: - self.viewBoxTransformX = effect.unittouu(self.doc.get('width')) / effect.unittouu(viewBox[2]) - self.viewBoxTransformY = effect.unittouu(self.doc.get('height')) / effect.unittouu(viewBox[3]) + viewBox[0] = viewBox[2] + viewBox[1] = viewBox[3] + if self.options.debug: + self.debugValues[2] = self.unitToUserUnit(viewBox[0]) + self.debugValues[3] = self.unitToUserUnit(viewBox[1]) + self.viewBoxTransformX = self.unitToUserUnit(self.doc.get('width'), True) / self.unitToUserUnit(viewBox[0]) + self.viewBoxTransformY = self.unitToUserUnit(self.doc.get('height'), True) / self.unitToUserUnit(viewBox[1]) def getHpgl(self): # dryRun to find edges @@ -97,9 +121,14 @@ class hpglEncoder: raise Exception('NO_PATHS') # live run self.dryRun = False + if self.options.debug: + self.debugValues[4] = self.sizeX - self.divergenceX + self.debugValues[5] = self.sizeY - self.divergenceY + self.debugValues[6] = self.unitToUserUnit(str(self.debugValues[4] / self.scaleX)) + self.debugValues[7] = self.unitToUserUnit(str(self.debugValues[5] / self.scaleY)) if self.options.center: - self.divergenceX += (self.sizeX - self.divergenceX) / 2 - self.divergenceY += (self.sizeY - self.divergenceY) / 2 + self.divergenceX += self.sizeX - self.divergenceX / 2 + self.divergenceY += self.sizeY - self.divergenceY / 2 elif self.options.useToolOffset: self.offsetX += self.toolOffset self.offsetY += self.toolOffset @@ -109,6 +138,10 @@ class hpglEncoder: self.vData = [['', -1.0, -1.0], ['', -1.0, -1.0], ['', -1.0, -1.0], ['', -1.0, -1.0]] # store first hpgl commands self.hpgl = 'IN;SP%d' % self.options.pen + if self.options.force > 0: + self.hpgl += ';FS%d' % self.options.force + if self.options.speed > 0: + self.hpgl += ';VS%d' % self.options.speed # add precut if self.options.useToolOffset and self.options.precut: self.processOffset('PU', 0, 0) @@ -124,6 +157,18 @@ class hpglEncoder: else: return self.hpgl, "" + def unitToUserUnit(self, string, isPixels=False): + '''Returns userunits given a string representation of units in another system''' + matches = re.match('^(.*?)(in|pt|px|mm|cm|km|pc|yd|ft|m)?$', string.strip()) + value = float(matches.group(1)) + unit = matches.group(2) + if unit is None: + if isPixels: + unit = "px" + else: + unit = self.documentUnit + return value * self.__USER_UNIT_CONVERSION[unit] / self.__USER_UNIT_CONVERSION[self.documentUnit] + def processGroups(self, doc, groupmat): # flatten groups to avoid recursion paths = [] diff --git a/share/extensions/hpgl_input.inx b/share/extensions/hpgl_input.inx index 15b91ae98..aba7a9308 100644 --- a/share/extensions/hpgl_input.inx +++ b/share/extensions/hpgl_input.inx @@ -7,9 +7,9 @@ inkex.py <_param name="introduction" type="description">Please note that you can only open HPGL files written by Inkscape, to open other HPGL files please change their file extension to .plt, make sure you have UniConverter installed and open them again.   - 1016.0 - 1016.0 - false + 1016.0 + 1016.0 + false .hpgl image/hpgl diff --git a/share/extensions/hpgl_output.inx b/share/extensions/hpgl_output.inx index c51215b4c..a0ba6e364 100644 --- a/share/extensions/hpgl_output.inx +++ b/share/extensions/hpgl_output.inx @@ -9,35 +9,38 @@ <_param name="introduction" type="description">Please make sure that all objects you want to save are converted to paths. The drawing will be automatically aligned to the zero point. Please use the plotter extension (Extensions menu) to plot directly on a plotter. - 1 - 1016.0 - 1016.0 - false - false - + 1016.0 + 1016.0 + 1 + 24 + 20 + - false + false + false + false - true - 1.00 + true + 1.00   - true - 0.25 - true + true + 0.25 + true   - <_param name="offsetNote" type="description">Please note that using the tool offset correction will move your plot away from the zero point by the length in mm specified by the tool offset. + <_param name="offsetNote" type="description">Please note that using the tool offset correction will move your plot away from the zero point by one tool offset length. - 1.2 - 0.00 - 0.00 + 1.2 + 0.00 + 0.00 + <_param name="settingsHelp" type="description">All these settings depend on the plotter you use, for more information please consult the manual or homepage for your plotter. .hpgl image/hpgl diff --git a/share/extensions/hpgl_output.py b/share/extensions/hpgl_output.py index 3844dc332..d6f6b8eec 100755 --- a/share/extensions/hpgl_output.py +++ b/share/extensions/hpgl_output.py @@ -31,22 +31,24 @@ 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='Rotation (Clockwise)') - 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('--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('--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('--force', action='store', type='int', dest='force', default=24, help='Pen force (g)') + self.OptionParser.add_option('--speed', action='store', type='int', dest='speed', default=20, help='Pen speed (cm/s)') + self.OptionParser.add_option('--orientation', action='store', type='string', dest='orientation', default='90', help='Rotation (Clockwise)') + 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('--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)') def effect(self): self.options.debug = False diff --git a/share/extensions/plotter.inx b/share/extensions/plotter.inx index 70bb85e37..e69099e1a 100644 --- a/share/extensions/plotter.inx +++ b/share/extensions/plotter.inx @@ -9,8 +9,8 @@ <_param name="introduction" type="description">Please make sure that all objects you want to plot are converted to paths. The plot will automatically be aligned to the zero point. - COM1 - + COM1 + @@ -27,52 +27,56 @@ - + <_option value="xonxoff">Software (XON/XOFF) <_option value="rtscts">Hardware (RTS/CTS) <_option value="dsrdtrrtscts">Hardware (DSR/DTR + RTS/CTS) <_option value="">None - - - + + + +   - <_param name="serialHelp" type="description">This can be a physical serial connection or a USB-to-Serial bridge. Ask your plotter manufacturer for drivers if needed. <_param name="freezeHelp" type="description">Using wrong settings can under certain circumstances cause Inkscape to freeze. Always save your work before plotting. + <_param name="serialHelp" type="description">This can be a physical serial connection or a USB-to-Serial bridge. Ask your plotter manufacturer for drivers if needed. <_param name="parallelHelp" type="description">Parallel (LPT) connections are not supported. - 1 - 1016.0 - 1016.0 - false - false - + 1016.0 + 1016.0 + 1 + 24 + 20 + - false + false + false + false - true - 1.00 + true + 1.00   - true - 0.25 - true + true + 0.25 + true   - <_param name="offsetNote" type="description">Please note that using the tool offset correction will move your plot away from the zero point by the length in mm specified by the tool offset. + <_param name="offsetNote" type="description">Please note that using the tool offset correction will move your plot away from the zero point by one tool offset length. - 1.2 - 0.00 - 0.00 + 1.2 + 0.00 + 0.00 false + <_param name="settingsHelp" type="description">All these settings depend on the plotter you use, for more information please consult the manual or homepage for your plotter. path diff --git a/share/extensions/plotter.py b/share/extensions/plotter.py index a5f75f6b3..574e2253c 100644 --- a/share/extensions/plotter.py +++ b/share/extensions/plotter.py @@ -39,9 +39,11 @@ class MyEffect(inkex.Effect): 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('--force', action='store', type='int', dest='force', default=24, help='Pen force (g)') + self.OptionParser.add_option('--speed', action='store', type='int', dest='speed', default=20, help='Pen speed (cm/s)') self.OptionParser.add_option('--orientation', action='store', type='string', dest='orientation', default='90', help='Rotation (Clockwise)') - 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('--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') @@ -63,7 +65,7 @@ class MyEffect(inkex.Effect): import serial except ImportError, e: inkex.errormsg(_("pySerial is not installed." - + "\n\n1. Download pySerial here (not the \".exe\"): http://pypi.python.org/pypi/pyserial" + + "\n\n1. Download pySerial here (not the \".exe\"!): http://pypi.python.org/pypi/pyserial" + "\n2. Extract the \"serial\" subfolder from the zip to the following folder: C:\\[Program files]\\inkscape\\python\\Lib\\" + "\n3. Restart Inkscape.")) return @@ -92,95 +94,123 @@ class MyEffect(inkex.Effect): # deliver document to inkscape self.document = doc ''' - if self.options.commandLanguage == 'dmpl': - # convert HPGL to DMPL - self.hpgl = self.hpgl.replace(';', ',') - self.hpgl = self.hpgl.replace('PU', 'U') - self.hpgl = self.hpgl.replace('PD', 'D') - self.hpgl = re.sub(r'IN,SP([0-9]{1,2}),', r';:HAL0P\1EC1', self.hpgl) - self.hpgl += 'Z' + # convert to other formats + if self.options.commandLanguage == 'DMPL': + self.convertToDmpl() + if self.options.commandLanguage == 'ZING': + self.convertToZing() + # output if self.options.debug: - # show debug information - inkex.errormsg("---------------------------------\nDebug information\n---------------------------------\n\nSettings:\n") - inkex.errormsg(' Serial Port: ' + str(self.options.serialPort)) - inkex.errormsg(' Serial baud rate: ' + str(self.options.serialBaudRate)) - inkex.errormsg(' Flow control: ' + str(self.options.flowControl)) - inkex.errormsg(' Command language: ' + str(self.options.commandLanguage)) - inkex.errormsg(' Pen number: ' + str(self.options.pen)) - inkex.errormsg(' Resolution X (dpi): ' + str(self.options.resolutionX)) - inkex.errormsg(' Resolution Y (dpi): ' + str(self.options.resolutionY)) - inkex.errormsg(' Mirror X-axis: ' + str(self.options.mirrorX)) - inkex.errormsg(' Mirror Y-axis: ' + str(self.options.mirrorY)) - inkex.errormsg(' Rotation (Clockwise): ' + str(self.options.orientation)) - inkex.errormsg(' Center zero point: ' + str(self.options.center)) - inkex.errormsg(' Use overcut: ' + str(self.options.useOvercut)) - inkex.errormsg(' Overcut (mm): ' + str(self.options.overcut)) - inkex.errormsg(' Use tool offset correction: ' + str(self.options.useToolOffset)) - inkex.errormsg(' Tool offset (mm): ' + str(self.options.toolOffset)) - inkex.errormsg(' Use precut: ' + str(self.options.precut)) - inkex.errormsg(' Curve flatness: ' + str(self.options.flat)) - inkex.errormsg(' X offset (mm): ' + str(self.options.offsetX)) - inkex.errormsg(' Y offset (mm): ' + str(self.options.offsetY)) - inkex.errormsg(' Show debug information: ' + str(self.options.debug)) - inkex.errormsg("\nDocument properties:\n") - version = self.document.getroot().xpath('//@inkscape:version', namespaces=inkex.NSS) - if version: - inkex.errormsg(' Inkscape version: ' + version[0]) - fileName = self.document.getroot().xpath('//@sodipodi:docname', namespaces=inkex.NSS) - if fileName: - inkex.errormsg(' Filename: ' + fileName[0]) - inkex.errormsg(' Document unit: ' + self.documentUnit) - inkex.errormsg(' Width: ' + str(self.unittouu(self.document.getroot().get('width'))) + ' ' + self.documentUnit) - inkex.errormsg(' Height: ' + str(self.unittouu(self.document.getroot().get('height'))) + ' ' + self.documentUnit) - viewBox = self.document.getroot().get('viewBox') - if viewBox: - viewBox = string.split(viewBox, ' ') - if viewBox[2] and viewBox[3]: - inkex.errormsg(' Viewbox Width: ' + str(self.unittouu(viewBox[2])) + ' ' + self.documentUnit) - inkex.errormsg(' Viewbox Height: ' + str(self.unittouu(viewBox[3])) + ' ' + self.documentUnit) - if self.options.commandLanguage == 'dmpl': - inkex.errormsg("\nDMPL properties:\n") - else: - inkex.errormsg("\nHPGL properties:\n") - inkex.errormsg(' Drawing width: ' + str(self.unittouu(str((debugObject.sizeX - debugObject.divergenceX) / debugObject.scaleX))) + ' ' + self.documentUnit) - inkex.errormsg(' Drawing height: ' + str(self.unittouu(str((debugObject.sizeY - debugObject.divergenceY) / debugObject.scaleY))) + ' ' + self.documentUnit) - inkex.errormsg(' Drawing width: ' + str(debugObject.sizeX - debugObject.divergenceX) + ' plotter steps') - inkex.errormsg(' Drawing height: ' + str(debugObject.sizeY - debugObject.divergenceY) + ' plotter steps') - inkex.errormsg(' Offset X: ' + str(debugObject.offsetX) + ' plotter steps') - inkex.errormsg(' Offset Y: ' + str(debugObject.offsetX) + ' plotter steps') - inkex.errormsg(' Overcut: ' + str(debugObject.overcut) + ' plotter steps') - inkex.errormsg(' Tool offset: ' + str(debugObject.toolOffset) + ' plotter steps') - inkex.errormsg(' Flatness: ' + str(debugObject.flat) + ' plotter steps') - inkex.errormsg(' Tool offset flatness: ' + str(debugObject.toolOffsetFlat) + ' plotter steps') - if self.options.commandLanguage == 'dmpl': - inkex.errormsg("\nDMPL data:\n") + self.showDebugInfo(debugObject) + else: + self.sendHpglToSerial() + + def convertToDmpl(self): + # convert HPGL to DMPL + # ;: = Initialise plotter + # H = Home position + # A = Absolute pen positioning + # Ln = Line type + # Pn = Pen select + # Vn = velocity + # ECn = Coordinate addressing, 1: 0.001 inch, 5: 0.005 inch, M: 0.1 mm + # D = Pen down + # U = Pen up + # Z = Reset plotter + # n,n, = Coordinate pair + self.hpgl = self.hpgl.replace(';', ',') + self.hpgl = self.hpgl.replace('PU', 'U') + self.hpgl = self.hpgl.replace('PD', 'D') + velocity = '' + if self.options.speed > 0: + velocity = 'V' + str(self.options.speed) + self.hpgl = re.sub(r'IN,SP[0-9]+(,FS[0-9]+)?(,VS[0-9]+)?,', r';:HAL0P' + str(self.options.pen) + velocity + 'EC1', self.hpgl) + self.hpgl += 'Z' + + def convertToZing(self): + # convert HPGL to Zing + self.hpgl = self.hpgl.replace('IN;', 'ZG;') + self.hpgl += '@' + + def sendHpglToSerial(self): + # send data to plotter + mySerial = serial.Serial() + mySerial.port = self.options.serialPort + mySerial.baudrate = self.options.serialBaudRate + mySerial.timeout = 0.1 + if self.options.flowControl == 'xonxoff': + mySerial.xonxoff = True + if self.options.flowControl == 'rtscts' or self.options.flowControl == 'dsrdtrrtscts': + mySerial.rtscts = True + if self.options.flowControl == 'dsrdtrrtscts': + mySerial.dsrdtr = True + try: + mySerial.open() + except Exception as inst: + if 'ould not open port' in inst.args[0]: + inkex.errormsg(_("Could not open port. Please check that your plotter is running, connected and the settings are correct.")) + return else: - inkex.errormsg("\nHPGL data:\n") - inkex.errormsg(self.hpgl) + type, value, traceback = sys.exc_info() + raise ValueError, ('', type, value), traceback + mySerial.write(self.hpgl) + mySerial.read(2) + mySerial.close() + + def showDebugInfo(self, debugObject): + # show debug information + inkex.errormsg("---------------------------------\nDebug information\n---------------------------------\n\nSettings:\n") + inkex.errormsg(' Serial Port: ' + str(self.options.serialPort)) + inkex.errormsg(' Serial baud rate: ' + str(self.options.serialBaudRate)) + inkex.errormsg(' Flow control: ' + str(self.options.flowControl)) + inkex.errormsg(' Command language: ' + str(self.options.commandLanguage)) + inkex.errormsg(' Resolution X (dpi): ' + str(self.options.resolutionX)) + inkex.errormsg(' Resolution Y (dpi): ' + str(self.options.resolutionY)) + inkex.errormsg(' Pen number: ' + str(self.options.pen)) + inkex.errormsg(' Pen force (g): ' + str(self.options.force)) + inkex.errormsg(' Pen speed (cm/s): ' + str(self.options.speed)) + inkex.errormsg(' Rotation (Clockwise): ' + str(self.options.orientation)) + inkex.errormsg(' Mirror X axis: ' + str(self.options.mirrorX)) + inkex.errormsg(' Mirror Y axis: ' + str(self.options.mirrorY)) + inkex.errormsg(' Center zero point: ' + str(self.options.center)) + inkex.errormsg(' Use overcut: ' + str(self.options.useOvercut)) + inkex.errormsg(' Overcut (mm): ' + str(self.options.overcut)) + inkex.errormsg(' Use tool offset correction: ' + str(self.options.useToolOffset)) + inkex.errormsg(' Tool offset (mm): ' + str(self.options.toolOffset)) + inkex.errormsg(' Use precut: ' + str(self.options.precut)) + inkex.errormsg(' Curve flatness: ' + str(self.options.flat)) + inkex.errormsg(' X offset (mm): ' + str(self.options.offsetX)) + inkex.errormsg(' Y offset (mm): ' + str(self.options.offsetY)) + inkex.errormsg(' Show debug information: ' + str(self.options.debug)) + inkex.errormsg("\nDocument properties:\n") + version = self.document.getroot().xpath('//@inkscape:version', namespaces=inkex.NSS) + if version: + inkex.errormsg(' Inkscape version: ' + version[0]) + fileName = self.document.getroot().xpath('//@sodipodi:docname', namespaces=inkex.NSS) + if fileName: + inkex.errormsg(' Filename: ' + fileName[0]) + inkex.errormsg(' Document unit: ' + debugObject.documentUnit) + inkex.errormsg(' Width: ' + str(debugObject.debugValues[0]) + ' ' + debugObject.documentUnit) + inkex.errormsg(' Height: ' + str(debugObject.debugValues[1]) + ' ' + debugObject.documentUnit) + if debugObject.debugValues[2] == 0: + inkex.errormsg(' Viewbox Width: -') + inkex.errormsg(' Viewbox Height: -') else: - # send data to plotter - mySerial = serial.Serial() - mySerial.port = self.options.serialPort - mySerial.baudrate = self.options.serialBaudRate - mySerial.timeout = 0.1 - if self.options.flowControl == 'xonxoff': - mySerial.xonxoff = True - if self.options.flowControl == 'rtscts' or self.options.flowControl == 'dsrdtrrtscts': - mySerial.rtscts = True - if self.options.flowControl == 'dsrdtrrtscts': - mySerial.dsrdtr = True - try: - mySerial.open() - except Exception as inst: - if 'ould not open port' in inst.args[0]: - inkex.errormsg(_("Could not open port. Please check that your plotter is running, connected and the settings are correct.")) - return - else: - type, value, traceback = sys.exc_info() - raise ValueError, ('', type, value), traceback - mySerial.write(self.hpgl) - mySerial.read(2) - mySerial.close() + inkex.errormsg(' Viewbox Width: ' + str(debugObject.debugValues[2]) + ' ' + debugObject.documentUnit) + inkex.errormsg(' Viewbox Height: ' + str(debugObject.debugValues[3]) + ' ' + debugObject.documentUnit) + inkex.errormsg("\n" + self.options.commandLanguage + " properties:\n") + inkex.errormsg(' Drawing width: ' + str(debugObject.debugValues[6]) + ' ' + debugObject.documentUnit) + inkex.errormsg(' Drawing height: ' + str(debugObject.debugValues[7]) + ' ' + debugObject.documentUnit) + inkex.errormsg(' Drawing width: ' + str(debugObject.debugValues[4]) + ' plotter steps') + inkex.errormsg(' Drawing height: ' + str(debugObject.debugValues[5]) + ' plotter steps') + inkex.errormsg(' Offset X: ' + str(debugObject.offsetX) + ' plotter steps') + inkex.errormsg(' Offset Y: ' + str(debugObject.offsetX) + ' plotter steps') + inkex.errormsg(' Overcut: ' + str(debugObject.overcut) + ' plotter steps') + inkex.errormsg(' Tool offset: ' + str(debugObject.toolOffset) + ' plotter steps') + inkex.errormsg(' Flatness: ' + str(debugObject.flat) + ' plotter steps') + inkex.errormsg(' Tool offset flatness: ' + str(debugObject.toolOffsetFlat) + ' plotter steps') + inkex.errormsg("\n" + self.options.commandLanguage + " data:\n") + inkex.errormsg(self.hpgl) if __name__ == '__main__': # start extension -- cgit v1.2.3