How to undo all document changes from a command

I am developing a python command to perform a custom export process. During the process changes will be made to the document (changing selection, adding objects, renaming objects…). At the end of the export (or in the case of an exception) I would like all changes to the document to be reverted.

After the script executes, undo will correctly revert all changes.
During the script execution this does not work: Undo (returns false) / 'rs.Command("_Undo")(printsNothing to undo.`).

I have tried BeginUndoRecord (returns 0) / EndUndoRecord (returns False). Looking at AddCustomUndoEvent it appears that this pertains only to plugin data.

Hi @services, to undo your changes without using a custom undo event, you might keep track of everything you do in your script. Eg. before changing the selection, store the object id’s of the selected objects so you can later re-select them. When you add new objects store their Id. eg. like this:

new_crv_id = scriptcontext.doc.Objects.AddCurve(my_curve)

you can add new_crv_id to a list of object ids to remove later. Before renaming objects, store the id and the old name so you can re-store it. To make this all work in case of an exception, put your code into a try except block eg.:

    # your export code
except Exception:
    # restore 


Hi Clement,
What you have described is what I am presently doing (but with try/finally so that the restore happens with and without an exception.)

Since Rhino is evidently able to track and revert these changes I was hoping that there might be a way to trigger that action from my script.

FWIW: An additional advantage of applying Rhino’s undo would be that an open document would not be deemed “modified” after running the export script.

Hi @services, that would be the least problem as you can set it yourself:

scriptcontext.doc.Modified = False

No, i have created custom undo events with python. But you need to populate the event code with the same stuff you currently do.

I think this is because the undo step is only recorded if your script finished not during execution.


Thank you so much - scriptcontext.doc.Modified = False is exactly what I needed!