Contains the undo engine allowing to adjust the scene with api commands while providing full undo and redo support.
- 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)
- 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.
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.
- 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
Assure our plugin is loaded - called during module intialization
Note: | will only load the plugin if the undo system is not disabled |
---|
Call before your function with undoable operations ends
Note: | prefer the @undoable decorator |
---|
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 |
---|
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 |
Call before you start undoable operations
Note: | prefer the @undoable decorator |
---|
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 |
---|
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 |
Epydoc: 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! |
Epydoc: mrv.maya.undo.DagModifier
Bases: mrv.maya.undo.DGModifier
undo-aware DAG modifier, copying all extra functions from DGModifier
Epydoc: 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
Execute the doit command
Returns: | result of the doit command |
---|
Epydoc: 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 |
Add a command to the queue for later application
Parameters: |
|
---|
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 |
Epydoc: 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 |
---|
Epydoc: 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 ! |
---|
Epydoc: mrv.maya.undo.StartUndo
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 |
Bases: maya.OpenMayaMPx.MPxCommand
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 |
Epydoc: 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. |
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. |
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 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 |