Code

implemented proper error checking
[inkscape.git] / share / extensions / motion.py
1 #!/usr/bin/env python 
2 '''
3 Copyright (C) 2005 Aaron Spike, aaron@ekips.org
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 '''
19 import math, inkex, simplestyle, simplepath, bezmisc
21 class Motion(inkex.Effect):
22     def __init__(self):
23         inkex.Effect.__init__(self)
24         self.OptionParser.add_option("-a", "--angle",
25                         action="store", type="float", 
26                         dest="angle", default=45.0,
27                         help="direction of the motion vector")
28         self.OptionParser.add_option("-m", "--magnitude",
29                         action="store", type="float", 
30                         dest="magnitude", default=100.0,
31                         help="magnitude of the motion vector")    
33     def makeface(self,last,(cmd, params)):
34         a = []
35         a.append(['M',last[:]])
36         a.append([cmd, params[:]])
38         #translate path segment along vector
39         np = params[:]
40         defs = simplepath.pathdefs[cmd]
41         for i in range(defs[1]):
42             if defs[3][i] == 'x':
43                 np[i] += self.vx
44             elif defs[3][i] == 'y':
45                 np[i] += self.vy
47         a.append(['L',[np[-2],np[-1]]])
48         
49         #reverse direction of path segment
50         np[-2:] = last[0]+self.vx,last[1]+self.vy
51         if cmd == 'C':
52             c1 = np[:2], np[2:4] = np[2:4], np[:2]
53         a.append([cmd,np[:]])
54             
55         a.append(['Z',[]])
56         face = inkex.etree.SubElement(self.facegroup,inkex.addNS('path','svg'),{'d':simplepath.formatPath(a)})
57         
58     def effect(self):
59         self.vx = math.cos(math.radians(self.options.angle))*self.options.magnitude
60         self.vy = math.sin(math.radians(self.options.angle))*self.options.magnitude
61         for id, node in self.selected.iteritems():
62             if node.tag == inkex.addNS('path','svg'):
63                 group = inkex.etree.SubElement(node.getparent(),inkex.addNS('g','svg'))
64                 self.facegroup = inkex.etree.SubElement(group, inkex.addNS('g','svg'))
65                 group.append(node)
66                 
67                 t = node.get('transform')
68                 if t:
69                     group.set('transform', t)
70                     node.set('transform','')
71                     
72                 s = node.get('style')
73                 self.facegroup.set('style', s)
75                 p = simplepath.parsePath(node.get('d'))
76                 for cmd,params in p:
77                     tees = []
78                     if cmd == 'C':
79                         bez = (last,params[:2],params[2:4],params[-2:])
80                         tees = [t for t in bezmisc.beziertatslope(bez,(self.vy,self.vx)) if 0<t<1]
81                         tees.sort()
83                     segments = []
84                     if len(tees) == 0 and cmd in ['L','C']:
85                             segments.append([cmd,params[:]])
86                     elif len(tees) == 1:
87                             one,two = bezmisc.beziersplitatt(bez,tees[0])
88                             segments.append([cmd,list(one[1]+one[2]+one[3])])
89                             segments.append([cmd,list(two[1]+two[2]+two[3])])
90                     elif len(tees) == 2:
91                             one,two = bezmisc.beziersplitatt(bez,tees[0])
92                             two,three = bezmisc.beziersplitatt(two,tees[1])
93                             segments.append([cmd,list(one[1]+one[2]+one[3])])
94                             segments.append([cmd,list(two[1]+two[2]+two[3])])
95                             segments.append([cmd,list(three[1]+three[2]+three[3])])
97                     for seg in segments:
98                         self.makeface(last,seg)
99                         last = seg[1][-2:]
100                     
101                     if cmd == 'M':
102                         subPathStart = params[-2:]
103                     if cmd == 'Z':
104                         last = subPathStart
105                     else:
106                         last = params[-2:]
108 if __name__ == '__main__':
109     e = Motion()
110     e.affect()
113 # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99