On 12/11/2015 at 03:13, xxxxxxxx wrote:
Now, how to use the Undos best? First, you have the bracket calls StartUndo() and EndUndo(). These simply define what range of single changes (AddUndo()s) will be reverted when the user presses the undo key. They must match, so if your code runs over a StartUndo, it must also run over an EndUndo sometime later. That means no early exits from a function that opens a StartUndo!
Then there are many types of AddUndo()s that can be used within such a StartUndo/EndUndo bracket. Each determines the scope of the undo - the amount of data that C4D needs to remember to revert the change. For example, UNDOTYPE_BITS will create storage only for the bits of an object, which uses very little space, while UNDOTYPE_CHANGE_SMALL stores all the parameters, and UNDOTYPE_CHANGE stores even hierarchies, so it takes up more space. You call these AddUndos before you make the actual change because this way, C4D knows what state to remember.
Now I don't know the actual C4D source code, but I guess you can imagine it like this:
- C4D gets an AddUndo for a certain object
- C4D thinks "Hey, this thing here is going to be changed! I must remember it the way it used to be!"
- C4D creates a copy of that object and puts it into its Undo list
- Then you make changes to that object.
When the user presses the Undo key, C4D looks at its list, and goes through all the AddUndo nodes in reverse order from the last EndUndo to the StartUndo before it. Now it finds that AddUndo node, and restores the original object with this data. Once it reaches the StartUndo, it considers that Undo sequence to be done, and stops.
Any failure to match EndUndo and StartUndo will corrupt this list. Any use of the wrong AddUndo may cause C4D to store too little data for a complete reversal of the change. If you use an UNDOTYPE with a broader scope, you should be able to execute several changes to an object with only one AddUndo - but you need to watch out for functions that DO create undos by themselves.
Think about what you need in an undo to revert an action, and use the appropriate UNDOTYPE. Now I am not a Maxon programmer so maybe they can add to the matter (the documentation is giving some examples but more information is always welcome), but your example above should also work as
doc.AddUndo(c4d.UNDOTYPE_CHANGE_SMALL, shrinkwrapdeformer)
shrinkwrapdeformer[c4d.ID_BASEOBJECT_GENERATOR_FLAG]=False
shrinkwrapdeformer.SetName("HB_RetopoProjector")
But when in doubt, it may be best to test :-)