MPxCommand undoIt()

383 views
Skip to first unread message

André Adam

unread,
Nov 18, 2011, 5:02:48 AM11/18/11
to python_inside_maya
Hi!

I have written some MPxCommands and would like to implement undo
functionality. I think I have done things right so far, I used doIt()
to collect data and store it to the class, and I implemented the
actual workload in redoIt(), using only the stored data sets.

Now, with

def isUndoable(self):
return True

I think Maya should trigger my

def undoIt(self):
print 'Hello!'

when pressing z after the command was excecuted. Unfortunately, this
does not work, my undoIt() function is not called. I have queried
isUndoable from the doIt() function, and it returns True, so undoIt()
should be triggered, no?

Any hint would be greaty appreciated, cheers!

-André

Justin Israel

unread,
Nov 18, 2011, 11:14:17 AM11/18/11
to python_in...@googlegroups.com
Hey Andre,

This quick test seems to work fine for me:

It successfully prints as it enters each method as expected.
Maybe you could compare it to how your code is arranged?

-- justin



jo benayoun

unread,
Nov 18, 2011, 5:55:42 AM11/18/11
to python_in...@googlegroups.com
Hi André, 

Have you try to put a trace statement ("print ...") inside your "isUndoable()" method to see if Maya queries it right after the command's execution ?
Do you make a use of Maya Python API calls during the execution of your commands which are not undoable or modify underlying datas ?
Have you check for typos ? :(

jo








2011/11/18 André Adam <a_adam...@gmx.de>

André Adam

unread,
Nov 21, 2011, 4:24:56 AM11/21/11
to python_inside_maya
Thanks for the input, I have found what makes it not work, though I
don't quite understand why. I am executing my command from a Python
tab in the script editor (for ease of handling) while still coding on
it. A simple call makes the command work as expected and correctly
triggers the undoIt(). So, this works as expected:

-----
import maya
maya.cmds.SimpleCommand()
-----

However, when I put some code in front of the script call, undo does
not work anymore. I suspect it might have something to do with this
being API code and not MEL, thus perhaps tunneling below the undo-
queue.

Does someone know this for certain? Thanks for a quick hint, here is
the script code which prevents the undo of SimpleCommand() to be
triggered:

-----
import maya
import maya.OpenMaya as api

#New Scene
api.MGlobal.executeCommand('file -new -f')

#Create and fetch three tori
oCmdResult = api.MCommandResult()
aCmdResult = []

api.MGlobal.executeCommand('polyTorus -name Pong1', oCmdResult)
oCmdResult.getResult(aCmdResult)
sTorus0 = aCmdResult[0]

api.MGlobal.executeCommand('polyTorus -name Pong2', oCmdResult)
oCmdResult.getResult(aCmdResult)
sTorus1 = aCmdResult[0]

api.MGlobal.executeCommand('polyTorus -name Pong3', oCmdResult)
oCmdResult.getResult(aCmdResult)
sTorus2 = aCmdResult[0]

api.MGlobal.executeCommand('move 0 5 0 %s' %(sTorus1))
api.MGlobal.executeCommand('rotate 0 45 45 %s' %(sTorus1))
api.MGlobal.executeCommand('move 0 10 0 %s' %(sTorus2))

#Call the command
maya.cmds.SimpleCommand()
-----

Cheers!

-André


On Nov 18, 11:55 am, jo benayoun <jobenay...@gmail.com> wrote:
> Hi André,
>
> Have you try to put a trace statement ("print ...") inside your
> "isUndoable()" method to see if Maya queries it right after the command's
> execution ?
> Do you make a use of Maya Python API calls during the execution of your
> commands which are not undoable or modify underlying datas ?
> Have you check for typos ? :(
>
> jo
>

> 2011/11/18 André Adam <a_adam_li...@gmx.de>

AK Eric

unread,
Nov 29, 2011, 2:04:11 PM11/29/11
to python_inside_maya
I've found that a very precarious way to work :) Whenever I'm working
on scripted plugins, I just unload\reload them between each
iteration. Here's a code chunk I use to do that, that I save in the
physical scripted plugin module itself:

import os
import maya.cmds as mc

def pluginLoader(load):
fullPath = __file__
if fullPath.endswith('.pyc'):
fullPath = fullPath [:-1]
dirPath, plugin = os.path.split(fullPath)
if load:
if not mc.pluginInfo(plugin, query=True, loaded=True):
mc.loadPlugin(fullPath, quiet=True)
mc.pluginInfo(plugin, edit=True, autoload=True)
else:
if mc.pluginInfo(plugin, query=True, loaded=True):
mc.unloadPlugin(plugin, force=True)
mc.pluginInfo(plugin, edit=True, autoload=False)

Then in the script editor I do something like this, which I can
highlight and execute as a single block:

import myPlugin
myPlugin.pluginLoader(False)
reload(myPlugin)
myPlugin.pluginLoader(True)
# Now execute the plugin code
# ...

I've also read it's a really good idea to flush your undo queue when
unloading\reloading the plugin.

André Adam

unread,
Nov 29, 2011, 2:13:22 PM11/29/11
to python_inside_maya
Yep, once the plugin is part of the undo stack, Maya naturally is very
unhappy when unloading it. Already hit that one. :)

Your code looks like a good wrapper for working with plugins, thanks
for sharing!

-André

viktoras

unread,
Dec 6, 2011, 11:48:20 PM12/6/11
to python_in...@googlegroups.com
I've experienced that flushing undo queue might not be enough in a lot of cases, my plugin reloader does "close scene"->"unload plugin"->"load plugin"->"load scene again". usually i work with test scenes while debuging plugins, so that is not a big issue. sometimes maya likes to crash when doing that as well - but I only get that with complex C++ plugins (custom DG data types, custom callbacks commands for userPaint tool, etc).
Reply all
Reply to author
Forward
0 new messages