diff options
Diffstat (limited to 'share/extensions/path_mesh_p2m.py')
-rwxr-xr-x | share/extensions/path_mesh_p2m.py | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/share/extensions/path_mesh_p2m.py b/share/extensions/path_mesh_p2m.py new file mode 100755 index 0000000..d5a4877 --- /dev/null +++ b/share/extensions/path_mesh_p2m.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# +# Copyright (C) 2016 su_v, <suv-sf@users.sf.net> +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +Convert path to mesh gradient +""" + +import inkex +from inkex.paths import Line, Curve +from inkex.elements import MeshGradient + +class PathToMesh(inkex.EffectExtension): + """Convert path data to mesh geometry.""" + def add_arguments(self, pars): + pars.add_argument("--tab", help="The selected UI-tab") + + def add_mesh(self, meshgradient): + """Add meshgradient definition to current document.""" + self.svg.defs.append(meshgradient) + meshgradient.set_random_id('meshgradient') + return meshgradient.get_id() + + def effect(self): + """Main routine to convert path data to mesh geometry.""" + # loop through selection + for node in self.svg.selection.filter(inkex.PathElement).values(): + csp = None + meshgradient = None + mesh_id = None + # parse path data + csp = node.path.to_superpath() + # convert csp to meshgradient definition + if csp is not None: + # TODO: check length of path data / csp + meshgradient = self.to_mesh(node, csp) + # add meshgradient to document + if meshgradient is not None: + mesh_id = self.add_mesh(meshgradient) + # apply meshgradient to node + if mesh_id is not None: + node.style['fill'] = 'url(#{})'.format(mesh_id) + + def to_mesh(self, node, csp, subpath=0): + """Convert csp to meshgradient geometry.""" + # mesh data + corners, edges = self.to_meshdata(csp[subpath]) + # alternating stop colors + colors = [node.style.get('fill'), '#ffffff'] + # define meshgradient with first corner as initial point + meshgradient = MeshGradient.new_mesh(pos=corners[0], rows=1, cols=1) + # define stops (stop-color, path) for first meshpatch + meshgradient[0][0].stops(edges[0:4], colors) + return meshgradient + + @staticmethod + def to_meshdata(subpath): + """Convert csp subpath to corners, edge path data.""" + if len(subpath) >= 5: + corners = [] + edges = [] + for i, corner in enumerate(subpath[:4]): + corners.append(corner[1]) + edge = [list(subpath[i]), list(subpath[i+1])] + edge[0][0] = list(edge[0][1]) + edge[1][2] = list(edge[1][1]) + if inkex.CubicSuperPath.is_line(edge[0], edge[1]): + edges.append(Line(*edge[1][1])) + else: + edges.append(Curve(*(edge[0][2] + edge[1][0] + edge[1][1]))) + + return corners, edges + +if __name__ == '__main__': + PathToMesh().run() |