From 319578b3b612a6eb612f4ded2338191a9ac6ca6a Mon Sep 17 00:00:00 2001 From: Mario Voigt Date: Sun, 17 Oct 2021 21:04:57 +0200 Subject: [PATCH] Added Paths to lowlevel strokes extension --- .../braille_l18n.inx} | 4 +- .../braille_l18n.py} | 0 .../{braille-l18n => braille_l18n}/meta.json | 4 +- .../paths_to_lowlevel_strokes/meta.json | 19 +++ .../paths_to_lowlevel_strokes.inx | 19 +++ .../paths_to_lowlevel_strokes.py | 118 ++++++++++++++++++ 6 files changed, 160 insertions(+), 4 deletions(-) rename extensions/fablabchemnitz/{braille-l18n/braille-l18n.inx => braille_l18n/braille_l18n.inx} (86%) rename extensions/fablabchemnitz/{braille-l18n/braille-l18n.py => braille_l18n/braille_l18n.py} (100%) rename extensions/fablabchemnitz/{braille-l18n => braille_l18n}/meta.json (91%) create mode 100644 extensions/fablabchemnitz/paths_to_lowlevel_strokes/meta.json create mode 100644 extensions/fablabchemnitz/paths_to_lowlevel_strokes/paths_to_lowlevel_strokes.inx create mode 100644 extensions/fablabchemnitz/paths_to_lowlevel_strokes/paths_to_lowlevel_strokes.py diff --git a/extensions/fablabchemnitz/braille-l18n/braille-l18n.inx b/extensions/fablabchemnitz/braille_l18n/braille_l18n.inx similarity index 86% rename from extensions/fablabchemnitz/braille-l18n/braille-l18n.inx rename to extensions/fablabchemnitz/braille_l18n/braille_l18n.inx index 92ad17c9..e36574e0 100644 --- a/extensions/fablabchemnitz/braille-l18n/braille-l18n.inx +++ b/extensions/fablabchemnitz/braille_l18n/braille_l18n.inx @@ -1,7 +1,7 @@ Convert To Localized Braille - fablabchemnitz.de.braille-l18n + fablabchemnitz.de.braille_l18n @@ -20,6 +20,6 @@ \ No newline at end of file diff --git a/extensions/fablabchemnitz/braille-l18n/braille-l18n.py b/extensions/fablabchemnitz/braille_l18n/braille_l18n.py similarity index 100% rename from extensions/fablabchemnitz/braille-l18n/braille-l18n.py rename to extensions/fablabchemnitz/braille_l18n/braille_l18n.py diff --git a/extensions/fablabchemnitz/braille-l18n/meta.json b/extensions/fablabchemnitz/braille_l18n/meta.json similarity index 91% rename from extensions/fablabchemnitz/braille-l18n/meta.json rename to extensions/fablabchemnitz/braille_l18n/meta.json index 5a66fb74..57eb291d 100644 --- a/extensions/fablabchemnitz/braille-l18n/meta.json +++ b/extensions/fablabchemnitz/braille_l18n/meta.json @@ -1,8 +1,8 @@ [ { "name": "Convert To Localized Braille", - "id": "fablabchemnitz.de.braille-l18n", - "path": "braille-l18n", + "id": "fablabchemnitz.de.braille_l18n", + "path": "braille_l18n", "original_name": "Convert to localized Braille", "original_id": "org.inkscape.text.braille-l18n", "license": "BSD-3-Clause License", diff --git a/extensions/fablabchemnitz/paths_to_lowlevel_strokes/meta.json b/extensions/fablabchemnitz/paths_to_lowlevel_strokes/meta.json new file mode 100644 index 00000000..28ca7913 --- /dev/null +++ b/extensions/fablabchemnitz/paths_to_lowlevel_strokes/meta.json @@ -0,0 +1,19 @@ +[ + { + "name": "Paths To Lowlevel Strokes", + "id": "fablabchemnitz.de.paths_to_lowlevel_strokes", + "path": "paths_to_lowlevel_strokes", + "original_name": "Paths To Lowlevel Strokes", + "original_id": "fablabchemnitz.de.paths_to_lowlevel_strokes", + "license": "GNU GPL v3", + "license_url": "https://gitea.fablabchemnitz.de/FabLab_Chemnitz/mightyscape-1.X/src/branch/master/LICENSE", + "comment": "Created by Mario Voigt", + "source_url": "https://gitea.fablabchemnitz.de/FabLab_Chemnitz/mightyscape-1.X/src/branch/master/extensions/fablabchemnitz/paths_to_strokes", + "fork_url": null, + "documentation_url": "https://stadtfabrikanten.org/display/IFM/Paths+To+Lowlevel+Strokes", + "inkscape_gallery_url": null, + "main_authors": [ + "github.com/vmario89" + ] + } +] \ No newline at end of file diff --git a/extensions/fablabchemnitz/paths_to_lowlevel_strokes/paths_to_lowlevel_strokes.inx b/extensions/fablabchemnitz/paths_to_lowlevel_strokes/paths_to_lowlevel_strokes.inx new file mode 100644 index 00000000..23f63431 --- /dev/null +++ b/extensions/fablabchemnitz/paths_to_lowlevel_strokes/paths_to_lowlevel_strokes.inx @@ -0,0 +1,19 @@ + + + Paths To Lowlevel Strokes + fablabchemnitz.de.paths_to_lowlevel_strokes + true + 0.100 + 3 + + path + + + + + + + + \ No newline at end of file diff --git a/extensions/fablabchemnitz/paths_to_lowlevel_strokes/paths_to_lowlevel_strokes.py b/extensions/fablabchemnitz/paths_to_lowlevel_strokes/paths_to_lowlevel_strokes.py new file mode 100644 index 00000000..395e794a --- /dev/null +++ b/extensions/fablabchemnitz/paths_to_lowlevel_strokes/paths_to_lowlevel_strokes.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 + + +from lxml import etree +import inkex +from inkex import bezier, PathElement +from inkex.paths import CubicSuperPath, Path +import copy + +class PathsToStrokes(inkex.EffectExtension): + + def add_arguments(self, pars): + 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) + + def effect(self): + + def flatten(node): + path = node.path.transform(node.composed_transform()).to_superpath() + bezier.cspsubdiv(path, self.options.flatness) + newpath = [] + for subpath in path: + first = True + for csp in subpath: + cmd = 'L' + if first: + cmd = 'M' + first = False + newpath.append([cmd, [csp[1][0], csp[1][1]]]) + node.path = newpath + + def break_contours(element, breakelements = None): + if breakelements == None: + breakelements = [] + if element.tag == inkex.addNS('path','svg'): + if self.options.flattenbezier is True: + flatten(element) + parent = element.getparent() + idx = parent.index(element) + idSuffix = 0 + raw = element.path.to_arrays() + subPaths = [] + prev = 0 + for i in range(len(raw)): # Breaks compound paths into simple paths + if raw[i][0] == 'M' and i != 0: + subPath = raw[prev:i] + subPaths.append(Path(subPath)) + prev = i + subPaths.append(Path(raw[prev:])) #finally add the last path + for subPath in subPaths: + replacedelement = copy.copy(element) + oldId = replacedelement.get('id') + csp = CubicSuperPath(subPath) + if len(subPath) > 1 and csp[0][0] != csp[0][1]: #avoids pointy paths like M "31.4794 57.6024 Z" + replacedelement.path = subPath + if len(subPaths) == 1: + replacedelement.set('id', oldId) + else: + replacedelement.set('id', oldId + str(idSuffix)) + idSuffix += 1 + parent.insert(idx, replacedelement) + breakelements.append(replacedelement) + element.delete() + for child in element.getchildren(): + break_contours(child, breakelements) + return breakelements + + if len(self.svg.selected) == 0: + elementsToWork = break_contours(self.document.getroot()) + else: + elementsToWork = None + for element in self.svg.selected.values(): + elementsToWork = break_contours(element, elementsToWork) + + for element in elementsToWork: + oldId = element.get('id') + oldStyle = element.style + path = element.path.to_absolute().to_arrays() #to_arrays() is deprecated. How to make more modern? + pathIsClosed = False + if path[-1][0] == 'Z' or \ + (path[-1][0] == 'L' and path[0][1] == path[-1][1]) or \ + (path[-1][0] == 'C' and path[0][1] == [path[-1][1][-2], path[-1][1][-1]]) \ + : #if first is last point the path is also closed. The "Z" command is not required + pathIsClosed = True + parent = element.getparent() + idx = parent.index(element) + element.delete() + + if len(path) == 2 and pathIsClosed is False: + line = inkex.Line(id=oldId) + line.set('x1', '{:0.{dec}f}'.format(path[0][1][0], dec=self.options.decimals)) + line.set('y1', '{:0.{dec}f}'.format(path[0][1][1], dec=self.options.decimals)) + line.set('x2', '{:0.{dec}f}'.format(path[1][1][0], dec=self.options.decimals)) + line.set('y2', '{:0.{dec}f}'.format(path[1][1][1], dec=self.options.decimals)) + line.style = oldStyle + parent.insert(idx, line) + + if len(path) > 2 and pathIsClosed is False: + polyline = inkex.Polyline(id=oldId) + points = "" + for i in range(0, len(path)): + points += '{:0.{dec}f},{:0.{dec}f} '.format(path[i][1][0], path[i][1][1], dec=self.options.decimals) + polyline.set('points', points) + polyline.style = oldStyle + parent.insert(idx, polyline) + + if len(path) > 2 and pathIsClosed is True: + polygon = inkex.Polygon(id=oldId) + points = "" + for i in range(0, len(path) - 1): + points += '{:0.{dec}f},{:0.{dec}f} '.format(path[i][1][0], path[i][1][1], dec=self.options.decimals) + polygon.set('points', points) + polygon.style = oldStyle + parent.insert(idx, polygon) + +if __name__ == '__main__': + PathsToStrokes().run() \ No newline at end of file