summaryrefslogtreecommitdiffstats
path: root/share/extensions/path_mesh_p2m.py
diff options
context:
space:
mode:
Diffstat (limited to 'share/extensions/path_mesh_p2m.py')
-rwxr-xr-xshare/extensions/path_mesh_p2m.py89
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()