logger.setLevel(level=logging.ERROR)#we set this to error before importing vpype to ignore the nasty output "WARNING:root:!!! `vpype.Length` is deprecated, use `vpype.LengthType` instead."
importsys
importos
fromlxmlimportetree
importinkex
frominkeximporttransforms,bezier,PathElement
frominkex.pathsimportCubicSuperPath,Path
frominkex.commandimportinkscape
importvpype
importvpype_viewer
fromvpype_viewerimportViewMode
fromvpype_cliimportexecute
logger=logging.getLogger()
logger.setLevel(level=logging.WARNING)#after importing vpype we enabled logging again
importwarnings# we import this to suppress moderngl warnings from vpype_viewer
pars.add_argument("--linemerge_tolerance",type=float,default=0.500,help="Maximum distance between two line endings that should be merged (default 0.500 mm)")
pars.add_argument("--linemerge_no_flip",type=inkex.Boolean,default=False,help="Disable reversing stroke direction for merging")
pars.add_argument("--reloop_tolerance",type=float,default=0.500,help="Controls how close the path beginning and end must be to consider it closed (default 0.500 mm)")
pars.add_argument("--plugin_occult_tolerance",type=float,default=0.01,help="Max distance between start and end point to consider a path closed (default 0.01 mm)")
pars.add_argument("--plugin_occult_keepseparatelayer",type=inkex.Boolean,default=False,help="Put occulted lines to separate layer")
pars.add_argument("--plugin_deduplicate_tolerance",type=float,default=0.01,help="Max distance between points to consider them equal (default 0.01 mm)")
pars.add_argument("--plugin_deduplicate_keepseparatelayer",type=inkex.Boolean,default=False,help="Put duplicate lines to separate layer")
pars.add_argument("--flattenbezier",type=inkex.Boolean,default=False,help="Flatten bezier curves to polylines")
pars.add_argument("--flatness",type=float,default=0.1,help="Minimum flatness = 0.1. The smaller the value the more fine segments you will get (quantization).")
pars.add_argument("--decimals",type=int,default=3,help="Accuracy for imported lines' coordinates into vpype. Does not work for 'Multilayer/document'")
pars.add_argument("--simplify",type=inkex.Boolean,default=False,help="Reduces significantly the number of segments used to approximate the curve while still guaranteeing an accurate conversion, but may increase the execution time. Does not work for 'Singlelayer/paths'")
pars.add_argument("--parallel",type=inkex.Boolean,default=False,help="Enables multiprocessing for the SVG conversion. This is recommended ONLY when using 'Simplify geometry' on large SVG files with many curved elements. Does not work for 'Singlelayer/paths'")
pars.add_argument("--output_show",type=inkex.Boolean,default=False,help="This will open a separate window showing the finished SVG data. If enabled, output is not applied to InkScape canvas (only for preview)!")
pars.add_argument("--output_show_points",type=inkex.Boolean,default=False,help="Enable point display in viewer")
pars.add_argument("--output_trajectories",type=inkex.Boolean,default=False,help="Add paths for the travel trajectories")
pars.add_argument("--keep_objects",type=inkex.Boolean,default=False,help="If false, selected paths will be removed")
pars.add_argument("--strokes_to_paths",type=inkex.Boolean,default=True,help="Recommended option. Performs 'Path' > 'Stroke to Path' (CTRL + ALT + C) to convert vpype converted lines back to regular path objects")
pars.add_argument("--use_style_of_first_element",type=inkex.Boolean,default=True,help="If enabled the first element in selection is scanned and we apply it's style to all imported vpype lines (but not for trajectories). Does not work for 'Multilayer/document'")
pars.add_argument("--lines_stroke_width",type=float,default=1.0,help="Stroke width of tooling lines (px). Gets overwritten if 'Use style of first selected element' is enabled")
pars.add_argument("--trajectories_stroke_width",type=float,default=1.0,help="Stroke width of trajectory lines (px). Gets overwritten if 'Use style of first selected element' is enabled")
defeffect(self):
lc=vpype.LineCollection()# create a new array of LineStrings consisting of Points. We convert selected paths to polylines and grab their points
elementsToWork=[]# we make an array of all collected nodes to get the boundingbox of that array. We need it to place the vpype converted stuff to the correct XY coordinates
iflen(subPath)>2and(subPath[-1][0]=='Z'orsubPath[0][1]==subPath[-1][1]):#check if path has more than 2 points and is closed by Z or first pont == last point
points.append(Point(round(subPath[0][1][0],self.options.decimals),round(subPath[0][1][1],self.options.decimals)))#if closed, we add the first point again
# getting the bounding box of the current selection. We use to calculate the offset XY from top-left corner of the canvas. This helps us placing back the elements
#input_bbox = inkex.elements._selected.ElementList.bounding_box(self.svg.selected) # get BoundingBox for selection
input_bbox=self.svg.selection.bounding_box()# get BoundingBox for selection
iflen(lc)==0:
self.msg('Selection appears to be empty or does not contain any valid svg:path nodes. Try to cast your objects to paths using CTRL + SHIFT + C or strokes to paths using CTRL + ALT+ C')
return
# find the first object in selection which has a style attribute (skips groups and other things which have no style)
firstElementStyle=None
forelementinelementsToWork:
ifelement.attrib.has_key('style'):
firstElementStyle=element.get('style')
doc=vpype.Document(page_size=(input_bbox.width+input_bbox.left,input_bbox.height+input_bbox.top))#create new vpype document
doc.add(lc,layer_id=None)# we add the lineCollection (converted selection) to the vpype document
self.msg('No lines left after vpype conversion. Conversion result is empty. Cannot continue. Check your document about containing any svg:path elements. You will need to convert objects and strokes to paths first! Vpype command chain was:')
self.msg(command)
return
# show the vpype document visually
ifself.options.output_show:
warnings.filterwarnings("ignore")# workaround to suppress annoying DeprecationWarning
element.set('transform','scale('+str(scaleX)+','+str(scaleY)+')')#imported groups need to be transformed. Or they have wrong size. Reason: different viewBox sizes/units in namedview definitions
# convert vpype polylines/lines/polygons to regular paths again (objects to paths)
#newPolygon.path = Path('M' + " ".join(polygon.attrib['points'].split(' ')[:-1]) + ' Z') #remove the last point of the points string by splitting at whitespace, converting to array and removing the last item. then converting back to string