Python API 2.0 Reference
python/api1/py1MotionTraceCmd.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 # DESCRIPTION:
41 #
42 # Produces the Python command "spMotionTrace".
43 #
44 # This plug-in traces the position of an animated object and creates a curve
45 # showing the object's path.
46 #
47 # To use this plug-in, you must first create an object and animate it by setting
48 # keyframes. An easy way to do this is to just create a primitive, then set several
49 # keyframes on it.
50 #
51 # Once this is done, select the animated object and invoke the spMotionTrace command.
52 #
53 # Options:
54 #
55 # s=<frame> The start frame. Default to 1.
56 # e=<frame> The end frame. Default to 60.
57 # b=<frame> The by frame. Default to 1.
58 #
59 # Example:
60 #
61 # From Python:
62 # import maya
63 # maya.cmds.spMotionTrace(s=1, e=100, b=2)
64 #
65 # From Mel:
66 # spMotionTrace -s 1 -e 100 -b 2
67 #
68 # The object will move along its animated path under control of the plug-in and when the
69 # animation is complete, the plug-in will draw a curve in the scene that represents
70 # the motion path of the object.
71 #
72 ########################################################################
73 
74 #
75 # Creation Date: 27 September 2006
76 #
77 
78 from builtins import range
79 import maya.OpenMaya as OpenMaya
80 import maya.OpenMayaMPx as OpenMayaMPx
81 import math, sys
82 
83 kPluginCmdName="spMotionTrace"
84 
85 kStartFlag = "-s"
86 kStartLongFlag = "-startFrame"
87 kEndFlag = "-e"
88 kEndLongFlag = "-endFrame"
89 kByFlag = "-b"
90 kByLongFlag = "-byFrame"
91 
92 # command
93 class motionTrace(OpenMayaMPx.MPxCommand):
94  def __init__(self):
95  OpenMayaMPx.MPxCommand.__init__(self)
96  # setup private data members
97  self.__start = 1
98  self.__end = 60
99  self.__by = 1
100 
101 
102  def doIt(self, args):
103  """
104  This method is called from script when this command is called.
105  It should set up any class data necessary for redo/undo,
106  parse any given arguments, and then call redoIt.
107  """
108  argData = OpenMaya.MArgDatabase(self.syntax(), args)
109 
110  if argData.isFlagSet(kStartFlag):
111  self.__start = argData.flagArgumentInt(kStartFlag, 0)
112  if argData.isFlagSet(kEndFlag):
113  self.__end = argData.flagArgumentInt(kEndFlag, 0)
114  if argData.isFlagSet(kByFlag):
115  self.__by = argData.flagArgumentInt(kByFlag, 0)
116 
117  self.redoIt()
118 
119 
120  def redoIt(self):
121  """
122  This method performs the action of the command.
123  This method iterates over all selected items and
124  prints out connected plug and dependency node type
125  information.
126  """
127  picked = OpenMaya.MObjectArray()
128  dependNode = OpenMaya.MObject() # Selected dependency node
129 
130  # Create a selection list iterator
131  slist = OpenMaya.MSelectionList()
133  iter = OpenMaya.MItSelectionList(slist)
134 
135  # Iterate over all selected dependency nodes
136  # and save them in a list
137  while not iter.isDone():
138  # Get the selected dependency node
139  iter.getDependNode(dependNode)
140  picked.append(dependNode)
141  next(iter)
142 
143  # sample the animation using start, end, by values
144  pointArrays = [ OpenMaya.MPointArray() for i in range(picked.length()) ]
145 
146  time = self.__start
147  while (time <= self.__end):
148  timeval = OpenMaya.MTime(time)
150 
151  # Iterate over selected dependency nodes
152  for i in range(picked.length()):
153  # Get the selected dependency node
154  dependNode = picked[i]
155 
156  # Create a function set for the dependency node
157  fnDependNode = OpenMaya.MFnDependencyNode(dependNode)
158 
159  # Get the translation attribute values
160  txAttr = fnDependNode.attribute("translateX")
161  txPlug = OpenMaya.MPlug(dependNode, txAttr)
162  tx = txPlug.asDouble()
163 
164  tyAttr = fnDependNode.attribute("translateY")
165  tyPlug = OpenMaya.MPlug(dependNode, tyAttr)
166  ty = tyPlug.asDouble()
167 
168  tzAttr = fnDependNode.attribute("translateZ")
169  tzPlug = OpenMaya.MPlug(dependNode, tzAttr)
170  tz = tzPlug.asDouble()
171 
172  print("adding", tx, ty, tz, "\n")
173  pointArrays[i].append(OpenMaya.MPoint(tx, ty, tz))
174 
175  time += self.__by
176 
177  # make a path curve for each selected object
178  for i in range(picked.length()):
179  self.__jMakeCurve(pointArrays[i])
180 
181 
182  def __jMakeCurve(self, cvs):
183  """
184  Make a degree 1 curve from the given CVs.
185 
186  Note that in Python, a double underscore in front of a member name
187  make the method "private" to the class through name-mangling
188  """
189  deg = 1
190  knots = OpenMaya.MDoubleArray()
191 
192  for i in range(cvs.length()):
193  knots.append(i)
194 
195  # Now create the curve
196  nullObj = OpenMaya.MObject()
197  curveFn = OpenMaya.MFnNurbsCurve()
198  curveFn.create(cvs, knots, deg, OpenMaya.MFnNurbsCurve.kOpen, False, False, nullObj)
199 
200 
201 # Creator
202 def cmdCreator():
203  return OpenMayaMPx.asMPxPtr(motionTrace())
204 
205 
206 # Syntax creator
207 def syntaxCreator():
208  syntax = OpenMaya.MSyntax()
209  syntax.addFlag(kStartFlag, kStartLongFlag, OpenMaya.MSyntax.kLong)
210  syntax.addFlag(kEndFlag, kEndLongFlag, OpenMaya.MSyntax.kLong)
211  syntax.addFlag(kByFlag, kByLongFlag, OpenMaya.MSyntax.kLong)
212  return syntax
213 
214 
215 # Initialize the script plug-in
216 def initializePlugin(mobject):
217  mplugin = OpenMayaMPx.MFnPlugin(mobject, "Autodesk", "1.0", "Any")
218  try:
219  mplugin.registerCommand(kPluginCmdName, cmdCreator, syntaxCreator)
220  except:
221  sys.stderr.write("Failed to register command: %s\n" % kPluginCmdName)
222  raise
223 
224 
225 # Uninitialize the script plug-in
226 def uninitializePlugin(mobject):
227  mplugin = OpenMayaMPx.MFnPlugin(mobject)
228  try:
229  mplugin.deregisterCommand(kPluginCmdName)
230  except:
231  sys.stderr.write("Failed to unregister command: %s\n" % kPluginCmdName)
232  raise
233 
234