diff --git a/inkscape_driver/eggbot.py b/inkscape_driver/eggbot.py index 53695d8..924d5a5 100755 --- a/inkscape_driver/eggbot.py +++ b/inkscape_driver/eggbot.py @@ -3,7 +3,7 @@ # Part of the Eggbot driver for Inkscape # https://github.com/evil-mad/EggBot # -# Version 2.8.1, dated June 19, 2019. +# Version 2.8.5, dated August 9, 2021. # # 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 @@ -19,21 +19,27 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# TODO: Add and honor advisory locking around device open/close for non Win32 - import gettext import math import time -import sys -import cubicsuperpath -import ebb_motion # https://github.com/evil-mad/plotink Requires version 0.2 or newer. -import ebb_serial # https://github.com/evil-mad/plotink +from lxml import etree + +from plot_utils_import import from_dependency_import # plotink +simplepath = from_dependency_import('ink_extensions.simplepath') +simplestyle = from_dependency_import('ink_extensions.simplestyle') +cubicsuperpath = from_dependency_import('ink_extensions.cubicsuperpath') +simpletransform = from_dependency_import('ink_extensions.simpletransform') +inkex = from_dependency_import('ink_extensions.inkex') +exit_status = from_dependency_import('ink_extensions_utils.exit_status') +message = from_dependency_import('ink_extensions_utils.message') +ebb_serial = from_dependency_import('plotink.ebb_serial') # Requires v 0.13 in plotink https://github.com/evil-mad/plotink +ebb_motion = from_dependency_import('plotink.ebb_motion') # Requires v 0.16 in plotink +plot_utils = from_dependency_import('plotink.plot_utils') # Requires v 0.15 in plotink + import eggbot_conf # Some settings can be changed here. -import inkex -import plot_utils # https://github.com/evil-mad/plotink -import simplepath -from simpletransform import applyTransformToPath, composeTransform, parseTransform + + F_DEFAULT_SPEED = 1 N_PEN_DOWN_DELAY = 400 # delay (ms) for the pen to go down before the next move @@ -436,7 +442,7 @@ class EggBot(inkex.Effect): if float(vinfo[2]) != 0 and float(vinfo[3]) != 0: sx = self.svgWidth / float(vinfo[2]) sy = self.svgHeight / float(vinfo[3]) - self.svgTransform = parseTransform('scale({0:f},{1:f}) translate({2:f},{3:f})'.format(sx, sy, -float(vinfo[0]), -float(vinfo[1]))) + self.svgTransform = simpletransform.parseTransform('scale({0:f},{1:f}) translate({2:f},{3:f})'.format(sx, sy, -float(vinfo[0]), -float(vinfo[1]))) self.ServoSetup() ebb_motion.sendEnableMotors(self.serialPort, 1) # 16X microstepping @@ -505,7 +511,7 @@ class EggBot(inkex.Effect): continue # first apply the current matrix transform to this node's transform - mat_new = composeTransform(mat_current, parseTransform(node.get("transform"))) + mat_new = simpletransform.composeTransform(mat_current, simpletransform.parseTransform(node.get("transform"))) if node.tag in [inkex.addNS('g', 'svg'), 'g']: @@ -515,7 +521,10 @@ class EggBot(inkex.Effect): if not self.allLayers: self.DoWePlotLayer(self.sCurrentLayerName) self.recursivelyTraverseSvg(node, mat_new, parent_visibility=v) - + elif node.tag in [inkex.addNS('switch', 'svg'), 'switch']: + # Treat switch as a container element to plot + self.penUp() + self.recursivelyTraverseSvg(node, mat_new, parent_visibility=v) elif node.tag in [inkex.addNS('use', 'svg'), 'use']: # A element refers to another SVG element via an xlink:href="#blah" @@ -541,7 +550,7 @@ class EggBot(inkex.Effect): y = float(node.get('y', '0')) # Note: the transform has already been applied if x != 0 or y != 0: - mat_new2 = composeTransform(mat_new, parseTransform('translate({0:f},{1:f})'.format(x, y))) + mat_new2 = simpletransform.composeTransform(mat_new, simpletransform.parseTransform('translate({0:f},{1:f})'.format(x, y))) else: mat_new2 = mat_new v = node.get('visibility', v) @@ -842,19 +851,19 @@ class EggBot(inkex.Effect): inkex.addNS('flowRoot', 'svg'), 'flowRoot']: if 'text' not in self.warnings: inkex.errormsg(gettext.gettext('Warning: in layer "' + - self.sCurrentLayerName + '" unable to draw text; ' + - 'please convert it to a path first. Consider using the ' + - 'Hershey Text extension which is located under the ' + - '"Render" category of extensions.')) + str(self.sCurrentLayerName) + '" unable to draw text; ' + + 'please convert it to a path first. Consider using the ' + + 'Hershey Text extension which is located in the menu' + + 'under Extensions > Text.')) self.warnings['text'] = 1 pass elif node.tag in [inkex.addNS('image', 'svg'), 'image']: if 'image' not in self.warnings: inkex.errormsg(gettext.gettext('Warning: in layer "' + - self.sCurrentLayerName + '" unable to draw bitmap images; ' + - 'please convert them to line art first. Consider using the "Trace bitmap..." ' + - 'tool of the "Path" menu. Mac users please note that some X11 settings may ' + - 'cause cut-and-paste operations to paste in bitmap copies.')) + str(self.sCurrentLayerName) + '" unable to draw bitmap images; ' + + 'please convert them to line art first. Consider using the "Trace bitmap..." ' + + 'tool of the "Path" menu. Mac users please note that some X11 settings may ' + + 'cause cut-and-paste operations to paste in bitmap copies.')) self.warnings['image'] = 1 pass elif node.tag in [inkex.addNS('pattern', 'svg'), 'pattern']: @@ -874,19 +883,14 @@ class EggBot(inkex.Effect): elif node.tag in [inkex.addNS('color-profile', 'svg'), 'color-profile']: # Gamma curves, color temp, etc. are not relevant to single color output pass - elif not isinstance(node.tag, basestring): - # This is likely an XML processing instruction such as an XML - # comment. lxml uses a function reference for such node tags - # and as such the node tag is likely not a printable string. - # Further, converting it to a printable string likely won't - # be very useful. + elif node.tag in [inkex.addNS('foreignObject', 'svg'), 'foreignObject']: pass else: if str(node.tag) not in self.warnings: t = str(node.tag).split('}') inkex.errormsg(gettext.gettext('Warning: in layer "' + - self.sCurrentLayerName + '" unable to draw <' + str(t[-1]) + - '> object, please convert it to a path first.')) + str(self.sCurrentLayerName) + '" unable to draw <' + str(t[-1]) + + '> object, please convert it to a path first.')) self.warnings[str(node.tag)] = 1 pass @@ -904,11 +908,7 @@ class EggBot(inkex.Effect): temp_num_string = 'x' string_pos = 1 - if sys.version_info < (3,): # Yes this is ugly. More elegant suggestions welcome. :) - current_layer_name = str_layer_name.encode('ascii', 'ignore') # Drop non-ascii characters - else: - current_layer_name = str(str_layer_name) - + current_layer_name = str(str_layer_name) current_layer_name.lstrip() # Remove leading whitespace # Look at layer name. Sample first character, then first two, and @@ -918,14 +918,14 @@ class EggBot(inkex.Effect): max_length = len(current_layer_name) if max_length > 0: while string_pos <= max_length: - if str.isdigit(current_layer_name[:string_pos]): + if current_layer_name[:string_pos].isdigit(): temp_num_string = current_layer_name[:string_pos] # Store longest numeric string so far string_pos += 1 else: break self.plotCurrentLayer = False # Temporarily assume that we aren't plotting the layer - if str.isdigit(temp_num_string): + if temp_num_string.isdigit(): if self.svgLayer == int(float(temp_num_string)): self.plotCurrentLayer = True # We get to plot the layer! self.LayersPlotted += 1 @@ -959,7 +959,7 @@ class EggBot(inkex.Effect): p = cubicsuperpath.parsePath(d) # ...and apply the transformation to each point - applyTransformToPath(mat_transform, p) + simpletransform.applyTransformToPath(mat_transform, p) # p is now a list of lists of cubic beziers [control pt1, control pt2, endpoint] # where the start-point is the last point in the previous segment. @@ -1021,7 +1021,7 @@ class EggBot(inkex.Effect): def penDown(self): self.virtualPenIsUp = False # Virtual pen keeps track of state for resuming plotting. - if self.bPenIsUp or self.bPenIsUp == None:: # Continue only if pen state is up (or unknown) + if self.bPenIsUp or self.bPenIsUp == None: # Continue only if pen state is up (or unknown) if not self.resumeMode and not self.bStopped: # skip if we're resuming or stopped self.bPenIsUp = False if self.penDownActivatesEngraver: @@ -1125,8 +1125,8 @@ class EggBot(inkex.Effect): n_time = int(math.ceil(1000.0 / self.fSpeed * plot_utils.distance(n_delta_x, n_delta_y))) while abs(n_delta_x) > 0 or abs(n_delta_y) > 0: - xd = n_delta_x - yd = n_delta_y + xd = int(n_delta_x) + yd = int(n_delta_y) td = n_time if td < 1: td = 1 # don't allow zero-time moves. diff --git a/inkscape_driver/eggbot_hatch.inx b/inkscape_driver/eggbot_hatch.inx index 69d364d..944b152 100755 --- a/inkscape_driver/eggbot_hatch.inx +++ b/inkscape_driver/eggbot_hatch.inx @@ -7,56 +7,64 @@ - <_param name="Header" type="description" xml:space="preserve"> -This extension fills each closed figure in your drawing -with a path consisting of back and forth drawn "hatch" lines. -If any objects are selected, then only those selected objects -will be filled. + <_param name="Header" type="description"> +An extension to fill all (or selected) closed figures in your +drawing with paths consisting of back-and-forth hatch lines. + -Hatched figures will be grouped with their fills. - - 3.0 - 45 - false +3.0 - true - 3.0 - true - 1.0 - 3.0 + + <_option value="2">px + <_option value="3">mm + <_option value="4">inch + - - (v2.3.2, March 27, 2020) +45 +false - - - <_param name="aboutpage" type="description" xml:space="preserve"> -Hatch spacing is the distance between hatch lines, -measured in units of screen pixels (px). Angles are in -degrees from horizontal; for example 90 is vertical. + -The Crosshatch option will apply a second set of -hatches, perpendicular to the first. +true +3.0 -The "Connect nearby ends" option will attempt to connect -nearby line ends with a smoothly flowing curve, to improve -the smoothness of plotting. + +true +0.5 -The Range parameter sets the distance (in hatch widths) -over which that option searches for segments to join. -Large values may result in hatches where you don't want -them. Consider using a value in the range of 2-4. + +2.0 -The Inset option allows you to hold back the edges of the -fill somewhat from the edge of your original object. -This can improve performance, as it allows you to more -reliably "color inside the lines" when using pens. - -The hatches will be the same color and width -as the original object. - -The Tolerance parameter affects how precisely -the hatches try to fill the input paths. + + + +Hatch spacing is the distance between hatch lines, measured in selected units. Hatch angle is in +degrees from horizontal; e.g., 90 for vertical. + +The Crosshatch option will add a second set of hatches, perpendicular to the first. + +The Connect Nearby Ends option will join nearby line ends with a smooth curve, giving a different +appearance and reducing the number of pen lifts when using robotic tools like pen plotters. The +Range parameter sets the distance (in hatch spacing) over which end connections may be made. Large +values may result in hatches where you don't want them. + +The Inset Fill from Edges option allows you to hold back the hatches away from the edge of your +original object. This can allow you to more reliably "color inside the lines". + +The Tolerance parameter affects how precisely the hatches try to fill the input paths. + +Hatches will have the same stroke color and width as the original object. When filling more than one +object, the hatches will be grouped with their original (filled) objects. + + + +v2.4.1. Copyright 2021, Evil Mad Scientist diff --git a/inkscape_driver/eggbot_hatch.py b/inkscape_driver/eggbot_hatch.py old mode 100755 new mode 100644 index 012627c..1262936 --- a/inkscape_driver/eggbot_hatch.py +++ b/inkscape_driver/eggbot_hatch.py @@ -84,8 +84,12 @@ # This prevents extremely complex plots from generating glitches # Modifications are limited to recursivelyTraverseSvg and effect methods +# Updated by Windell H. Oskay, 2021 +# Add option for selecting units. +# Make inset settable in selected units as well. + # Current software version: -# (v2.3.2, March 27, 2020) +# (v2.4.1, October 9, 2021<) # # 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 @@ -102,26 +106,17 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import math +from lxml import etree -try: - from plot_utils_import import from_dependency_import # plotink - inkex = from_dependency_import('ink_extensions.inkex') - simplepath = from_dependency_import('ink_extensions.simplepath') - simpletransform = from_dependency_import('ink_extensions.simpletransform') - simplestyle = from_dependency_import('ink_extensions.simplestyle') - cubicsuperpath = from_dependency_import('ink_extensions.cubicsuperpath') - cspsubdiv = from_dependency_import('ink_extensions.cspsubdiv') - bezmisc = from_dependency_import('ink_extensions.bezmisc') -except: - import inkex - import simplepath - import simpletransform - import simplestyle - import cubicsuperpath - import cspsubdiv - import bezmisc - -import plot_utils # https://github.com/evil-mad/plotink +from axidrawinternal.plot_utils_import import from_dependency_import # plotink +inkex = from_dependency_import('ink_extensions.inkex') +simplepath = from_dependency_import('ink_extensions.simplepath') +simpletransform = from_dependency_import('ink_extensions.simpletransform') +simplestyle = from_dependency_import('ink_extensions.simplestyle') +cubicsuperpath = from_dependency_import('ink_extensions.cubicsuperpath') +cspsubdiv = from_dependency_import('ink_extensions.cspsubdiv') +bezmisc = from_dependency_import('ink_extensions.bezmisc') +plot_utils = from_dependency_import('plotink.plot_utils') # https://github.com/evil-mad/plotink N_PAGE_WIDTH = 3200 N_PAGE_HEIGHT = 800 @@ -480,7 +475,7 @@ def interstices(self, p1, p2, paths, hatches, b_hold_back_hatches, f_hold_back_s # remove it from consideration by marking it as already drawn - a # fiction, but is much quicker than actually removing the hatch from the list. - f_min_allowed_hatch_length = self.options.hatchSpacing * MIN_HATCH_FRACTION + f_min_allowed_hatch_length = self.hatch_spacing_px * MIN_HATCH_FRACTION f_initial_hatch_length = math.hypot(x2 - x1, y2 - y1) # We did as much as possible of the inset operation back when we were finding intersections. # We did it back then because at that point we knew more about the geometry than we know now. @@ -619,19 +614,19 @@ class Eggbot_Hatch(inkex.Effect): self.docTransform = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]] self.OptionParser.add_option( - "--holdBackSteps", action="store", type="float", - dest="holdBackSteps", default=3.0, - help="How far hatch strokes stay from boundary (steps)") + "--inset_dist", action="store", type="float", + dest="inset_dist", default=3.0, + help="How far hatch strokes stay from boundary") self.OptionParser.add_option( "--hatchScope", action="store", type="float", dest="hatchScope", default=3.0, help="Radius searched for segments to join (units of hatch width)") self.OptionParser.add_option( - "--holdBackHatchFromEdges", action="store", dest="holdBackHatchFromEdges", + "--inset_bool", action="store", dest="inset_bool", type="inkbool", default=True, help="Stay away from edges, so no need for inset") self.OptionParser.add_option( - "--reducePenLifts", action="store", dest="reducePenLifts", + "--connect_bool", action="store", dest="connect_bool", type="inkbool", default=True, help="Reduce plotting time by joining some hatches") self.OptionParser.add_option( @@ -648,11 +643,18 @@ class Eggbot_Hatch(inkex.Effect): help="Spacing between hatch lines") self.OptionParser.add_option( "--tolerance", action="store", type="float", - dest="tolerance", default=20.0, + dest="tolerance", default=3.0, help="Allowed deviation from original paths") + self.OptionParser.add_option( + "--units", + action="store", type="int", + dest="units", default=1, + help="Units to use for hatches. 1: line width. 2: px. 3: mm. 4: inch") + self.OptionParser.add_option("--tab", # NOTE: value is not used. - action="store", type="string", dest="tab", default="splash", + action="store", type="string", dest="_tab", default="splash", help="The active tab when Apply was pressed") + def getDocProps(self): @@ -812,7 +814,17 @@ class Eggbot_Hatch(inkex.Effect): if v == 'inherit': v = parent_visibility if v == 'hidden' or v == 'collapse': - pass + continue + + style = simplestyle.parseStyle(node.get('style')) + + # Check for "display:none" in the node's style attribute: + if 'display' in style.keys() and style['display'] == 'none': + continue # Do not hatch this object or its children + + # The node may have a display="none" attribute as well: + if node.get('display') == 'none': + continue # Do not hatch this object or its children # first apply the current matrix transform to this node's transform mat_new = simpletransform.composeTransform(mat_current, simpletransform.parseTransform(node.get("transform"))) @@ -858,13 +870,13 @@ class Eggbot_Hatch(inkex.Effect): self.addPathVertices(path_data, node, mat_new) # We now have a path we want to apply a (cross)hatch to # Apply appropriate functions - b_have_grid = self.makeHatchGrid(float(self.options.hatchAngle), float(self.options.hatchSpacing), True) + b_have_grid = self.makeHatchGrid(float(self.options.hatchAngle), float(self.hatch_spacing_px), True) if b_have_grid: if self.options.crossHatch: - self.makeHatchGrid(float(self.options.hatchAngle + 90.0), float(self.options.hatchSpacing), False) + self.makeHatchGrid(float(self.options.hatchAngle + 90.0), float(self.hatch_spacing_px), False) # Now loop over our hatch lines looking for intersections for h in self.grid: - interstices(self, (h[0], h[1]), (h[2], h[3]), self.paths, self.hatches, self.options.holdBackHatchFromEdges, self.options.holdBackSteps) + interstices(self, (h[0], h[1]), (h[2], h[3]), self.paths, self.hatches, self.options.inset_bool, self.inset_dist_px) elif node.tag in [inkex.addNS('rect', 'svg'), 'rect']: @@ -894,13 +906,13 @@ class Eggbot_Hatch(inkex.Effect): self.addPathVertices(simplepath.formatPath(a), node, mat_new) # We now have a path we want to apply a (cross)hatch to # Apply appropriate functions - b_have_grid = self.makeHatchGrid(float(self.options.hatchAngle), float(self.options.hatchSpacing), True) + b_have_grid = self.makeHatchGrid(float(self.options.hatchAngle), float(self.hatch_spacing_px), True) if b_have_grid: if self.options.crossHatch: - self.makeHatchGrid(float(self.options.hatchAngle + 90.0), float(self.options.hatchSpacing), False) + self.makeHatchGrid(float(self.options.hatchAngle + 90.0), float(self.hatch_spacing_px), False) # Now loop over our hatch lines looking for intersections for h in self.grid: - interstices(self, (h[0], h[1]), (h[2], h[3]), self.paths, self.hatches, self.options.holdBackHatchFromEdges, self.options.holdBackSteps) + interstices(self, (h[0], h[1]), (h[2], h[3]), self.paths, self.hatches, self.options.inset_bool, self.inset_dist_px) elif node.tag in [inkex.addNS('line', 'svg'), 'line']: @@ -923,13 +935,13 @@ class Eggbot_Hatch(inkex.Effect): self.addPathVertices(simplepath.formatPath(a), node, mat_new) # We now have a path we want to apply a (cross)hatch to # Apply appropriate functions - b_have_grid = self.makeHatchGrid(float(self.options.hatchAngle), float(self.options.hatchSpacing), True) + b_have_grid = self.makeHatchGrid(float(self.options.hatchAngle), float(self.hatch_spacing_px), True) if b_have_grid: if self.options.crossHatch: - self.makeHatchGrid(float(self.options.hatchAngle + 90.0), float(self.options.hatchSpacing), False) + self.makeHatchGrid(float(self.options.hatchAngle + 90.0), float(self.hatch_spacing_px), False) # Now loop over our hatch lines looking for intersections for h in self.grid: - interstices(self, (h[0], h[1]), (h[2], h[3]), self.paths, self.hatches, self.options.holdBackHatchFromEdges, self.options.holdBackSteps) + interstices(self, (h[0], h[1]), (h[2], h[3]), self.paths, self.hatches, self.options.inset_bool, self.inset_dist_px) elif node.tag in [inkex.addNS('polyline', 'svg'), 'polyline']: @@ -964,13 +976,13 @@ class Eggbot_Hatch(inkex.Effect): # We now have a path we want to apply a (cross)hatch to # Apply appropriate functions - b_have_grid = self.makeHatchGrid(float(self.options.hatchAngle), float(self.options.hatchSpacing), True) + b_have_grid = self.makeHatchGrid(float(self.options.hatchAngle), float(self.hatch_spacing_px), True) if b_have_grid: if self.options.crossHatch: - self.makeHatchGrid(float(self.options.hatchAngle + 90.0), float(self.options.hatchSpacing), False) + self.makeHatchGrid(float(self.options.hatchAngle + 90.0), float(self.hatch_spacing_px), False) # Now loop over our hatch lines looking for intersections for h in self.grid: - interstices(self, (h[0], h[1]), (h[2], h[3]), self.paths, self.hatches, self.options.holdBackHatchFromEdges, self.options.holdBackSteps) + interstices(self, (h[0], h[1]), (h[2], h[3]), self.paths, self.hatches, self.options.inset_bool, self.inset_dist_px) elif node.tag in [inkex.addNS('polygon', 'svg'), 'polygon']: # Convert @@ -991,13 +1003,13 @@ class Eggbot_Hatch(inkex.Effect): self.addPathVertices(d, node, mat_new) # We now have a path we want to apply a (cross)hatch to # Apply appropriate functions - b_have_grid = self.makeHatchGrid(float(self.options.hatchAngle), float(self.options.hatchSpacing), True) + b_have_grid = self.makeHatchGrid(float(self.options.hatchAngle), float(self.hatch_spacing_px), True) if b_have_grid: if self.options.crossHatch: - self.makeHatchGrid(float(self.options.hatchAngle + 90.0), float(self.options.hatchSpacing), False) + self.makeHatchGrid(float(self.options.hatchAngle + 90.0), float(self.hatch_spacing_px), False) # Now loop over our hatch lines looking for intersections for h in self.grid: - interstices(self, (h[0], h[1]), (h[2], h[3]), self.paths, self.hatches, self.options.holdBackHatchFromEdges, self.options.holdBackSteps) + interstices(self, (h[0], h[1]), (h[2], h[3]), self.paths, self.hatches, self.options.inset_bool, self.inset_dist_px) elif node.tag in [inkex.addNS('ellipse', 'svg'), 'ellipse', inkex.addNS('circle', 'svg'), 'circle']: @@ -1042,34 +1054,33 @@ class Eggbot_Hatch(inkex.Effect): self.addPathVertices(d, node, mat_new) # We now have a path we want to apply a (cross)hatch to # Apply appropriate functions - b_have_grid = self.makeHatchGrid(float(self.options.hatchAngle), float(self.options.hatchSpacing), True) + b_have_grid = self.makeHatchGrid(float(self.options.hatchAngle), float(self.hatch_spacing_px), True) if b_have_grid: if self.options.crossHatch: - self.makeHatchGrid(float(self.options.hatchAngle + 90.0), float(self.options.hatchSpacing), False) + self.makeHatchGrid(float(self.options.hatchAngle + 90.0), float(self.hatch_spacing_px), False) # Now loop over our hatch lines looking for intersections for h in self.grid: - interstices(self, (h[0], h[1]), (h[2], h[3]), self.paths, self.hatches, self.options.holdBackHatchFromEdges, self.options.holdBackSteps) + interstices(self, (h[0], h[1]), (h[2], h[3]), self.paths, self.hatches, self.options.inset_bool, self.inset_dist_px) elif node.tag in [inkex.addNS('pattern', 'svg'), 'pattern']: - pass + continue elif node.tag in [inkex.addNS('metadata', 'svg'), 'metadata']: - pass + continue elif node.tag in [inkex.addNS('defs', 'svg'), 'defs']: - pass + continue elif node.tag in [inkex.addNS('namedview', 'sodipodi'), 'namedview']: - pass + continue elif node.tag in [inkex.addNS('eggbot', 'svg'), 'eggbot']: - pass + continue elif node.tag in [inkex.addNS('WCB', 'svg'), 'WCB']: - pass + continue + elif node.tag in [inkex.addNS('image', 'svg'), 'image']: + continue elif node.tag in [inkex.addNS('text', 'svg'), 'text']: - inkex.errormsg('Warning: unable to draw text, please convert it to a path first.') - pass - elif not isinstance(node.tag, basestring): - pass + inkex.errormsg('Warning: unable to hatch text, please convert it to a path first.') + continue else: - inkex.errormsg('Warning: unable to hatch object <{0}>, please convert it to a path first.'.format(node.tag)) - pass + continue # produce no error on other SVG elements. def joinFillsWithNode(self, node, stroke_width, path): @@ -1202,8 +1213,19 @@ class Eggbot_Hatch(inkex.Effect): # Viewbox handling self.handleViewBox() - if self.options.hatchSpacing == 0: - self.options.hatchSpacing = 0.1 # Hardcode minimum value + # Default spacing values for hatches and inset; handle px units case: + self.hatch_spacing_px = self.options.hatchSpacing + self.inset_dist_px = self.options.inset_dist + + if self.options.units == 3: # Units in mm + self.hatch_spacing_px = (96.0 / 25.4) * self.options.hatchSpacing + self.inset_dist_px = (96.0 / 25.4) * self.options.inset_dist + if self.options.units == 4: # Units in inches + self.hatch_spacing_px = 96.0 * self.options.hatchSpacing + self.inset_dist_px = 96.0 * self.options.inset_dist + + if self.hatch_spacing_px < 0.1: + self.hatch_spacing_px = 0.1 # Hardcode minimum value ref_count = 0 pt_last_position_abs = [0, 0] @@ -1265,14 +1287,14 @@ class Eggbot_Hatch(inkex.Effect): stroke_width = 1.0 # The transform also applies to the hatch spacing we use when searching for end connections - transformed_hatch_spacing = stroke_width * self.options.hatchSpacing + transformed_hatch_spacing = stroke_width * self.hatch_spacing_px path = '' # regardless of whether or not we're reducing pen lifts pt_last_position_abs = [0, 0] pt_last_position_abs[0] = 0 pt_last_position_abs[1] = 0 f_distance_moved_with_pen_up = 0 - if not self.options.reducePenLifts: + if not self.options.connect_bool: for segment in self.hatches[key]: if len(segment) < 2: continue