mrv.maya.undo

Epydoc: mrv.maya.undo

Contains the undo engine allowing to adjust the scene with api commands while providing full undo and redo support.

Features

  • modify dag or dg using the undo-enabled DG and DAG modifiers
  • modify values using Nodes and their plugs (as the plugs are overridden to store undo information)

Limitations

  • You cannot mix mel and API proprely unless you use an MDGModifier.commandToExecute
  • Calling operations that flush the undo queue from within an undoable method causes the internal python undo stack not to be flushed, leaving dangling objects that might crash maya once they are undon.
  • WORKAROUND: Mark these methods with @notundoable and assure they are not called by an undoable method
  • calling MFn methods on a node usually means that undo is not supported for it.

Configuration

To globally disable the undo queue using cmds.undo will disable tracking of opeartions, but will still call the mel command.

Disable the ‘undoable’ decorator effectively remove the surrounding mel script calls by setting the MRV_UNDO_ENABLED environment variable to 0 (default 1). Additionally it will turn off the maya undo queue as a convenience.

If the mrv undo queue is disabled, MPlugs will not store undo information anymore and do not incur any overhead.

Implementing an undoable method

  • decorate with @undoable
  • minimize probability that your operation will fail before creating an operation (for efficiency)
  • only use operation’s doIt() method to apply your changes
  • if you raise, you should not have created an undo operation

Functions

mrv.maya.undo.__initialize()

Assure our plugin is loaded - called during module intialization

Note:will only load the plugin if the undo system is not disabled
mrv.maya.undo._decrStack(name='unnamed')
Indicate that a method level was exitted - and cause the undo queue to be stored on the command if appropriate We try to call the command only if needed
mrv.maya.undo._incrStack()
Indicate that a new method level was reached
mrv.maya.undo.endUndo()

Call before your function with undoable operations ends

Note:prefer the @undoable decorator
mrv.maya.undo.forceundoable(func)

As undoable, but will enable the undo queue if it is currently disabled. It will forcibly enable maya’s undo queue.

Note:can only be employed reasonably if used in conjunction with undoAndClear as it will restore the old state of the undoqueue afterwards, which might be off, thus rendering attempts to undo impossible
mrv.maya.undo.initializePlugin(mobject)
mrv.maya.undo.notundoable(func)

Decorator wrapping a function into a muteUndo call, thus all undoable operations called from this method will not enter the UndoRecorder and thus pollute it.

Note:use it if your method cannot support undo, butcalls undoable operations itself
Note:all functions using a notundoable should be notundoable themselves
Note:does nothing if the undo queue is globally disabled
mrv.maya.undo.startUndo()

Call before you start undoable operations

Note:prefer the @undoable decorator
mrv.maya.undo.undoAndClear()

Undo all operations on the undo stack and clear it afterwards. The respective undo command will do nothing once undo, but would undo all future operations. The state of the undoqueue is well defined afterwards, but callers may stop functioning if their changes have been undone.

Note:can be used if you need control over undo in very specific operations and in a well defined context
mrv.maya.undo.undoable(func)

Decorator wrapping func so that it will start undo when it begins and end undo when it ends. It assures that only toplevel undoable functions will actually produce an undo event To mark a function undoable, decorate it:

>>> @undoable
>>> def func():
>>>     pass
Note:Using decorated functions appears to be only FASTER than implementing it manually, thus using these is will greatly improve code readability
Note:if you use undoable functions, you should mark yourself undoable too - otherwise the functions you call will create individual undo steps
Note:if the undo queue is disabled, the decorator does nothing
mrv.maya.undo.uninitializePlugin(mobject)

Classes

Epydoc: mrv.maya.undo.DGModifier

class mrv.maya.undo.DGModifier

Bases: mrv.maya.undo.Operation

Undo-aware DG Modifier - using it will automatically put it onto the API undo queue

Note:You MUST call doIt() before once you have instantiated an instance, even though you have nothing on it. This requiredment is related to the undo queue mechanism
Note:May NOT derive directly from dg modifier!
doIt()
Override from Operation
undoIt()
Override from Operation

Epydoc: mrv.maya.undo.DagModifier

class mrv.maya.undo.DagModifier

Bases: mrv.maya.undo.DGModifier

undo-aware DAG modifier, copying all extra functions from DGModifier

doIt()
Override from Operation
undoIt()
Override from Operation

Epydoc: mrv.maya.undo.GenericOperation

class mrv.maya.undo.GenericOperation

Bases: mrv.maya.undo.Operation

Simple oeration allowing to use a generic doit and untoit call to be accessed using the operation interface.

In other words: If you do not want to derive from operation just because you would like to have your own custom ( but simple) do it and undo it methods, you would just use this all-in-one operation

doIt()

Execute the doit command

Returns:result of the doit command
setDoitCmd(func, *args, **kwargs)
Add the doit call to our instance
setUndoitCmd(func, *args, **kwargs)
Add the undoit call to our instance
undoIt()
Execute undoit if doit did not fail

Epydoc: mrv.maya.undo.GenericOperationStack

class mrv.maya.undo.GenericOperationStack

Bases: mrv.maya.undo.Operation

Operation able to undo generic callable commands (one or multiple). It would be used whenever a simple generic operatino is not sufficient

In your api command, create a GenericOperationStack operation instance, add your (mel) commands that should be executed in a row as Call. To apply them, call doIt once (and only once !). You can have only one command stored, or many if they should be executed in a row. The vital part is that with each do command, you supply an undo command. This way your operations can be undone and redone once undo / redo is requested

Note:this class works well with mrv.util.Call
Note:to execute the calls added, you must call doIt or addCmdAndCall - otherwise the undoqueue might brake if exceptions occour !
Note:your calls may use MEL commands safely as the undo-queue will be torn off during execution
Note:Undocommand will be applied in reversed order automatically
addCmd(doCall, undoCall)

Add a command to the queue for later application

Parameters:
  • doCall – instance supporting __call__ interface, called on doIt
  • undoCall – instance supporting __call__ interface, called on undoIt
addCmdAndCall(doCall, undoCall)

Add commands to the queue and execute it right away - either always use this way to add your commands or the addCmd method, never mix them !

Returns:return value of the doCall
Note:use this method if you need the return value of the doCall right away
doIt()
Call all doIt commands stored in our instance after temporarily disabling the undo queue
undoIt()
Call all undoIt commands stored in our instance after temporarily disabling the undo queue

Epydoc: mrv.maya.undo.MuteUndo

class mrv.maya.undo.MuteUndo

Bases: object

Instantiate this class to disable the maya undo queue - on deletion, the previous state will be restored

Note:useful if you want to save the undo overhead involved in an operation, but assure that the previous state is always being reset
prevstate

Epydoc: mrv.maya.undo.Operation

class mrv.maya.undo.Operation

Bases: object

Simple command class as base for all operations All undoable/redoable operation must support it

Note:only operations may be placed on the undo stack !
doIt()
Do whatever you do
undoIt()
Undo whatever you did

Epydoc: mrv.maya.undo.StartUndo

class mrv.maya.undo.StartUndo(id=None)

Bases: object

Utility class that will push the undo stack on __init__ and pop it on __del__

Note:Prefer the undoable decorator over this one as they are easier to use and FASTER !
Note:use this class to assure that you pop undo when your method exists
id

Epydoc: mrv.maya.undo.UndoCmd

class mrv.maya.undo.UndoCmd

Bases: maya.OpenMayaMPx.MPxCommand

appendToResult()
className()
clearResult()
commandString()
static createSyntax()
static creator()
currentDoubleResult()
currentIntResult()
currentResultType()
currentStringResult()
displayError()
displayInfo()
displayWarning()
doIt(argList)
Store out undo information on maya’s undo stack
getCurrentResult()
hasSyntax()
isCurrentResultArray()
isHistoryOn()
isUndoable()
Returns:True if we are undoable - it depends on the state of our undo stack
Note:This doesn’t really seem to have an effect as we will always end up on the undo-queue it seems
redoIt()
Called on once a redo is requested
setCommandString()
setHistoryOn()
setResult()
setUndoable()
syntax()
thisown
The membership flag
undoIt()
Called once undo is requested

Epydoc: mrv.maya.undo.UndoRecorder

class mrv.maya.undo.UndoRecorder

Bases: object

Utility class allowing to undo and redo operations on the python command stack so far to be undone and redone separately and independently of maya’s undo queue.

It can be used to define sections that need to be undone afterwards, for example to reset a scene to its original state after it was prepared for export.

Use the startRecording method to record all future undoable operations onto the stack. stopRecording will finalize the operation, allowing the undo and redo methods to be used.

If you never call startRecording, the instance does not do anything. If you call startRecording and stopRecording but do not call undo, it will integrate itself transparently with the default undo queue.

Note:as opposed to undoAndClear, this utility may be used even if the user is not at the very beginning of an undoable operation.
Note:If this utility is used incorrectly, the undo queue will be in an inconsistent state which may crash maya or cause unexpected behaviour
Note:You may not interleave the start/stop recording areas of different instances which could happen easily in recursive calls.
doIt()
Called only if the user didn’t call undo
redo()
Redo all stored operations after they have been undone :raise AssertionError: if called before stopRecording
startRecording()

Start recording all future undoable commands onto this stack. The previous stack will be safed and restored once this class gets destroyed or once stopRecording gets called.

Note:this method may only be called once, subsequent calls have no effect
Note:This will forcibly enable the undo queue if required until stopRecording is called.
stopRecording()

Stop recording of undoable comamnds and restore the previous command stack. The instance is now ready to undo and redo the recorded commands

Note:this method may only be called once, subsequent calls have no effect
undo()

Undo all stored operations

Note:Must be called at the right time, otherwise the undo queue is in an inconsistent state.
Note:If this method is never being called, the undo-stack will undo itself as part of mayas undo queue, and thus behaves transparently
Raises AssertionError:
 if called before stopRecording as called
undoIt()
called only if the user didnt call undo

Table Of Contents

Previous topic

mrv.maya.scene

Next topic

mrv.maya.env

This Page