diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:24:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:24:48 +0000 |
commit | cca66b9ec4e494c1d919bff0f71a820d8afab1fa (patch) | |
tree | 146f39ded1c938019e1ed42d30923c2ac9e86789 /share/extensions/extrude.py | |
parent | Initial commit. (diff) | |
download | inkscape-cca66b9ec4e494c1d919bff0f71a820d8afab1fa.tar.xz inkscape-cca66b9ec4e494c1d919bff0f71a820d8afab1fa.zip |
Adding upstream version 1.2.2.upstream/1.2.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'share/extensions/extrude.py')
-rwxr-xr-x | share/extensions/extrude.py | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/share/extensions/extrude.py b/share/extensions/extrude.py new file mode 100755 index 0000000..34eeaf8 --- /dev/null +++ b/share/extensions/extrude.py @@ -0,0 +1,150 @@ +#!/usr/bin/env python +# coding=utf-8 +# +# Copyright (C) 2022 Jonathan Neuhauser, jonathan.neuhauser@outlook.com +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +"""Join paths with lines or polygons""" + + +import itertools +from typing import List, Union + +import inkex +from inkex.localization import inkex_gettext as _ +from inkex.paths import ZoneClose, zoneClose, Line, Move, move +from inkex.turtle import PathGroupBuilder, PathBuilder + + +class Extrude(inkex.EffectExtension): + """This effect draws lines between each nth node of each selected path. + It can be chosen whether these regions are filled and whether the fill uses rectangles + or copies of the path segments. + The lines will be inserted between the two elements. + """ + + def add_arguments(self, pars): + pars.add_argument("--tab") + pars.add_argument( + "-m", + "--mode", + default="lines", + choices=["lines", "polygons", "snug"], + help='Join paths with lines, polygons or copies of the segments ("snug")', + ) + pars.add_argument( + "-s", + "--subpaths", + default=True, + type=inkex.Boolean, + help="""If true, connecting lines will be inserted as subpaths of a single path. + If false, they will be inserted in newly created group. + Only applies to mode=lines""", + ) + + @staticmethod + def _handle_lines(manager, com1, com2): + if not ( + isinstance(com1.command, (ZoneClose, zoneClose)) + or isinstance(com2.command, (ZoneClose, zoneClose)) + ): + # For a closed subpath, the first line has already been drawn. + manager.Move_to(*com1.end_point) + manager.Line_to(*com2.end_point) + + @staticmethod + def _handle_polygons(manager, com1, com2): + if not ( + isinstance(com1.command, (Move, move)) + or isinstance(com2.command, (Move, move)) + ): + # We skip if one of either commands is a "Move" command + manager.Move_to(*com1.previous_end_point) + for point in [ + com1.end_point, + com2.end_point, + com2.previous_end_point, + com1.previous_end_point, + ]: + manager.Line_to(*point) + + @staticmethod + def _handle_snug(manager, com1, com2): + if not ( + isinstance(com1.command, (Move, move)) + or isinstance(com2.command, (Move, move)) + ): + # We skip if one of either commands is a "Move" command + manager.Move_to(*com1.previous_end_point) + com1r = com1.command + com2r = com2.reverse() + doflag = True + if isinstance(com1r, (ZoneClose, zoneClose)): + # ZoneClose can not be used directly, must be converted to line + com1r = Line(*com1.first_point) + if com1.previous_end_point.is_close(com1.end_point): + doflag = False + if doflag: + manager.add([com1r, Line(*com2.end_point), com2r, ZoneClose()]) + + def effect(self): + paths: List[inkex.PathElement] = [] + for node in self.svg.selection.rendering_order().filter(inkex.ShapeElement): + if isinstance(node, inkex.PathElement): + node.apply_transform() + paths.append(node) + if len(paths) < 2: + raise inkex.AbortExtension(_("Need at least 2 paths selected")) + lines = self.options.mode.lower() == "lines" + subpaths = self.options.subpaths and lines + + mode = ( + self._handle_lines + if lines + else ( + self._handle_polygons + if self.options.mode.lower() == "polygons" + else self._handle_snug + ) + ) + + if lines: + style = { + "fill": "none", + "stroke": "#000000", + "stroke-opacity": 1, + "stroke-width": "1px", + } + else: + style = { + "fill": "#000000", + "fill-opacity": 0.3, + "stroke": "#000000", + "stroke-opacity": 0.6, + "stroke-width": "1px", + "stroke-linejoin": "round", + } + + for pa1, pa2 in itertools.combinations(paths, 2): + manager = PathBuilder(style) if subpaths else PathGroupBuilder(style) + for com1, com2 in zip(pa1.path.proxy_iterator(), pa2.path.proxy_iterator()): + mode(manager, com1, com2) + manager.terminate() + manager.append_next(pa1) + + +if __name__ == "__main__": + Extrude().run() |