<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.slicer.org/w/index.php?action=history&amp;feed=atom&amp;title=Documentation%2F4.6%2FDevelopers%2FMRML%2FNodeReferences</id>
	<title>Documentation/4.6/Developers/MRML/NodeReferences - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.slicer.org/w/index.php?action=history&amp;feed=atom&amp;title=Documentation%2F4.6%2FDevelopers%2FMRML%2FNodeReferences"/>
	<link rel="alternate" type="text/html" href="https://www.slicer.org/w/index.php?title=Documentation/4.6/Developers/MRML/NodeReferences&amp;action=history"/>
	<updated>2026-04-04T15:29:36Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.33.0</generator>
	<entry>
		<id>https://www.slicer.org/w/index.php?title=Documentation/4.6/Developers/MRML/NodeReferences&amp;diff=47455&amp;oldid=prev</id>
		<title>UpdateBot: Nightly -&gt; 4.6</title>
		<link rel="alternate" type="text/html" href="https://www.slicer.org/w/index.php?title=Documentation/4.6/Developers/MRML/NodeReferences&amp;diff=47455&amp;oldid=prev"/>
		<updated>2016-11-07T06:24:42Z</updated>

		<summary type="html">&lt;p&gt;Nightly -&amp;gt; 4.6&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;noinclude&amp;gt;{{documentation/versioncheck}}&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This page explains how to create a MRML node that reference and observes other MRML nodes.&lt;br /&gt;
&lt;br /&gt;
As describe in the [[Documentation/{{documentation/version}}/Developers/MRML#MRML_Nodes|MRML Nodes]] section, node references allow to associate data node implementing interfaces (like [{{doxygen-class-url|vtkMRMLDisplayableNode}} Displayable], [{{doxygen-class-url|vtkMRMLStorableNode}} Storable] and [{{doxygen-class-url|vtkMRMLTransformableNode}} Transformable]) with a representation node (like [{{doxygen-class-url|vtkMRMLStorageNode}} Storage] or [{{doxygen-class-url|vtkMRMLDisplayNode}} Display] node) or other data node (like [{{doxygen-class-url|vtkMRMLTransformNode}} Transform] node).&lt;br /&gt;
&lt;br /&gt;
== API Description ==&lt;br /&gt;
&lt;br /&gt;
The node reference API automatically takes care of&lt;br /&gt;
(1) read/write/copy of node references,&lt;br /&gt;
(2) updating references on scene import,&lt;br /&gt;
(3) adding and deleting nodes.&lt;br /&gt;
&lt;br /&gt;
All that functionality is implemented in the [{{doxygen-class-url|vtkMRMLNode}} vtkMRMLNode] base class. &lt;br /&gt;
&lt;br /&gt;
The only thing that needs to happen in the derived MRML node class (usually in the constructor of the class)&lt;br /&gt;
is a call to &amp;lt;code&amp;gt;vtkMRMLNode::AddNodeReferenceRole(const char *referenceRole, const char *mrmlAttributeName)&amp;lt;/code&amp;gt;&lt;br /&gt;
that takes a unique string defining the reference role between this node &lt;br /&gt;
and the referenced node, and a MRML attribute name for storing the&lt;br /&gt;
reference in the .mrml file.&lt;br /&gt;
&lt;br /&gt;
The only other call that is needed is either:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vtkMRMLNode* SetAndObserveNodeReferenceID(const char* referenceRole , const char* referencedNodeID, vtkIntArray *events=0);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
or &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vtkMRMLNode* AddAndObserveNodeReferenceID(const char* referenceRole , const char* referencedNodeID, vtkIntArray *events=0);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
if multiple instances of this reference are allowed.&lt;br /&gt;
&lt;br /&gt;
[{{doxygen-class-url|vtkMRMLNode}} vtkMRMLNode] also provides virtual callbacks that can be extended in the&lt;br /&gt;
derived classes:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
OnNodeReferenceAdded(vtkMRMLNodeReference *reference)&lt;br /&gt;
OnNodeReferenceRemoved(vtkMRMLNodeReference *reference)&lt;br /&gt;
OnNodeReferenceModified(vtkMRMLNodeReference *reference)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default those methods generate the following events:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vtkMRMLNode::ReferenceAddedEvent&lt;br /&gt;
vtkMRMLNode::ReferenceRemovedEvent&lt;br /&gt;
vtkMRMLNode::ReferenceModifiedEvent&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the derived classes those methods could be extended using &amp;lt;code&amp;gt;vtkMRMLNode&amp;lt;/code&amp;gt;&lt;br /&gt;
API that allows querying of node's references:&lt;br /&gt;
&lt;br /&gt;
* char *GetNthNodeReferenceID(const char* referenceRole, int n);&lt;br /&gt;
* vtkMRMLNode* GetNthNodeReference(const char* referenceRole, int n);&lt;br /&gt;
* int GetNumberOfNodeReferences(const char* referenceRole);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
For full API see [{{doxygen-class-url|vtkMRMLNode|members}} here]&lt;br /&gt;
&lt;br /&gt;
Currently the following MRML nodes are implemented using MRML Node Reference API:&lt;br /&gt;
* [{{doxygen-class-url|vtkMRMLStorableNode}} vtkMRMLStorableNode]&lt;br /&gt;
* [{{doxygen-class-url|vtkMRMLTransformableNode}} vtkMRMLTransformableNode]&lt;br /&gt;
* [{{doxygen-class-url|vtkMRMLDisplayableNode}} vtkMRMLDisplayableNode]&lt;br /&gt;
&lt;br /&gt;
Other references to MRML nodes such as to [{{doxygen-class-url|vtkMRMLColorTableNode}} vtkMRMLColorTableNode], [{{doxygen-class-url|vtkMRMLDiffusionTensorDisplayPropertiesNode}} vtkMRMLDiffusionTensorDisplayPropertiesNode] are currently not using this API. &lt;br /&gt;
&lt;br /&gt;
Module parameter nodes that contain references to input/output Volume/Model, etc. nodes may or may not require a new API since not all of them contain logic to deal with reference changes.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
* vtkMRMLTransformableNode implementation:&lt;br /&gt;
http://viewvc.slicer.org/viewvc.cgi/Slicer4/trunk/Libs/MRML/Core/vtkMRMLTransformableNode.h?view=log&lt;br /&gt;
* vtkMRMLDisplayableNodeimplementation:&lt;br /&gt;
http://viewvc.slicer.org/viewvc.cgi/Slicer4/trunk/Libs/MRML/Core/vtkMRMLDisplayableNode.h?view=log&lt;br /&gt;
* vtkMRMLStorableNodeimplementation:&lt;br /&gt;
http://viewvc.slicer.org/viewvc.cgi/Slicer4/trunk/Libs/MRML/Core/vtkMRMLStorableNode.h?view=log&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In Slicer4.2 prior to March of 2013 each MRML node that contained&lt;br /&gt;
references to other MRML nodes (for example each vtkMRMLDisplayableNode contained&lt;br /&gt;
a reference to an instance vtkMRMLDisplayNode) was responsible for&lt;br /&gt;
managing the references internally. This involved complicated logic and&lt;br /&gt;
bookkeeping to maintain the references in sync when importing scenes,&lt;br /&gt;
adding/deleting nodes, modifying referenced nodes, etc.&lt;br /&gt;
&lt;br /&gt;
When creating a new node with the reference to another node the following&lt;br /&gt;
methods needed to be created/updated to handle the references:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Copy&lt;br /&gt;
* PrintSelf&lt;br /&gt;
* ReadXMLAttributes&lt;br /&gt;
* WriteXML&lt;br /&gt;
* ProcessMRMLEvents&lt;br /&gt;
* UpdateReferenceID&lt;br /&gt;
* SetSceneReferences&lt;br /&gt;
* UpdateScene&lt;br /&gt;
* UpdateReferences&lt;br /&gt;
* SetAndObserveNodeReferenceID&lt;/div&gt;</summary>
		<author><name>UpdateBot</name></author>
		
	</entry>
</feed>