Making operations undoable#

SAMSON supports Undo and Redo for many operations. Most functions from the SAMSON SDK that modify the data graph can participate in undo/redo. However, simply calling such a function does not automatically make the operation visible in the History. This behavior avoids filling the history with internal or temporary operations, for example when working on nodes that are not part of a document.

To perform operations in an undoable way, use the SAMSON.holding context manager, which automatically turns holding on when entering the block and turns it off when leaving it. Alternatively, you can wrap the code manually using:

This makes the operation appear in the History, where you or the user can undo it.

Prefer the SAMSON.holding context manager because it automatically turns holding off upon exit. This is safer: if your script stops inside the context manager, holding is still cleaned up automatically, whereas a manual SAMSON.beginHolding() without a matching SAMSON.endHolding() may leave SAMSON in an unwanted holding state.

Note

Wrapping operations that are not undoable by their implementation cannot make them undoable.

Note

Most of the commands executed via SAMSON.runCommand() are undoable via the internal use of SAMSON.beginHolding() and SAMSON.endHolding(). But for some you might need to call them from within the context manager SAMSON.holding (or wrap them into SAMSON.beginHolding() and SAMSON.endHolding() directly).

See also

User Guide: History: Undo and redo

SAMSON SDK: Undo and redo

Examples:

Selecting residues in an undoable way using the SAMSON.holding context manager#
# make the operation undoable
with SAMSON.holding('Select residues'):
    # get a node indexer of all residues in the active document
    residueIndexer = SAMSON.getNodes('node.type residue')
    # set selectionFlag to True for residues in the indexer
    for residue in residueIndexer:
        residue.selectionFlag = True
Selecting residues in undoable way by wrapping the code in SAMSON.beginHolding() and SAMSON.endHolding()#
# begin holding - turn the Undo system on
SAMSON.beginHolding('Select residues')

# get a node indexer of all residues in the active document
residueIndexer = SAMSON.getNodes('node.type residue')
# set selectionFlag to True for residues in the indexer
for residue in residueIndexer:
    residue.selectionFlag = True

# end holding - turn the Undo system off
SAMSON.endHolding()
Renaming the active camera#
# get the active camera
camera = SAMSON.getActiveCamera()

# begin holding - turn the Undo system on
with SAMSON.holding('Change camera name'):
    # change the camera name
    camera.name = "New camera name"

When creating nodes not for some temporary use but in documents, it is necessary to make their creation undoable as well.

Make node creation undoable#
# create an instance of a structural model
structuralModel = SBStructuralModel()

# make the operation undoable
with SAMSON.holding("Add node"):
    # hold the node to make it creation undoable
    SAMSON.hold(structuralModel)
    # create the node
    structuralModel.create()
    # add the visual model to the active document
    SAMSON.getActiveDocument().addChild(structuralModel)

Note

When creating a hierarchy of nodes, e.g. a whole structural model, it is not necessary to call SAMSON.hold() for each node - you can call it only for the root node, e.g. for the structural model, which will automatically make the creation of its children undoable as well.