scripted/motionTraceCmd.py

scripted/motionTraceCmd.py
1 #-
2 # ==========================================================================
3 # Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors. All
4 # rights reserved.
5 #
6 # The coded instructions, statements, computer programs, and/or related
7 # material (collectively the "Data") in these files contain unpublished
8 # information proprietary to Autodesk, Inc. ("Autodesk") and/or its
9 # licensors, which is protected by U.S. and Canadian federal copyright
10 # law and by international treaties.
11 #
12 # The Data is provided for use exclusively by You. You have the right
13 # to use, modify, and incorporate this Data into other products for
14 # purposes authorized by the Autodesk software license agreement,
15 # without fee.
16 #
17 # The copyright notices in the Software and this entire statement,
18 # including the above license grant, this restriction and the
19 # following disclaimer, must be included in all copies of the
20 # Software, in whole or in part, and all derivative works of
21 # the Software, unless such copies or derivative works are solely
22 # in the form of machine-executable object code generated by a
23 # source language processor.
24 #
25 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
26 # AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED
27 # WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF
28 # NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR
29 # PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR
30 # TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS
31 # BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL,
32 # DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK
33 # AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY
34 # OR PROBABILITY OF SUCH DAMAGES.
35 #
36 # ==========================================================================
37 #+
38 
39 #
40 # Creation Date: 27 September 2006
41 #
42 # Description:
43 #
44 # Traces the position of an animated object
45 # and create a curve showing the object's path.
46 #
47 # Usage:
48 #
49 # Animate an object.
50 # Select the object.
51 # Run the command in the command window.
52 # See the object's path drawn as a curve.
53 #
54 # Options:
55 #
56 # s=<frame> The start frame. Default to 1.
57 # e=<frame> The end frame. Default to 60.
58 # b=<frame> The by frame. Default to 1.
59 #
60 # Example:
61 #
62 # From Python:
63 # import maya
64 # maya.cmds.spMotionTrace(s=1, e=100, b=2)
65 #
66 # From Mel:
67 # spMotionTrace -s 1 -e 100 -b 2
68 #
69 
70 import maya.OpenMaya as OpenMaya
71 import maya.OpenMayaMPx as OpenMayaMPx
72 import math, sys
73 
74 kPluginCmdName="spMotionTrace"
75 
76 kStartFlag = "-s"
77 kStartLongFlag = "-startFrame"
78 kEndFlag = "-e"
79 kEndLongFlag = "-endFrame"
80 kByFlag = "-b"
81 kByLongFlag = "-byFrame"
82 
83 # command
84 class motionTrace(OpenMayaMPx.MPxCommand):
85  def __init__(self):
86  OpenMayaMPx.MPxCommand.__init__(self)
87  # setup private data members
88  self.__start = 1
89  self.__end = 60
90  self.__by = 1
91 
92 
93  def doIt(self, args):
94  """
95  This method is called from script when this command is called.
96  It should set up any class data necessary for redo/undo,
97  parse any given arguments, and then call redoIt.
98  """
99  argData = OpenMaya.MArgDatabase(self.syntax(), args)
100 
101  if argData.isFlagSet(kStartFlag):
102  self.__start = argData.flagArgumentInt(kStartFlag, 0)
103  if argData.isFlagSet(kEndFlag):
104  self.__end = argData.flagArgumentInt(kEndFlag, 0)
105  if argData.isFlagSet(kByFlag):
106  self.__by = argData.flagArgumentInt(kByFlag, 0)
107 
108  self.redoIt()
109 
110 
111  def redoIt(self):
112  """
113  This method performs the action of the command.
114  This method iterates over all selected items and
115  prints out connected plug and dependency node type
116  information.
117  """
118  picked = OpenMaya.MObjectArray()
119  dependNode = OpenMaya.MObject() # Selected dependency node
120 
121  # Create a selection list iterator
122  slist = OpenMaya.MSelectionList()
123  OpenMaya.MGlobal.getActiveSelectionList(slist)
124  iter = OpenMaya.MItSelectionList(slist)
125 
126  # Iterate over all selected dependency nodes
127  # and save them in a list
128  while not iter.isDone():
129  # Get the selected dependency node
130  iter.getDependNode(dependNode)
131  picked.append(dependNode)
132  iter.next()
133 
134  # sample the animation using start, end, by values
135  pointArrays = [ OpenMaya.MPointArray() for i in range(picked.length()) ]
136 
137  time = self.__start
138  while (time <= self.__end):
139  timeval = OpenMaya.MTime(time)
140  OpenMaya.MGlobal.viewFrame(timeval)
141 
142  # Iterate over selected dependency nodes
143  for i in range(picked.length()):
144  # Get the selected dependency node
145  dependNode = picked[i]
146 
147  # Create a function set for the dependency node
148  fnDependNode = OpenMaya.MFnDependencyNode(dependNode)
149 
150  # Get the translation attribute values
151  txAttr = fnDependNode.attribute("translateX")
152  txPlug = OpenMaya.MPlug(dependNode, txAttr)
153  tx = txPlug.asDouble()
154 
155  tyAttr = fnDependNode.attribute("translateY")
156  tyPlug = OpenMaya.MPlug(dependNode, tyAttr)
157  ty = tyPlug.asDouble()
158 
159  tzAttr = fnDependNode.attribute("translateZ")
160  tzPlug = OpenMaya.MPlug(dependNode, tzAttr)
161  tz = tzPlug.asDouble()
162 
163  print "adding", tx, ty, tz, "\n"
164  pointArrays[i].append(OpenMaya.MPoint(tx, ty, tz))
165 
166  time += self.__by
167 
168  # make a path curve for each selected object
169  for i in range(picked.length()):
170  self.__jMakeCurve(pointArrays[i])
171 
172 
173  def __jMakeCurve(self, cvs):
174  """
175  Make a degree 1 curve from the given CVs.
176 
177  Note that in Python, a double underscore in front of a member name
178  make the method "private" to the class through name-mangling
179  """
180  deg = 1
181  knots = OpenMaya.MDoubleArray()
182 
183  for i in range(cvs.length()):
184  knots.append(i)
185 
186  # Now create the curve
187  nullObj = OpenMaya.MObject()
188  curveFn = OpenMaya.MFnNurbsCurve()
189  curveFn.create(cvs, knots, deg, OpenMaya.MFnNurbsCurve.kOpen, False, False, nullObj)
190 
191 
192 # Creator
193 def cmdCreator():
194  return OpenMayaMPx.asMPxPtr(motionTrace())
195 
196 
197 # Syntax creator
198 def syntaxCreator():
199  syntax = OpenMaya.MSyntax()
200  syntax.addFlag(kStartFlag, kStartLongFlag, OpenMaya.MSyntax.kLong)
201  syntax.addFlag(kEndFlag, kEndLongFlag, OpenMaya.MSyntax.kLong)
202  syntax.addFlag(kByFlag, kByLongFlag, OpenMaya.MSyntax.kLong)
203  return syntax
204 
205 
206 # Initialize the script plug-in
207 def initializePlugin(mobject):
208  mplugin = OpenMayaMPx.MFnPlugin(mobject, "Autodesk", "1.0", "Any")
209  try:
210  mplugin.registerCommand(kPluginCmdName, cmdCreator, syntaxCreator)
211  except:
212  sys.stderr.write("Failed to register command: %s\n" % kPluginCmdName)
213  raise
214 
215 
216 # Uninitialize the script plug-in
217 def uninitializePlugin(mobject):
218  mplugin = OpenMayaMPx.MFnPlugin(mobject)
219  try:
220  mplugin.deregisterCommand(kPluginCmdName)
221  except:
222  sys.stderr.write("Failed to unregister command: %s\n" % kPluginCmdName)
223  raise
224 
225