>
>
> Yes, but Method A sets tx, ty and tz of a transform - that is 3  
> calls to the API , but just one call to MethodA. The way it works  
> now with that node, it would 3 operations onto the stack, requireing  
> it to be undone 3 times ( instead of one ).

i think this is where you are misunderstanding.  let me clarify a  
little more how it all works with an example.  take  
MFnTransform.setTranslation. PyMEL provides a wrapped copy of this as  
Transform.setTranslation.   when pymel.Transform.setTranslation is  
called, here's what happens in relation to undo:

1) process input args, if any
2) call MFnTransform.getTranslation() to get the current translation.
3) append to the api undo queue, with necessary info to undo/redo  
later (the current method, the current args, and the current  
translation)
4) call MFnTransform.setTranslation() with the passed args
5) process result and return it

Transform.setTranslation does not call any API methods other than  
those pertaining to translation.   so a call to setTranslation would  
append one element to the undo stack.  it doesn't matter that  
internally, translation is three attributes, all that is handled in  
the c++ api.  it's still one api call, which needs just one undo.


>
> Your explanation does not alleviate my concern - which is acutally a  
> major flaw in the whole concept of using a garbage node.
> In fact you would have to store these 3 commands in an individual  
> list that can be undone at once. This is impossible with a garbage  
> node putting every attribute change onto maya's undo stack. Even if  
> you would track your stack depth to be able to internally track your  
> 3 commands as one, maya's undo queue will still be contaminated with  
> 2 additional do-nothing commands.
> This shows that having a node respond to every API call ( that  
> should be undoable ) cannot work the way undo has to work.

first of all, a little primer on how undo works.  let's start with  
some example code:



def check():
        for cam in cmds.ls(type='camera'):
                print cam, cmds.getAttr( cam + ".focalLength" )

for cam in cmds.ls(type='camera'):
        cmds.setAttr( cam + ".focalLength", 20 )

--------------STOP---------------------

check()
cmds.undo()
check()



if you run the first part, you set all the focal lengths in the scene  
to 20.  if you're starting from a fresh scene. that is 4 separate undo  
items, because there's four cameras.  maya is smart about this and it  
knows to group them because they were all done in a "for" loop.  so if  
you call cmds.undo a single time, as in the example above, it will  
undo all 4 at once, but it's still 4 separate undos in a stack  ( to  
see this for yourself, you can add an attribute change callback to all  
the cameras and see that calling cmds.undo once in the example above  
changes each attribute in succession).  to further demonstrate that  
this grouping effect is maya magic, try the same thing via a  
standalone interpreter:  it doesn't work.  cmds.undo in standalone  
will only undo one setAttr at a time, even if they're done in a loop.

here's the pymel equivalent.  if you check out the latest pymel from  
svn and run this in 2009, it will work just the same as the maya.cmds  
example above.




for cam in ls(type='camera'):
        cam.setFocalLength( 20 )

--------------STOP---------------------

check()
undo()
check()


it undoes everything as expected.  i hope that this clarifies how the  
system works. in fact, it works very much the way that undo/redo works  
when writing plugins, only it's external to the plugin API.  in that  
regard, i think it's less of a hack than you  make it out to be.

all this said, i think that Autodesk needs to consider opening up the  
undo queue for us hackers to utilize outside of the plugin  
architecture.  now that the API is python, we don't always want to use  
it in a plugin or in a node.  but in case you haven't noticed, the  
entire point of pymel is that we don't have time to wait for autodesk  
to catch up.

i'm glad that you're pushing me on this issue, because it helped me  
clarify my understanding of the undo queue and i squashed some bugs  
along the way, but rest assured that it does work.


-chad




--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/python_inside_maya
-~----------~----~----~----~------~----~------~--~---

Reply via email to