<?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.4%2FDevelopers%2FMRML%2FNodeReferences</id>
	<title>Documentation/4.4/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.4%2FDevelopers%2FMRML%2FNodeReferences"/>
	<link rel="alternate" type="text/html" href="https://www.slicer.org/w/index.php?title=Documentation/4.4/Developers/MRML/NodeReferences&amp;action=history"/>
	<updated>2026-04-09T17:38:17Z</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.4/Developers/MRML/NodeReferences&amp;diff=40071&amp;oldid=prev</id>
		<title>UpdateBot: Nightly -&gt; 4.4</title>
		<link rel="alternate" type="text/html" href="https://www.slicer.org/w/index.php?title=Documentation/4.4/Developers/MRML/NodeReferences&amp;diff=40071&amp;oldid=prev"/>
		<updated>2014-12-24T19:59:18Z</updated>

		<summary type="html">&lt;p&gt;Nightly -&amp;gt; 4.4&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;
== Goal ==&lt;br /&gt;
&lt;br /&gt;
This page explains how to create a MRML node that reference and observes&lt;br /&gt;
other MRML nodes.&lt;br /&gt;
&lt;br /&gt;
== API Description ==&lt;br /&gt;
&lt;br /&gt;
The node reference API automatically takes care of (1) read/write/copy of&lt;br /&gt;
node references, (2) updating references on scene import, (3) adding and deleting&lt;br /&gt;
nodes. All that functionality is implemented in the &amp;lt;code&amp;gt;vtkMRMLNode&amp;lt;/code&amp;gt; base&lt;br /&gt;
class. The only thing that needs to happen in the derived MRML node class&lt;br /&gt;
(usually in the constructor of the class)&lt;br /&gt;
is a call to &amp;lt;code&amp;gt;vtkMRMLNode::AddNodeReferenceRole(const char *referenceRole,&lt;br /&gt;
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 the multiple instances of this reference are allowed.&lt;br /&gt;
&lt;br /&gt;
vtkMRMLNode also provides virtual callbacks that can be extended in the&lt;br /&gt;
derived classes:&lt;br /&gt;
* OnNodeReferenceAdded(vtkMRMLNodeReference *reference)&lt;br /&gt;
* OnNodeReferenceRemoved(vtkMRMLNodeReference *reference)&lt;br /&gt;
* OnNodeReferenceModified(vtkMRMLNodeReference *reference)&lt;br /&gt;
&lt;br /&gt;
By default those methods generate the following events:&lt;br /&gt;
* vtkMRMLNode::ReferenceAddedEvent&lt;br /&gt;
* vtkMRMLNode::ReferenceRemovedEvent&lt;br /&gt;
* vtkMRMLNode::ReferenceModifiedEvent&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: http://slicer.org/doc/html/classvtkMRMLNode-members.html&lt;br /&gt;
&lt;br /&gt;
Currently the following MRML nodes are implemented using MRML Node Reference API:&lt;br /&gt;
* vtkMRMLStorableNode&lt;br /&gt;
* vtkMRMLTransformableNode&lt;br /&gt;
* vtkMRMLDisplayableNode&lt;br /&gt;
&lt;br /&gt;
Other references to MRML nodes such as to vtkMRMLColorTableNode, 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>