better conversion of strokes to paths in vpypetools

This commit is contained in:
Mario Voigt 2021-06-05 16:12:38 +02:00
parent a2e9469b37
commit c50d034738

View File

@ -9,8 +9,8 @@ import os
from lxml import etree from lxml import etree
import inkex import inkex
from inkex import transforms, bezier from inkex import transforms, bezier, PathElement
from inkex.paths import CubicSuperPath from inkex.paths import CubicSuperPath, Path
from inkex.command import inkscape from inkex.command import inkscape
import vpype import vpype
@ -345,19 +345,6 @@ class vpypetools (inkex.EffectExtension):
#vpype.write_svg(output_fileIO, doc, page_size=(self.svg.unittouu(self.document.getroot().get('width')), self.svg.unittouu(self.document.getroot().get('height'))), center=False, source_string='', layer_label_format='%d', show_pen_up=self.options.output_trajectories, color_mode='layer') #vpype.write_svg(output_fileIO, doc, page_size=(self.svg.unittouu(self.document.getroot().get('width')), self.svg.unittouu(self.document.getroot().get('height'))), center=False, source_string='', layer_label_format='%d', show_pen_up=self.options.output_trajectories, color_mode='layer')
output_fileIO.close() output_fileIO.close()
# convert vpype polylines/lines/polygons to regular paths again. We need to use "--with-gui" to respond to "WARNING: ignoring verb FileSave - GUI required for this verb."
if self.options.strokes_to_paths is True:
cli_output = inkscape(output_file, "--with-gui", actions="EditSelectAllInAllLayers;EditUnlinkClone;ObjectToPath;FileSave;FileQuit") #we do not use StrokeToPath because it will convert svg:line to a svg:path, but as closed path with four points
if len(cli_output) > 0:
self.debug(_("Inkscape returned the following output when trying to run the vpype object to path back-conversion:"))
self.debug(cli_output)
# this does not work because line, polyline and polygon have no base class to execute replace_with
#if self.options.strokes_to_paths is True:
# for lineLayer in lineLayers:
# for element in lineLayer:
# element.replace_with(element.to_path_element())
# parse the SVG file # parse the SVG file
try: try:
stream = open(output_file, 'r') stream = open(output_file, 'r')
@ -414,11 +401,31 @@ class vpypetools (inkex.EffectExtension):
scaleY = self.svg.unittouu(self_viewBoxValues[3]) / self.svg.unittouu(import_viewBox[3]) scaleY = self.svg.unittouu(self_viewBoxValues[3]) / self.svg.unittouu(import_viewBox[3])
for element in import_doc.getroot().iter("{http://www.w3.org/2000/svg}g"): for element in import_doc.getroot().iter("{http://www.w3.org/2000/svg}g"):
self.document.getroot().append(element) e = self.document.getroot().append(element)
if self.options.input_handling == "layers": if self.options.input_handling == "layers":
if self_viewBox is not None: if self_viewBox is not None:
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 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 (strokes to paths)
if self.options.strokes_to_paths is True:
for line in element.iter("{http://www.w3.org/2000/svg}line"):
newLine = PathElement()
newLine.path = Path("M {},{}L {},{}".format(line.attrib['x1'], line.attrib['y1'], line.attrib['x2'], line.attrib['y2']))
element.append(newLine)
line.delete()
for polyline in element.iter("{http://www.w3.org/2000/svg}polyline"):
newPolyLine = PathElement()
newPolyLine.path = Path('M' + polyline.attrib['points'])
element.append(newPolyLine)
polyline.delete()
for polygon in element.iter("{http://www.w3.org/2000/svg}polygon"):
newPolygon = PathElement()
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
element.append(newPolygon)
polygon.delete()
# Delete the temporary file again because we do not need it anymore # Delete the temporary file again because we do not need it anymore
if os.path.exists(output_file): if os.path.exists(output_file):
os.remove(output_file) os.remove(output_file)