160 likes | 401 Views
Slicer MRML. MRML Library provides API for managing medical image data types (Volumes, Models, Transforms, Fiducials, Cameras, etc) and their visualization. Each data type is represented by a special MRML node. MRML Scene is a collection of MRML nodes.
E N D
Slicer MRML • MRML Library provides API for managing medical image data types (Volumes, Models, Transforms, Fiducials, Cameras, etc) and their visualization. • Each data type is represented by a special MRML node. • MRML Scene is a collection of MRML nodes. • Slicer MRML data model is implemented independent of the visualization and algorithmic components of the system. • Other Slicer components (Logic and GUI) observe changes in MRML scene and individual nodes and process change MRML events.
Slicer MRML Scene • MRML Scene manages MRML nodes : add, delete, find, find by type, etc. • MRML Scene provides persistence of MRML nodes (reading/writing to/from XML file). • MRML Scene provides Undo/Redo mechanism that restores a previous state of the scene and individual nodes.
Slicer MRML Nodes • The MRML nodes are designed to store the state of the Slicer application, both raw data and visualization parameters. • All MRML nodes have to implement certain standard API: ReadAttributes, WriteAttributes, Copy, etc. • MRML nodes are organized into C++ class hierarchies, all derived from vtkMRMLNode class. • For example vtkMRMLTransformableNode is the parent class of Volume, Model, Fiducial, and Transformation nodes; vtkVolumeNode is a parent of vtkMRMLScalarVolumeNode and vtkMRMLVectorVolumeNode
MRML Nodes Class Hierarchy (vtkMRML)Node TransformableNode VolumeNode ModelNode FiducialNode TransformNode LinearTransformNode ScalarVolumeNode TensorVolumeNode DiffusionWeightedVolumeNode VectorVolumeNode DiffusionTensorVolumeNode
References to MRML Nodes • Some MRML nodes have references to other nodes. • Transformable Node has a reference to a Transformation node. Transformation node has a reference to its parent Transformation node. • References are stored by node ID. • Use vtkSetReferenceStringMacro to set reference ID (it registers reference with the scene). • Access methods should check if the referenced node is still in the MRML scene using its ID.
Transform Hierarchy and Node References TransformNode0 TransformNodeID =NULL ModeNode0 TransformNodeID = ‘TransofrmNode1’ VolumeNode0 TransformNodeID = ‘TransofrmNode2’ TransformNode1 TransformNodeID = TransformNode0 TransformNode2 TransformNodeID = TransformNode1
MRML Events and Observers • Changes in MRML scene and individual nodes propagate to other observing nodes, GUI and Logic objects via vtk events and command-observer mechanism. • Use vtk AddObserver() and InvokeEvent() methods. vtk SetMacro generates ModifiedEvent. • The command-observer mechanism for MRML is implemented using helper vtkObserverManager, class, MRML Observer macros, and ProcessMRMLEvents method. • Observers should store a registered pointer to a MRML node to prevent callbacks on a deleted object.
Events and Observers Example ViewerWidget ProcessMRMLEvents() update transforms observes callback ModelNode ProcessMRMLEvents() InvokeEvent(TransformModifiedEvent) observes callback LinearTransofmNode ProcessMRMLEvents() InvokeEvent(TransformModifiedEvent) observes callback vtkMatrix4x4 SetElement() InvokeEvent(ModifiedEvent)
MRML Observer API • Defined in Libs/MRML/vtkMRMLNode.h • VtkSetMRMLObjectMacro - registers MRML node with another vtk object (another MRML node, Logic or GUI). No observers added. • VtkSetAndObserveMRMLObjectMacro - registers MRML node and adds an observer for vtkCommand::ModifyEvent. • VtkSetAndObserveMRMLObjectEventsMacro - registers MRML node and adds an observer for a specified set of events. • SetAndObserveMRMLScene[Events]() method is used in GUI and Logic to observe Modify, NewScene, NodeAdded, etc. events. • ProcessMRMLEvents method should be implemented in MRML nodes, Logic, and GUI classes in order to process events from the observed nodes.
Creating Custom MRML Node • Custom MRML nodes provide persistent storage for the module parameters. • Custom MRML nodes should be registered with the MRML scene using RegisterNodeClass() so they can be saved and restored from a scene file. • Classes should implement the following methods: • CreateNodeInstance() – similar to VTK New() method only not static. • GetNodeTagName() – return a unique XML tag for this node. • ReadXMLAttributes() – reads node attributes from XML file as name-value pairs. • WriteXML() – writes node attributes to output stream (as in interpolate="1" ). • Copy() – copies node attributes.
Creating Custom MRML Node - continued • If the node has references to other nodes the following additional methods should be implemented: • UpdateReferenceID() - updates the stored reference to another node. • UpdateScene()- updates other nodes in the scene depending on this node or updates this node if it depends on other nodes when the scene is read in. This method is called automatically by XML parser after all nodes are created. • An example of a custom MRML node implementation: vtkMRMLGradientAnisotropicDiffusionFilterNode in Modules/GradientAnisotropicDiffusionFilter directory. • To add node to the MRML scene: • In the code: use standard vtk New() and add node to the scene using vtkMRMLScene::AddNode(vtkMRMLNode *) • By user request: use vtkSlicerNodeSelectorWidget that creates a new node from the module’s UI.
Undo/Redo Architecture for Slicer3 • Undo/Redo is based on saving and restoring the state of MRML nodes in the Scene. • MRML scene can save snapshot of all nodes into a special Undo and Redo stacks. • The Undo and Redo stacks store copies of nodes that have changed from the previous snapshot. The node that have not changes are stored by a reference (pointer). • When an Undo is called on the scene, the current state of Undo stack is copied into the current scene and also into Redo stack. • => All Undoable operations must store their data as MRML nodes
Undo Implementation MRML Scene Undo Stack Initial Scene Delta1 Scene Delta2 Scene Saved Scene N1 N1 N2 N4 N4 N3 N5 N5
How to use Undo API • Developer controls at what point the snapshot is saved by calling SaveStateForUndo method on the MRML scene. • SaveStateForUndo() - saves the state of all nodes in the scene • SetActiveScene(vtkMRMLScene *) - saves the state of the specified node. • SetActiveScene(vtkCollection*) - saves the state of the specified collection of nodes. • SaveStateForUndo() should be called in GUI/Logic classes before changing the state of MRML nodes. Usually done in the ProcessGUIEvents method that processes events from the user interactions with GUI widgets. • SaveStateForUndo() should not be called while processing transient events such as continuous events sent by KW UI while dragging a slider (for example vtkKWScale::ScaleValueStartChangingEvent).