diff options
| -rw-r--r-- | share/extensions/hpgl_encoder.py | 47 | ||||
| -rw-r--r-- | share/extensions/hpgl_input.inx | 2 | ||||
| -rwxr-xr-x | share/extensions/hpgl_output.py | 3 | ||||
| -rw-r--r-- | share/extensions/plotter.inx | 7 | ||||
| -rw-r--r-- | share/extensions/plotter.py | 107 |
5 files changed, 116 insertions, 50 deletions
diff --git a/share/extensions/hpgl_encoder.py b/share/extensions/hpgl_encoder.py index 692f11cd4..ba9412bde 100644 --- a/share/extensions/hpgl_encoder.py +++ b/share/extensions/hpgl_encoder.py @@ -65,12 +65,12 @@ class hpglEncoder: 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 scaleXY = (self.scaleX + self.scaleY) / 2 - self.options.offsetX = effect.unittouu(str(self.options.offsetX) + "mm") * self.scaleX # mm to dots (plotter coordinate system) - self.options.offsetY = effect.unittouu(str(self.options.offsetY) + "mm") * self.scaleY # mm to dots - self.options.overcut = effect.unittouu(str(self.options.overcut) + "mm") * scaleXY # mm to dots - self.options.toolOffset = effect.unittouu(str(self.options.toolOffset) + "mm") * scaleXY # mm to dots - self.options.flat = self.options.flat / (1016 / ((self.options.resolutionX + self.options.resolutionY) / 2)) # scale flatness to resolution - self.toolOffsetFlat = self.options.flat / self.options.toolOffset * 4.5 # scale flatness to offset + 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.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 if self.options.mirrorX: self.mirrorX = -1.0 @@ -101,10 +101,10 @@ class hpglEncoder: self.divergenceX += (self.sizeX - self.divergenceX) / 2 self.divergenceY += (self.sizeY - self.divergenceY) / 2 elif self.options.useToolOffset: - self.options.offsetX += self.options.toolOffset - self.options.offsetY += self.options.toolOffset - groupmat = [[self.mirrorX * self.scaleX * self.viewBoxTransformX, 0.0, - self.divergenceX + self.options.offsetX], - [0.0, self.mirrorY * self.scaleY * self.viewBoxTransformY, - self.divergenceY + self.options.offsetY]] + self.offsetX += self.toolOffset + self.offsetY += self.toolOffset + groupmat = [[self.mirrorX * self.scaleX * self.viewBoxTransformX, 0.0, - self.divergenceX + self.offsetX], + [0.0, self.mirrorY * self.scaleY * self.viewBoxTransformY, - self.divergenceY + self.offsetY]] groupmat = simpletransform.composeTransform(groupmat, simpletransform.parseTransform('rotate(' + self.options.orientation + ')')) self.vData = [['', -1.0, -1.0], ['', -1.0, -1.0], ['', -1.0, -1.0], ['', -1.0, -1.0]] # store first hpgl commands @@ -112,14 +112,17 @@ class hpglEncoder: # add precut if self.options.useToolOffset and self.options.precut: self.processOffset('PU', 0, 0) - self.processOffset('PD', 0, self.options.toolOffset * 8) + self.processOffset('PD', 0, self.toolOffset * 8) # start conversion self.processGroups(self.doc, groupmat) # shift an empty node in in order to process last node in cache self.processOffset('PU', 0, 0) # add return to zero point self.hpgl += ';PU0,0;' - return self.hpgl + if self.options.debug: + return self.hpgl, self + else: + return self.hpgl, "" def processGroups(self, doc, groupmat): # flatten groups to avoid recursion @@ -165,7 +168,7 @@ class hpglEncoder: # parse and transform path paths = cubicsuperpath.parsePath(paths) simpletransform.applyTransformToPath(mat, paths) - cspsubdiv.cspsubdiv(paths, self.options.flat) + cspsubdiv.cspsubdiv(paths, self.flat) # path to HPGL commands oldPosX = 0.0 oldPosY = 0.0 @@ -190,8 +193,8 @@ class hpglEncoder: # check if point is repeating, if so, ignore if int(round(posX)) != int(round(oldPosX)) or int(round(posY)) != int(round(oldPosY)): overcutLength += self.getLength(oldPosX, oldPosY, posX, posY) - if overcutLength >= self.options.overcut: - newLength = self.changeLength(oldPosX, oldPosY, posX, posY, - (overcutLength - self.options.overcut)) + if overcutLength >= self.overcut: + newLength = self.changeLength(oldPosX, oldPosY, posX, posY, - (overcutLength - self.overcut)) self.processOffset(cmd, newLength[0], newLength[1]) break else: @@ -235,12 +238,12 @@ class hpglEncoder: else: # perform tool offset correction (It's a *tad* complicated, if you want to understand it draw the data as lines on paper) if self.vData[2][0] == 'PD': # If the 3rd entry in the cache is a pen down command make the line longer by the tool offset - pointThree = self.changeLength(self.vData[1][1], self.vData[1][2], self.vData[2][1], self.vData[2][2], self.options.toolOffset) + pointThree = self.changeLength(self.vData[1][1], self.vData[1][2], self.vData[2][1], self.vData[2][2], self.toolOffset) self.storePoint('PD', pointThree[0], pointThree[1]) elif self.vData[0][1] != -1.0: # Elif the 1st entry in the cache is filled with data and the 3rd entry is a pen up command shift # the 3rd entry by the current tool offset position according to the 2nd command - pointThree = self.changeLength(self.vData[0][1], self.vData[0][2], self.vData[1][1], self.vData[1][2], self.options.toolOffset) + pointThree = self.changeLength(self.vData[0][1], self.vData[0][2], self.vData[1][1], self.vData[1][2], self.toolOffset) pointThree[0] = self.vData[2][1] - (self.vData[1][1] - pointThree[0]) pointThree[1] = self.vData[2][2] - (self.vData[1][2] - pointThree[1]) self.storePoint('PU', pointThree[0], pointThree[1]) @@ -250,11 +253,11 @@ class hpglEncoder: self.storePoint('PU', pointThree[0], pointThree[1]) if self.vData[3][0] == 'PD': # If the 4th entry in the cache is a pen down command guide tool to next line with a circle between the prolonged 3rd and 4th entry - if self.getLength(self.vData[2][1], self.vData[2][2], self.vData[3][1], self.vData[3][2]) >= self.options.toolOffset: - pointFour = self.changeLength(self.vData[3][1], self.vData[3][2], self.vData[2][1], self.vData[2][2], - self.options.toolOffset) + if self.getLength(self.vData[2][1], self.vData[2][2], self.vData[3][1], self.vData[3][2]) >= self.toolOffset: + pointFour = self.changeLength(self.vData[3][1], self.vData[3][2], self.vData[2][1], self.vData[2][2], - self.toolOffset) else: pointFour = self.changeLength(self.vData[2][1], self.vData[2][2], self.vData[3][1], self.vData[3][2], - (self.options.toolOffset - self.getLength(self.vData[2][1], self.vData[2][2], self.vData[3][1], self.vData[3][2]))) + (self.toolOffset - self.getLength(self.vData[2][1], self.vData[2][2], self.vData[3][1], self.vData[3][2]))) # get angle start and angle vector angleStart = math.atan2(pointThree[1] - self.vData[2][2], pointThree[0] - self.vData[2][1]) angleVector = math.atan2(pointFour[1] - self.vData[2][2], pointFour[0] - self.vData[2][1]) - angleStart @@ -267,12 +270,12 @@ class hpglEncoder: if angleVector >= 0: angle = angleStart + self.toolOffsetFlat while angle < angleStart + angleVector: - self.storePoint('PD', self.vData[2][1] + math.cos(angle) * self.options.toolOffset, self.vData[2][2] + math.sin(angle) * self.options.toolOffset) + self.storePoint('PD', self.vData[2][1] + math.cos(angle) * self.toolOffset, self.vData[2][2] + math.sin(angle) * self.toolOffset) angle += self.toolOffsetFlat else: angle = angleStart - self.toolOffsetFlat while angle > angleStart + angleVector: - self.storePoint('PD', self.vData[2][1] + math.cos(angle) * self.options.toolOffset, self.vData[2][2] + math.sin(angle) * self.options.toolOffset) + self.storePoint('PD', self.vData[2][1] + math.cos(angle) * self.toolOffset, self.vData[2][2] + math.sin(angle) * self.toolOffset) angle -= self.toolOffsetFlat self.storePoint('PD', pointFour[0], pointFour[1]) diff --git a/share/extensions/hpgl_input.inx b/share/extensions/hpgl_input.inx index 8dd90b3f7..15b91ae98 100644 --- a/share/extensions/hpgl_input.inx +++ b/share/extensions/hpgl_input.inx @@ -9,7 +9,7 @@ <param name="space" type="description"> </param> <param name="resolutionX" type="float" min="1.0" max="4096.0" precision="1" _gui-text="Resolution X (dpi)" _gui-description="The amount of steps in one inch on the X axis (Default: 1016.0)">1016.0</param> <param name="resolutionY" type="float" min="1.0" max="4096.0" precision="1" _gui-text="Resolution Y (dpi)" _gui-description="The amount of steps in one inch on the Y axis (Default: 1016.0)">1016.0</param> - <param name="showMovements" type="boolean" _gui-text="Show Movements between paths" _gui-description="Check this to show movements between paths (Default: Unchecked)">false</param> + <param name="showMovements" type="boolean" _gui-text="Show movements between paths" _gui-description="Check this to show movements between paths (Default: Unchecked)">false</param> <input> <extension>.hpgl</extension> <mimetype>image/hpgl</mimetype> diff --git a/share/extensions/hpgl_output.py b/share/extensions/hpgl_output.py index 93be82980..3844dc332 100755 --- a/share/extensions/hpgl_output.py +++ b/share/extensions/hpgl_output.py @@ -49,10 +49,11 @@ class MyEffect(inkex.Effect): 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 # get hpgl data myHpglEncoder = hpgl_encoder.hpglEncoder(self) try: - self.hpgl = myHpglEncoder.getHpgl() + self.hpgl, debugObject = myHpglEncoder.getHpgl() except Exception as inst: if inst.args[0] == 'NO_PATHS': # issue error if no paths found diff --git a/share/extensions/plotter.inx b/share/extensions/plotter.inx index 7cc9f1c94..70bb85e37 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.</_param> <param name="tab" type="notebook"> <page name="misc" _gui-text="Connection"> - <param name="serialPort" type="string" _gui-text="Serial Port" _gui-description="The port of your serial connection, on Windows something like 'COM1', on Linux something like: '/dev/ttyUSB0' (Default: COM1)">COM1</param> - <param name="serialBaudRate" type="optiongroup" appearance="minimal" _gui-text="Serial Baud rate" _gui-description="The Baud rate of your serial connection (Default: 9600)"> + <param name="serialPort" type="string" _gui-text="Serial port" _gui-description="The port of your serial connection, on Windows something like 'COM1', on Linux something like: '/dev/ttyUSB0' (Default: COM1)">COM1</param> + <param name="serialBaudRate" type="optiongroup" appearance="minimal" _gui-text="Serial baud rate" _gui-description="The Baud rate of your serial connection (Default: 9600)"> <option value="9600">9600</option> <option value="110">110</option> <option value="300">300</option> @@ -33,7 +33,7 @@ <_option value="dsrdtrrtscts">Hardware (DSR/DTR + RTS/CTS)</_option> <_option value="">None</_option> </param> - <param name="commandLanguage" type="optiongroup" appearance="minimal" _gui-text="Command Language" _gui-description="The command language to use - Try different settings to find the one that fits your plotter (Default: HPGL)"> + <param name="commandLanguage" type="optiongroup" appearance="minimal" _gui-text="Command language" _gui-description="The command language to use - Try different settings to find the one that fits your plotter (Default: HPGL)"> <option value="hpgl">HPGL</option> <option value="dmpl">DMPL</option> </param> @@ -70,6 +70,7 @@ <param name="flat" type="float" min="0.1" max="10.0" precision="1" _gui-text="Curve flatness" _gui-description="Curves are divided into lines, this number controls how fine the curves will be reproduced, the smaller the finer (Default: '1.2')">1.2</param> <param name="offsetX" type="float" min="-10000.0" max="10000.0" precision="2" _gui-text="X offset (mm)" _gui-description="The offset to move your plot away from the zero point in mm (Default: '0.00')">0.00</param> <param name="offsetY" type="float" min="-10000.0" max="10000.0" precision="2" _gui-text="Y offset (mm)" _gui-description="The offset to move your plot away from the zero point in mm (Default: '0.00')">0.00</param> + <param name="debug" type="boolean" _gui-text="Show debug information" _gui-description="Check this to get verbose information about the plot without actually sending something to the plotter (A.k.a. data dump). (Default: Unchecked)">false</param> </page> </param> <effect needs-live-preview="false"> diff --git a/share/extensions/plotter.py b/share/extensions/plotter.py index 78d480f05..a5f75f6b3 100644 --- a/share/extensions/plotter.py +++ b/share/extensions/plotter.py @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # standard library import re +import string import sys # local libraries import gettext @@ -54,6 +55,7 @@ class MyEffect(inkex.Effect): self.OptionParser.add_option('--serialBaudRate', action='store', type='string', dest='serialBaudRate', default='9600', help='Serial Baud rate') self.OptionParser.add_option('--flowControl', action='store', type='string', dest='flowControl', default='0', help='Flow control') self.OptionParser.add_option('--commandLanguage', action='store', type='string', dest='commandLanguage', default='hpgl', help='Command Language') + self.OptionParser.add_option('--debug', action='store', type='inkbool', dest='debug', default='FALSE', help='Show debug information') def effect(self): # gracefully exit script when pySerial is missing @@ -68,7 +70,7 @@ class MyEffect(inkex.Effect): # get hpgl data myHpglEncoder = hpgl_encoder.hpglEncoder(self) try: - self.hpgl = myHpglEncoder.getHpgl() + self.hpgl, debugObject = myHpglEncoder.getHpgl() except Exception as inst: if inst.args[0] == 'NO_PATHS': # issue error if no paths found @@ -97,29 +99,88 @@ class MyEffect(inkex.Effect): 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' - # 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 + 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: - type, value, traceback = sys.exc_info() - raise ValueError, ('', type, value), traceback - mySerial.write(self.hpgl) - mySerial.read(2) - mySerial.close() + 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") + else: + inkex.errormsg("\nHPGL data:\n") + inkex.errormsg(self.hpgl) + 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() if __name__ == '__main__': # start extension |
