Added Paths to lowlevel strokes extension
This commit is contained in:
parent
f388ca774f
commit
319578b3b6
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Convert To Localized Braille</name>
|
||||
<id>fablabchemnitz.de.braille-l18n</id>
|
||||
<id>fablabchemnitz.de.braille_l18n</id>
|
||||
<param name="locale" gui-text="Alphabet:" type="optiongroup" appearance="combo">
|
||||
<option value="en">English (ASCII)</option>
|
||||
<option value="es">Spanish</option>
|
||||
@ -20,6 +20,6 @@
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">braille-l18n.py</command>
|
||||
<command location="inx" interpreter="python">braille_l18n.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
@ -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",
|
@ -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"
|
||||
]
|
||||
}
|
||||
]
|
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Paths To Lowlevel Strokes</name>
|
||||
<id>fablabchemnitz.de.paths_to_lowlevel_strokes</id>
|
||||
<param name="flattenbezier" type="bool" gui-text="Quantization (flatten bezier curves to polylines)">true</param>
|
||||
<param name="flatness" type="float" min="0.001" max="99999.000" precision="3" gui-text="Flatness (tolerance)" gui-description="Minimum flatness = 0.001. The smaller the value the more fine segments you will get.">0.100</param>
|
||||
<param name="decimals" type="int" min="0" max="16" gui-text="Decimals" gui-description="Accuracy">3</param>
|
||||
<effect needs-live-preview="true">
|
||||
<object-type>path</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="FabLab Chemnitz">
|
||||
<submenu name="Modify existing Path(s)"/>
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">paths_to_lowlevel_strokes.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
@ -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()
|
Reference in New Issue
Block a user