added purge pointy paths extension
This commit is contained in:
parent
1264a864bc
commit
8fcc0cbf64
@ -36,8 +36,8 @@ class DrawBBoxes(inkex.EffectExtension):
|
||||
def effect(self):
|
||||
if len(self.svg.selected) > 0:
|
||||
if self.options.split is False:
|
||||
for id, item in self.svg.selected.items():
|
||||
self.drawBBox(item.bounding_box())
|
||||
for element in self.svg.selected.values():
|
||||
self.drawBBox(element.bounding_box())
|
||||
else:
|
||||
#self.drawBBox(self.svg.get_selected_bbox()) #works for InkScape (1:1.0+devel+202008292235+eff2292935) @ Linux and for Windows (but with deprecation)
|
||||
self.drawBBox(self.svg.selection.bounding_box()) #works for InkScape 1.1dev (9b1fc87, 2020-08-27)) @ Windows
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# coding=utf-8
|
||||
#
|
||||
# Copyright (C) 2005,2007 Aaron Spike, aaron@ekips.org
|
||||
@ -139,7 +139,7 @@ class LinksCreator(inkex.EffectExtension):
|
||||
if self.options.switch_pattern is True:
|
||||
dashes = dashes[::-1] #reverse the array
|
||||
|
||||
#validate dashes. May not be negative. Otherwise Inkscape will freeze forever. Reason: rendering issue
|
||||
#validate dashes. May not be negative (dash or gap cannot be longer than the path itself). Otherwise Inkscape will freeze forever. Reason: rendering issue
|
||||
if any(dash <= 0.0 for dash in dashes) == True:
|
||||
if self.options.show_info is True: self.msg("node " + node.get('id') + ": Error! Dash array may not contain negative numbers: " + ' '.join(format(dash, "1.3f") for dash in dashes) + ". Path skipped. Maybe it's too short. Adjust your link count, multiplicator and length accordingly, or set to unit '%'")
|
||||
return False if self.options.skip_errors is True else exit(1)
|
||||
@ -267,11 +267,10 @@ class LinksCreator(inkex.EffectExtension):
|
||||
dash = dash - length
|
||||
length = bezier.cspseglength(new[-1][-1], sub[i])
|
||||
while dash < length:
|
||||
new[-1][-1], nxt, sub[i] = \
|
||||
bezier.cspbezsplitatlength(new[-1][-1], sub[i], dash/length)
|
||||
if idash % 2: # create a gap
|
||||
new[-1][-1], nxt, sub[i] = bezier.cspbezsplitatlength(new[-1][-1], sub[i], dash/length)
|
||||
if idash % 2: # create a gap
|
||||
new.append([nxt[:]])
|
||||
else: # splice the curve
|
||||
else: # splice the curve
|
||||
new[-1].append(nxt[:])
|
||||
length = length - dash
|
||||
idash = (idash + 1) % len(dashes)
|
||||
@ -283,22 +282,44 @@ class LinksCreator(inkex.EffectExtension):
|
||||
i += 1
|
||||
style.pop('stroke-dasharray')
|
||||
node.pop('sodipodi:type')
|
||||
csp = CubicSuperPath(new)
|
||||
node.path = CubicSuperPath(new)
|
||||
node.style = style
|
||||
|
||||
# break apart the combined path to have multiple elements
|
||||
if self.options.breakapart is True:
|
||||
breakOutputNodes = self.breakContours(node)
|
||||
breakOutputNodes = None
|
||||
breakOutputNodes = self.breakContours(node, breakOutputNodes)
|
||||
breakApartGroup = nodeParent.add(inkex.Group())
|
||||
for breakOutputNode in breakOutputNodes:
|
||||
breakApartGroup.append(breakOutputNode)
|
||||
#self.msg(replacedNode.get('id'))
|
||||
#self.svg.selection.set(replacedNode.get('id')) #update selection to split paths segments (does not work, so commented out)
|
||||
|
||||
#cleanup useless points
|
||||
p = breakOutputNode.path
|
||||
commandsCoords = p.to_arrays()
|
||||
# "m 45.250809,91.692739" - this path contains onyl one command - a single point
|
||||
if len(commandsCoords) == 1:
|
||||
breakOutputNode.delete()
|
||||
# "m 45.250809,91.692739 z" - this path contains two commands, but only one coordinate.
|
||||
# It's a single point, the path is closed by a Z command
|
||||
elif len(commandsCoords) == 2 and commandsCoords[0][1] == commandsCoords[1][1]:
|
||||
breakOutputNode.delete()
|
||||
# "m 45.250809,91.692739 l 45.250809,91.692739" - this path contains two commands,
|
||||
# but the first and second coordinate are the same. It will render als point
|
||||
elif len(commandsCoords) == 2 and commandsCoords[-1][0] == 'Z':
|
||||
breakOutputNode.delete()
|
||||
# "m 45.250809,91.692739 l 45.250809,91.692739 z" - this path contains three commands,
|
||||
# but the first and second coordinate are the same. It will render als point, the path is closed by a Z command
|
||||
elif len(commandsCoords) == 3 and commandsCoords[0][1] == commandsCoords[1][1] and commandsCoords[2][1] == 'Z':
|
||||
breakOutputNode.delete()
|
||||
|
||||
if len(self.svg.selected) > 0:
|
||||
for node in self.svg.selection.values():
|
||||
#at first we need to break down combined nodes to single path, otherwise dasharray cannot properly be applied
|
||||
breakInputNodes = self.breakContours(node)
|
||||
breakInputNodes = None
|
||||
breakInputNodes = self.breakContours(node, breakInputNodes)
|
||||
for breakInputNode in breakInputNodes:
|
||||
createLinks(breakInputNode)
|
||||
else:
|
||||
|
16
extensions/fablabchemnitz/purge_pointy_paths.inx
Normal file
16
extensions/fablabchemnitz/purge_pointy_paths.inx
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Purge Pointy Paths</name>
|
||||
<id>fablabchemnitz.de.purge_pointy_paths</id>
|
||||
<effect>
|
||||
<object-type>path</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="FabLab Chemnitz">
|
||||
<submenu name="Nesting/Cut Optimization"/>
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">purge_pointy_paths.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
49
extensions/fablabchemnitz/purge_pointy_paths.py
Normal file
49
extensions/fablabchemnitz/purge_pointy_paths.py
Normal file
@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
This filter deletes paths which render as point only
|
||||
|
||||
More usesless and/or redundant filters for removing duplicate nodes and segments are provided by the following extension:
|
||||
- https://stadtfabrikanten.org/display/IFM/Purge+Duplicate+Path+Segments
|
||||
- https://stadtfabrikanten.org/display/IFM/Purge+Duplicate+Path+Nodes
|
||||
|
||||
Extension for InkScape 1.X
|
||||
Author: Mario Voigt / FabLab Chemnitz
|
||||
Mail: mario.voigt@stadtfabrikanten.org
|
||||
Date: 21.04.2021
|
||||
Last patch: 21.04.2021
|
||||
License: GNU GPL v3
|
||||
"""
|
||||
|
||||
import inkex
|
||||
from lxml import etree
|
||||
|
||||
class PurgeInvalidPaths(inkex.EffectExtension):
|
||||
|
||||
def effect(self):
|
||||
if len(self.svg.selected) > 0:
|
||||
for element in self.svg.selected.values():
|
||||
if isinstance(element, inkex.PathElement):
|
||||
p = element.path
|
||||
commandsCoords = p.to_arrays()
|
||||
# "m 45.250809,91.692739" - this path contains onyl one command - a single point
|
||||
if len(commandsCoords) == 1:
|
||||
element.delete()
|
||||
# "m 45.250809,91.692739 z" - this path contains two commands, but only one coordinate.
|
||||
# It's a single point, the path is closed by a Z command
|
||||
elif len(commandsCoords) == 2 and commandsCoords[0][1] == commandsCoords[1][1]:
|
||||
element.delete()
|
||||
# "m 45.250809,91.692739 l 45.250809,91.692739" - this path contains two commands,
|
||||
# but the first and second coordinate are the same. It will render als point
|
||||
elif len(commandsCoords) == 2 and commandsCoords[-1][0] == 'Z':
|
||||
element.delete()
|
||||
# "m 45.250809,91.692739 l 45.250809,91.692739 z" - this path contains three commands,
|
||||
# but the first and second coordinate are the same. It will render als point, the path is closed by a Z command
|
||||
elif len(commandsCoords) == 3 and commandsCoords[0][1] == commandsCoords[1][1] and commandsCoords[2][1] == 'Z':
|
||||
element.delete()
|
||||
else:
|
||||
inkex.errormsg('Please select some objects first.')
|
||||
return
|
||||
|
||||
if __name__ == '__main__':
|
||||
PurgeInvalidPaths().run()
|
@ -59,9 +59,9 @@ class RemoveRedundant(inkex.EffectExtension):
|
||||
seenSegments = set()
|
||||
coordsCache = FixedRadiusSearch()
|
||||
|
||||
for id, node in self.svg.selected.items():
|
||||
if node.tag == inkex.addNS('path','svg'):
|
||||
d = node.get('d')
|
||||
for element in self.svg.selected.values():
|
||||
if element.tag == inkex.addNS('path','svg'):
|
||||
d = element.get('d')
|
||||
path = paths.CubicSuperPath(d).to_path().to_arrays()
|
||||
newPath = []
|
||||
start = prev = None
|
||||
@ -117,7 +117,7 @@ class RemoveRedundant(inkex.EffectExtension):
|
||||
newPath.append([command, coords])
|
||||
while len(newPath) and newPath[-1][0] == 'M':
|
||||
newPath = newPath[:-1]
|
||||
node.set('d',str(paths.Path(newPath)))
|
||||
element.set('d',str(paths.Path(newPath)))
|
||||
|
||||
if __name__ == '__main__':
|
||||
RemoveRedundant().run()
|
Reference in New Issue
Block a user