Aaron Spike committed Jul 27, 2005 1 2 ``````#!/usr/bin/env python ''' `````` 3 4 5 6 7 ``````This extension either adds nodes to a path so that a) no segment is longer than a maximum value or b) so that each segment is divided into a given number of equal segments `````` Aaron Spike committed Jun 19, 2007 8 ``````Copyright (C) 2005,2007 Aaron Spike, aaron@ekips.org `````` Aaron Spike committed Jul 27, 2005 9 10 11 12 13 14 15 16 17 18 19 20 21 `````` 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 `````` Nicolas Dufour committed Mar 16, 2016 22 ``````Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. `````` Aaron Spike committed Jul 27, 2005 23 ``````''' `````` 24 25 26 `````` import inkex import cubicsuperpath, simplestyle, copy, math, re, bezmisc `````` Aaron Spike committed Jul 27, 2005 27 28 `````` def numsegs(csp): `````` Aaron Spike committed May 08, 2006 29 `````` return sum([len(p)-1 for p in csp]) `````` Thomas Holder committed Mar 04, 2019 30 31 32 ``````def tpoint(_x1_y1, _x2_y2, t = 0.5): (x1, y1) = _x1_y1 (x2, y2) = _x2_y2 `````` Aaron Spike committed May 08, 2006 33 `````` return [x1+t*(x2-x1),y1+t*(y2-y1)] `````` Aaron Spike committed Jul 27, 2005 34 ``````def cspbezsplit(sp1, sp2, t = 0.5): `````` Aaron Spike committed May 08, 2006 35 36 37 38 39 40 41 `````` m1=tpoint(sp1[1],sp1[2],t) m2=tpoint(sp1[2],sp2[0],t) m3=tpoint(sp2[0],sp2[1],t) m4=tpoint(m1,m2,t) m5=tpoint(m2,m3,t) m=tpoint(m4,m5,t) return [[sp1[0][:],sp1[1][:],m1], [m4,m,m5], [m3,sp2[1][:],sp2[2][:]]] `````` Aaron Spike committed Jul 27, 2005 42 ``````def cspbezsplitatlength(sp1, sp2, l = 0.5, tolerance = 0.001): `````` Aaron Spike committed May 08, 2006 43 44 45 `````` bez = (sp1[1][:],sp1[2][:],sp2[0][:],sp2[1][:]) t = bezmisc.beziertatlength(bez, l, tolerance) return cspbezsplit(sp1, sp2, t) `````` Aaron Spike committed Jul 27, 2005 46 ``````def cspseglength(sp1,sp2, tolerance = 0.001): `````` Aaron Spike committed May 08, 2006 47 48 `````` bez = (sp1[1][:],sp1[2][:],sp2[0][:],sp2[1][:]) return bezmisc.bezierlength(bez, tolerance) `````` Aaron Spike committed Jul 27, 2005 49 ``````def csplength(csp): `````` Aaron Spike committed May 08, 2006 50 51 52 53 `````` total = 0 lengths = [] for sp in csp: lengths.append([]) `````` Thomas Holder committed Mar 04, 2019 54 `````` for i in range(1,len(sp)): `````` Aaron Spike committed May 08, 2006 55 56 57 58 `````` l = cspseglength(sp[i-1],sp[i]) lengths[-1].append(l) total += l return lengths, total `````` Aaron Spike committed Jul 27, 2005 59 ``````def numlengths(csplen): `````` Aaron Spike committed May 08, 2006 60 61 62 63 64 65 `````` retval = 0 for sp in csplen: for l in sp: if l > 0: retval += 1 return retval `````` Aaron Spike committed Jul 27, 2005 66 67 `````` class SplitIt(inkex.Effect): `````` Aaron Spike committed May 08, 2006 68 69 `````` def __init__(self): inkex.Effect.__init__(self) `````` 70 71 72 73 74 `````` self.OptionParser.add_option("--segments", action="store", type="int", dest="segments", default=2, help="Number of segments to divide the path into") self.OptionParser.add_option("--max", `````` Dmitry Kirsanov committed May 12, 2008 75 `````` action="store", type="float", `````` 76 77 78 79 80 81 82 `````` dest="max", default=2, help="Number of segments to divide the path into") self.OptionParser.add_option("--method", action="store", type="string", dest="method", default='', help="The kind of division to perform") `````` Aaron Spike committed May 08, 2006 83 `````` def effect(self): `````` 84 `````` `````` Thomas Holder committed Mar 04, 2019 85 `````` for id, node in self.selected.items(): `````` Aaron Spike committed Jun 19, 2007 86 87 `````` if node.tag == inkex.addNS('path','svg'): p = cubicsuperpath.parsePath(node.get('d')) `````` Aaron Spike committed May 08, 2006 88 89 90 91 `````` #lens, total = csplength(p) #avg = total/numlengths(lens) #inkex.debug("average segment length: %s" % avg) `````` Aaron Spike committed Jul 27, 2005 92 `````` `````` Aaron Spike committed May 08, 2006 93 94 95 96 97 98 `````` new = [] for sub in p: new.append([sub[0][:]]) i = 1 while i <= len(sub)-1: length = cspseglength(new[-1][-1], sub[i]) `````` 99 100 101 102 `````` if self.options.method == 'bynum': splits = self.options.segments else: `````` Aaron Spike committed May 08, 2006 103 `````` splits = math.ceil(length/self.options.max) `````` 104 `````` `````` Thomas Holder committed Mar 04, 2019 105 `````` for s in range(int(splits),1,-1): `````` 106 107 `````` new[-1][-1], next, sub[i] = cspbezsplitatlength(new[-1][-1], sub[i], 1.0/s) new[-1].append(next[:]) `````` Aaron Spike committed May 08, 2006 108 109 110 `````` new[-1].append(sub[i]) i+=1 `````` Aaron Spike committed Jun 19, 2007 111 `````` node.set('d',cubicsuperpath.formatPath(new)) `````` Aaron Spike committed Jul 27, 2005 112 `````` `````` Peter Moulder committed May 23, 2008 113 114 115 ``````if __name__ == '__main__': e = SplitIt() e.affect() `````` 116 117 `````` `````` Chris Morgan committed Nov 17, 2010 118 ``# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99``