Difference between revisions of "Documentation/Nightly/Developers/Tutorials/MigrationGuide/Slicer"

From Slicer Wiki
Jump to: navigation, search
Tag: 2017 source edit
Line 2: Line 2:
 
==Slicer backward incompatible changes==
 
==Slicer backward incompatible changes==
  
=== Slicer 5.0: API changes since 4.10 ===
+
===Slicer 5.0: API changes since 4.10===
  
* Removed protected method <tt>vtkMRMLModelDisplayableManager::FindPickedDisplayNodeFromMesh</tt>
+
*Removed protected method <tt>vtkMRMLModelDisplayableManager::FindPickedDisplayNodeFromMesh</tt>
  
==== Python 2 to Python 3 ====
+
====Python 2 to Python 3====
  
 
Slicer core has been updated to only support Python 3.
 
Slicer core has been updated to only support Python 3.
Line 16: Line 16:
 
Updates specific to extensions are discussed in [[Documentation/Nightly/Developers/Tutorials/MigrationGuide#Slicer_5.0:_Python2_to_Python3]]
 
Updates specific to extensions are discussed in [[Documentation/Nightly/Developers/Tutorials/MigrationGuide#Slicer_5.0:_Python2_to_Python3]]
  
==== Interactor styles ====
+
====Interactor styles====
  
 
Limitations of VTK widgets (editable points, lines, curves, etc.) prevented Slicer from having sophisticated user interaction in slice and 3D views. In Slicer5, we replaced VTK widgets with MRML widgets. These widgets are still VTK-based and somewhat similar to VTK widgets, but they operate directly on MRML nodes, they use direct method calls between widgets and their representation, and they use a more efficient and flexible event processing. Instead of hardcoding how viewers behave in response to interaction (mouse move, button click, keyboard, ...) events in an interactor style, all these events are translated to actions and performed in a MRML widget. Most modules are not expected to observe interactor events or styles directly, but if they did, then they may need to be updated accordingly.
 
Limitations of VTK widgets (editable points, lines, curves, etc.) prevented Slicer from having sophisticated user interaction in slice and 3D views. In Slicer5, we replaced VTK widgets with MRML widgets. These widgets are still VTK-based and somewhat similar to VTK widgets, but they operate directly on MRML nodes, they use direct method calls between widgets and their representation, and they use a more efficient and flexible event processing. Instead of hardcoding how viewers behave in response to interaction (mouse move, button click, keyboard, ...) events in an interactor style, all these events are translated to actions and performed in a MRML widget. Most modules are not expected to observe interactor events or styles directly, but if they did, then they may need to be updated accordingly.
  
* vtkSliceViewInteractorStyle renamed to vtkMRMLSliceDViewInteractorStyle to reflect that it uses MRML classes directly.
+
*vtkSliceViewInteractorStyle renamed to vtkMRMLSliceDViewInteractorStyle to reflect that it uses MRML classes directly.
* vtkThreeDViewInteractorStyle renamed to vtkMRMLThreeDViewInteractorStyle to reflect that it uses MRML classes directly.
+
*vtkThreeDViewInteractorStyle renamed to vtkMRMLThreeDViewInteractorStyle to reflect that it uses MRML classes directly.
  
==== slicer.util functions ====
+
====slicer.util functions====
  
* slicer.util.loadVolume (and other node load functions) now return the loaded node instead of a True/False flag. In case of an error, a RuntimeError exception is thrown.
+
*slicer.util.loadVolume (and other node load functions) now return the loaded node instead of a True/False flag. In case of an error, a RuntimeError exception is thrown.
** Old way of loading a node and get it in a variable: <code>volumeNode = slicer.util.loadVolume('path/to/volume.nrrd', returnNode=True)[1]</code>
+
**Old way of loading a node and get it in a variable: <code>volumeNode = slicer.util.loadVolume('path/to/volume.nrrd', returnNode=True)[1]</code>
** New way of loading a node and get it in a variable: <code>volumeNode = slicer.util.loadVolume('path/to/volume.nrrd')</code>
+
**New way of loading a node and get it in a variable: <code>volumeNode = slicer.util.loadVolume('path/to/volume.nrrd')</code>
  
==== Markups ====
+
====Markups====
  
* <tt>vtkCommand::Modified</tt> events are no longer invoked when control points are added/removed/modified to improve performance. Modules that need to know If a point position is modified need to add observers to <tt>vtkMRMLMarkupsNode::PointAddedEvent</tt>, <tt>vtkMRMLMarkupsNode::PointRemovedEvent</tt>, <tt>vtkMRMLMarkupsNode::PointModifiedEvent</tt> events. See example in [[Documentation/Nightly/ScriptRepository#Get_a_notification_if_a_markup_point_position_is_modified|script repository]].
+
*<tt>vtkCommand::Modified</tt> events are no longer invoked when control points are added/removed/modified to improve performance. Modules that need to know If a point position is modified need to add observers to <tt>vtkMRMLMarkupsNode::PointAddedEvent</tt>, <tt>vtkMRMLMarkupsNode::PointRemovedEvent</tt>, <tt>vtkMRMLMarkupsNode::PointModifiedEvent</tt> events. See example in [[Documentation/Nightly/ScriptRepository#Get_a_notification_if_a_markup_point_position_is_modified|script repository]].
* <tt>vtkMRMLMarkupsNode::MarkupAddedEvent</tt> is renamed to <tt>vtkMRMLMarkupsNode::PointAddedEvent</tt>. This is called even when preview point is created. Use <tt>vtkMRMLMarkupsNode::PointPositionDefinedEvent</tt> to get notification only when position of a point becomes defined (and not during preview).
+
*<tt>vtkMRMLMarkupsNode::MarkupAddedEvent</tt> is renamed to <tt>vtkMRMLMarkupsNode::PointAddedEvent</tt>. This is called even when preview point is created. Use <tt>vtkMRMLMarkupsNode::PointPositionDefinedEvent</tt> to get notification only when position of a point becomes defined (and not during preview).
* <tt>vtkMRMLMarkupsNode::MarkupRemovedEvent</tt> is renamed to <tt>vtkMRMLMarkupsNode::PointRemovedEvent</tt>. This is called even when preview point is removed. Use <tt>vtkMRMLMarkupsNode::PointPositionUndefinedEvent</tt> to get notification only when position of a point becomes undefined (and not during preview).
+
*<tt>vtkMRMLMarkupsNode::MarkupRemovedEvent</tt> is renamed to <tt>vtkMRMLMarkupsNode::PointRemovedEvent</tt>. This is called even when preview point is removed. Use <tt>vtkMRMLMarkupsNode::PointPositionUndefinedEvent</tt> to get notification only when position of a point becomes undefined (and not during preview).
* <tt>vtkMRMLMarkupsNode::NthMarkupModifiedEvent</tt> is replaced by <tt>vtkMRMLMarkupsNode::PointModifiedEvent</tt>
+
*<tt>vtkMRMLMarkupsNode::NthMarkupModifiedEvent</tt> is replaced by <tt>vtkMRMLMarkupsNode::PointModifiedEvent</tt>
* During placement of markups, a preview markup point is created. If number of already placed markup points needs to be determined then <code>GetNumberOfDefinedControlPoints()</code> method can be used.
+
*During placement of markups, a preview markup point is created. If number of already placed markup points needs to be determined then <code>GetNumberOfDefinedControlPoints()</code> method can be used.
* <tt>GetDefaultMarkups...()</tt> and <tt>SetDefaultMarkups...()</tt> methods are removed. Instead default display node can be accessed by <tt>GetDefaultMarkupsDisplayNode()</tt> method and default values can be get/set in that class.
+
*<tt>GetDefaultMarkups...()</tt> and <tt>SetDefaultMarkups...()</tt> methods are removed. Instead default display node can be accessed by <tt>GetDefaultMarkupsDisplayNode()</tt> method and default values can be get/set in that class.
* <tt>vtkMRMLMarkupsNode::GetNthMarkupSelected()</tt> is replaced by <tt>GetNthControlPointSelected()</tt>
+
*<tt>vtkMRMLMarkupsNode::GetNthMarkupSelected()</tt> is replaced by <tt>GetNthControlPointSelected()</tt>
* <tt>vtkMRMLMarkupsNode::PointPositionDefinedEvent</tt> event is added. This event is invoked whenever position is defined for a new point.
+
*<tt>vtkMRMLMarkupsNode::PointPositionDefinedEvent</tt> event is added. This event is invoked whenever position is defined for a new point.
* <tt>vtkMRMLMarkupsNode::PointPositionUndefinedEvent</tt> event is added. This event is invoked whenever point with defined position is removed (point is deleted or its position gets undefined).
+
*<tt>vtkMRMLMarkupsNode::PointPositionUndefinedEvent</tt> event is added. This event is invoked whenever point with defined position is removed (point is deleted or its position gets undefined).
* For more details, see [{{doxygen-class-url|vtkMRMLMarkupsNode}} vtkMRMLMarkupsNode]
+
*For more details, see [{{doxygen-class-url|vtkMRMLMarkupsNode}} vtkMRMLMarkupsNode]
  
==== Segmentations ====
+
====Segmentations====
  
 
Binary labelmap segmentations can now be represented as shared labelmaps.
 
Binary labelmap segmentations can now be represented as shared labelmaps.
Line 55: Line 55:
 
Before saving, the labelmaps will be collapsed into as few layers as possible.
 
Before saving, the labelmaps will be collapsed into as few layers as possible.
  
* seg.nrrd files now contain two additional attributes for each segment: SegmentX_LabelValue and SegmentX_Layer
+
*seg.nrrd files now contain two additional attributes for each segment: SegmentX_LabelValue and SegmentX_Layer
* The label value of a segment can be found using vtkSegment::GetLabelValue()
+
*The label value of a segment can be found using vtkSegment::GetLabelValue()
* Whether or not a segment is shared can be found using vtkSegmentation::IsSharedBinaryLabelmap()
+
*Whether or not a segment is shared can be found using vtkSegmentation::IsSharedBinaryLabelmap()
* The other segments sharing the same labelmap can be found using vtkSegmentation::GetSegmentIDsSharingBinaryLabelmapRepresentation()
+
*The other segments sharing the same labelmap can be found using vtkSegmentation::GetSegmentIDsSharingBinaryLabelmapRepresentation()
* Segment editor effects should generally use modifySelectedSegmentByLabelmap rather than SetBinaryLabelmapToSegment to manage layer separation
+
*Segment editor effects should generally use modifySelectedSegmentByLabelmap rather than SetBinaryLabelmapToSegment to manage layer separation
* Conversion rules now call PreConvert() and PostConvert() before and after conversion to perform pre and post processing steps on the segmentation as a whole
+
*Conversion rules now call PreConvert() and PostConvert() before and after conversion to perform pre and post processing steps on the segmentation as a whole
* The function signature for vtkSegmentationConverterRule::Convert now accepts a vtkSegment rather than two vtkDataObjects
+
*The function signature for vtkSegmentationConverterRule::Convert now accepts a vtkSegment rather than two vtkDataObjects
* slicer.util.arrayFromSegment has been deprecated. slicer.util.arrayFromSegmentBinaryLabelmap and slicer.util.arrayFromSegmentInternalBinaryLabelmap can be used instead
+
*slicer.util.arrayFromSegment has been deprecated. slicer.util.arrayFromSegmentBinaryLabelmap and slicer.util.arrayFromSegmentInternalBinaryLabelmap can be used instead
  
 
=====Erase the contents of a single segment=====
 
=====Erase the contents of a single segment=====
Line 122: Line 122:
 
See code example in [[Documentation/{{documentation/version}}/ScriptRepository#Export_model_nodes_from_segmentation_node|script repository]].
 
See code example in [[Documentation/{{documentation/version}}/ScriptRepository#Export_model_nodes_from_segmentation_node|script repository]].
  
==== Volume rendering ====
+
====Volume rendering====
  
 
vtkMRMLVolumeRenderingDisplayNode::SetAndObserveVolumeNodeID method was removed, as display node base class already maintains a pointer to the displayed (volume) node. To associate a volume display node with a volume node, call <pre>volumeNode->AddAndObserveDisplayNodeID(volumeRenderingDisplayNode->GetID());</pre> after both nodes are added to the scene.
 
vtkMRMLVolumeRenderingDisplayNode::SetAndObserveVolumeNodeID method was removed, as display node base class already maintains a pointer to the displayed (volume) node. To associate a volume display node with a volume node, call <pre>volumeNode->AddAndObserveDisplayNodeID(volumeRenderingDisplayNode->GetID());</pre> after both nodes are added to the scene.
  
=== Slicer 4.11: Variable CMAKE_DEFAULT_BUILD_TYPE renamed to Slicer_DEFAULT_BUILD_TYPE ===
+
 
 +
== 5.0 : Avoid typedef of anonymous structure ==
 +
<nowiki>https://reviews.llvm.org/D74103</nowiki>
 +
 
 +
Due to a recent (but retroactive) C++ rule change, only sufficiently
 +
 
 +
C-compatible classes are permitted to be given a typedef name for
 +
 
 +
linkage purposes. Add an enabled-by-default warning for these cases, and
 +
 
 +
rephrase our existing error for the case where we encounter the typedef
 +
 
 +
name for linkage after we've already computed and used a wrong linkage
 +
 
 +
in terms of the new rule.<blockquote>Slicer/Libs/MRML/Core/vtkMRMLTableStorageNode.h:95:17:</blockquote><blockquote>warning: anonymous non-C-compatible type given name for linkage purposes by typedef declaration; add a tag name here [-Wnon-c-typedef-for-linkage]</blockquote><blockquote>  typedef struct</blockquote><blockquote>                ^</blockquote><blockquote>                ColumnInfo</blockquote><blockquote>Slicer/Libs/MRML/Core/vtkMRMLTableStorageNode.h:99:5:</blockquote><blockquote>note: type is not C-compatible due to this default member initializer</blockquote><blockquote>    int ScalarType = VTK_STRING;</blockquote><blockquote><nowiki>    ^~~~~~~~~~~~~~</nowiki></blockquote><blockquote>Slicer/Libs/MRML/Core/vtkMRMLTableStorageNode.h:102:5:</blockquote><blockquote>note: type is given name 'ColumnInfo' for linkage purposes by this typedef declaration</blockquote><blockquote>  } ColumnInfo;</blockquote><blockquote>    ^</blockquote><blockquote>For consistency, Use 'using' to a named structure definintion for all </blockquote><blockquote>structures.</blockquote><br />
 +
===Slicer 4.11: Variable CMAKE_DEFAULT_BUILD_TYPE renamed to Slicer_DEFAULT_BUILD_TYPE===
  
 
Setting the default build type for single config generator may be done setting <tt>Slicer_DEFAULT_BUILD_TYPE</tt> instead of <tt>CMAKE_DEFAULT_BUILD_TYPE</tt>.
 
Setting the default build type for single config generator may be done setting <tt>Slicer_DEFAULT_BUILD_TYPE</tt> instead of <tt>CMAKE_DEFAULT_BUILD_TYPE</tt>.
Line 149: Line 164:
 
https://github.com/Slicer/Slicer/pull/4799
 
https://github.com/Slicer/Slicer/pull/4799
  
=== Slicer 4.11: teem python module renamed to vtkTeem, explicit import required ===
+
===Slicer 4.11: teem python module renamed to vtkTeem, explicit import required===
  
* Since the module provides VTK classes interfacing with "teem", the name is now representative of the class it contains.
+
*Since the module provides VTK classes interfacing with "teem", the name is now representative of the class it contains.
* <tt>vtkTeem</tt> classes are expected to be used by explicitly importing the module.
+
*<tt>vtkTeem</tt> classes are expected to be used by explicitly importing the module.
  
 
<b>Replace code like this:</b>
 
<b>Replace code like this:</b>
Line 174: Line 189:
 
</pre>
 
</pre>
  
=== Slicer 4.11: Display window/level (brightness/contrast) adjustment ===
+
===Slicer 4.11: Display window/level (brightness/contrast) adjustment===
* A new "Window/level" mouse interaction mode was introduced. Volume display window/level can only be changed if this mode is activated by clicking the corresponding button in the toolbar. The new mouse mode prevents accidental modification of volume window/level (when for example the user accidentally clicked too far from a markup) and it also allows more sophisticated window/level adjustments.
 
* New region-based auto window/level feature added: activate "Window/level" mouse mode and use Ctrl + left-click-and-drag to highlight a region and optimize window/level for that (pressing Escape or right-click cancels the operation).
 
* Auto window/level reset: activate "Window/level" mouse mode and double-click the left mouse button.
 
* Improved auto window/level algorithm to prevent too bright display of images. Window/level is set to display values between 0.1th and 99.9th percentile of gray levels. See details here: https://discourse.slicer.org/t/feedback-requested-how-to-improve-mouse-interaction-in-views/6420.
 
* Removed class <tt>vtkImageBimodalAnalysis</tt>
 
  
=== Slicer 4.10: Registration of runTest function done in ScriptedLoadableModule base class===
+
*A new "Window/level" mouse interaction mode was introduced. Volume display window/level can only be changed if this mode is activated by clicking the corresponding button in the toolbar. The new mouse mode prevents accidental modification of volume window/level (when for example the user accidentally clicked too far from a markup) and it also allows more sophisticated window/level adjustments.
 +
*New region-based auto window/level feature added: activate "Window/level" mouse mode and use Ctrl + left-click-and-drag to highlight a region and optimize window/level for that (pressing Escape or right-click cancels the operation).
 +
*Auto window/level reset: activate "Window/level" mouse mode and double-click the left mouse button.
 +
*Improved auto window/level algorithm to prevent too bright display of images. Window/level is set to display values between 0.1th and 99.9th percentile of gray levels. See details here: https://discourse.slicer.org/t/feedback-requested-how-to-improve-mouse-interaction-in-views/6420.
 +
*Removed class <tt>vtkImageBimodalAnalysis</tt>
 +
 
 +
===Slicer 4.10: Registration of runTest function done in ScriptedLoadableModule base class===
  
 
Following [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=27617 r27617]:
 
Following [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=27617 r27617]:
* the <code>ScriptedLoadableModule</code> class takes care of registering the <code>runTest</code> function.
+
 
* the <code>runTest</code> function expects <code>msec</code> keyword argument.
+
*the <code>ScriptedLoadableModule</code> class takes care of registering the <code>runTest</code> function.
 +
*the <code>runTest</code> function expects <code>msec</code> keyword argument.
  
 
<b>Error message similar to:</b>
 
<b>Error message similar to:</b>
Line 241: Line 258:
 
</pre>
 
</pre>
  
=== Slicer 4.9: Update of VTK version from 9.0 to 8.2 ===
+
===Slicer 4.9: Update of VTK version from 9.0 to 8.2===
  
 
Following [https://github.com/Kitware/VTK/commit/b703d78be3ffd8ae69c319afa0230097ff270f26 kitware/VTK@b703d78be], VTK has updated to use version number 8.2 instead of 9.0. This was discussed in on the VTK mailing list in http://vtk.1045678.n5.nabble.com/Discussion-OK-to-change-VTK-s-version-number-from-9-0-to-8-2-tt5748702.html
 
Following [https://github.com/Kitware/VTK/commit/b703d78be3ffd8ae69c319afa0230097ff270f26 kitware/VTK@b703d78be], VTK has updated to use version number 8.2 instead of 9.0. This was discussed in on the VTK mailing list in http://vtk.1045678.n5.nabble.com/Discussion-OK-to-change-VTK-s-version-number-from-9-0-to-8-2-tt5748702.html
  
 
At first, this VTK commit and its companion [https://github.com/Kitware/VTK/commit/8a00b357e84eec695bda049216f30f2b76d80855 kitware/VTK@8a00b357e] were both reverted from the [https://github.com/Slicer/VTK/ Slicer/VTK] fork. Then, since having the corresponding changes reverted in VTK was not possible, it was decided to also update Slicer. This was done in the following commits:
 
At first, this VTK commit and its companion [https://github.com/Kitware/VTK/commit/8a00b357e84eec695bda049216f30f2b76d80855 kitware/VTK@8a00b357e] were both reverted from the [https://github.com/Slicer/VTK/ Slicer/VTK] fork. Then, since having the corresponding changes reverted in VTK was not possible, it was decided to also update Slicer. This was done in the following commits:
* [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=27472 r27472]: COMP: Update c++ classes to support building against VTK >= 9 and VTK >= 8.2
+
 
* [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=27473 r27473]: COMP: Update VTK to include version change from 9.0 to 8.2. Fixes #4623
+
*[http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=27472 r27472]: COMP: Update c++ classes to support building against VTK >= 9 and VTK >= 8.2
 +
*[http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=27473 r27473]: COMP: Update VTK to include version change from 9.0 to 8.2. Fixes #4623
  
 
This means that code depending on VTK must also be updated to include similar fixes.
 
This means that code depending on VTK must also be updated to include similar fixes.
Line 266: Line 284:
  
  
 
+
===Slicer 4.9: ITK_LEGACY_REMOVE is now OFF===
=== Slicer 4.9: ITK_LEGACY_REMOVE is now OFF ===
 
 
In preparation to switch to ITK 5.0, we disable legacy functionality in ITK. This might affect some modules which rely on ITK. Take a look at [https://itk.org/migrationv4 ITK 4 migration guide] before [https://github.com/InsightSoftwareConsortium/ITK/blob/master/Documentation/ITK5MigrationGuide.md ITK 5 migration guide].
 
In preparation to switch to ITK 5.0, we disable legacy functionality in ITK. This might affect some modules which rely on ITK. Take a look at [https://itk.org/migrationv4 ITK 4 migration guide] before [https://github.com/InsightSoftwareConsortium/ITK/blob/master/Documentation/ITK5MigrationGuide.md ITK 5 migration guide].
  
=== Slicer 4.9: vtkMRMLPlotDataNode renamed to vtkMRMLPlotSeriesNode ===
+
===Slicer 4.9: vtkMRMLPlotDataNode renamed to vtkMRMLPlotSeriesNode===
 
Plotting was improved in [https://github.com/Slicer/Slicer/commit/082edc40c this commit]
 
Plotting was improved in [https://github.com/Slicer/Slicer/commit/082edc40c this commit]
  
Line 280: Line 297:
 
   vtkMRMLPlotSeriesNode
 
   vtkMRMLPlotSeriesNode
  
=== Slicer 4.9: CMake: Module MIDAS not available ===
+
===Slicer 4.9: CMake: Module MIDAS not available===
  
 
The test infrastructure of your project should be updated to use [https://cmake.org/cmake/help/latest/module/ExternalData.html ExternalData] built-in CMake module
 
The test infrastructure of your project should be updated to use [https://cmake.org/cmake/help/latest/module/ExternalData.html ExternalData] built-in CMake module
Line 314: Line 331:
 
of testing time.
 
of testing time.
  
=== Slicer 4.9: CMake: Module SlicerMacroCheckExternalProjectDependency not available ===
+
===Slicer 4.9: CMake: Module SlicerMacroCheckExternalProjectDependency not available===
  
 
Since the module was removed in [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=26992 r26992], consider updating
 
Since the module was removed in [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=26992 r26992], consider updating
 
your build system to use CMake module <code>ExternalProjectDependency</code>
 
your build system to use CMake module <code>ExternalProjectDependency</code>
  
=== Slicer 4.9: CMake: Module SlicerMacroEmptyExternalProject not available ===
+
===Slicer 4.9: CMake: Module SlicerMacroEmptyExternalProject not available===
  
 
Since the module was removed in [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=26991 r26991]
 
Since the module was removed in [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=26991 r26991]
Line 343: Line 360:
 
</pre>
 
</pre>
  
=== Slicer 4.9: CMake: Module SlicerBlockSetCMakeOSXVariables not available ===
+
===Slicer 4.9: CMake: Module SlicerBlockSetCMakeOSXVariables not available===
  
 
Since it was renamed to <tt>SlicerInitializeOSXVariables</tt> in [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=26982 r26982]
 
Since it was renamed to <tt>SlicerInitializeOSXVariables</tt> in [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=26982 r26982]
Line 359: Line 376:
 
</pre>
 
</pre>
  
=== Slicer 4.9: Application: isRelease() function not available ===
+
===Slicer 4.9: Application: isRelease() function not available===
  
 
See [[#Slicer_4.8:_Application:_isRelease.28.29_function_not_available_or_deprecated]]
 
See [[#Slicer_4.8:_Application:_isRelease.28.29_function_not_available_or_deprecated]]
  
=== Slicer 4.9: slicer.util.getNode() raises exception if node not found ===
+
===Slicer 4.9: slicer.util.getNode() raises exception if node not found===
  
 
If slicer.util.getNode() is called and the node is not found then instead of just returning None (Slicer 4.8 behavior), the method now raises a MRMLNodeNotFoundException. This makes code debugging easier (the error is reported when it happens), and in general more consistent with Python conventions.
 
If slicer.util.getNode() is called and the node is not found then instead of just returning None (Slicer 4.8 behavior), the method now raises a MRMLNodeNotFoundException. This makes code debugging easier (the error is reported when it happens), and in general more consistent with Python conventions.
Line 423: Line 440:
  
 
The approach had few issues:
 
The approach had few issues:
* the name of the variable was confusing
+
 
* identifying a "stable release" only from a source tree revision was not enough. Indeed the environment defining a "release" is the one found on the build machines used to generate the installer.
+
*the name of the variable was confusing
* nightly build are also considered as release
+
*identifying a "stable release" only from a source tree revision was not enough. Indeed the environment defining a "release" is the one found on the build machines used to generate the installer.
 +
*nightly build are also considered as release
  
 
To address this, the CMake variable <tt>Slicer_RELEASE_TYPE</tt> was introduced. As of 2017-10-04, it can be set to <tt>Experimental</tt>, <tt>Nightly</tt>
 
To address this, the CMake variable <tt>Slicer_RELEASE_TYPE</tt> was introduced. As of 2017-10-04, it can be set to <tt>Experimental</tt>, <tt>Nightly</tt>
Line 468: Line 486:
  
 
<b>References:</b>
 
<b>References:</b>
* Changed introduced in [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=24891 r24891]
+
 
 +
*Changed introduced in [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=24891 r24891]
  
 
<b>Error message similar to:</b>
 
<b>Error message similar to:</b>
Line 486: Line 505:
  
 
Removes lines and/or refactor code
 
Removes lines and/or refactor code
 
  
  
Line 567: Line 585:
  
 
<b>References:</b>
 
<b>References:</b>
* https://www.slicer.org/wiki/Documentation/Labs/Segmentations#vtkMRMLLabelMapVolumeNode_integration* http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=24291
+
 
 +
*https://www.slicer.org/wiki/Documentation/Labs/Segmentations#vtkMRMLLabelMapVolumeNode_integration* http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=24291
  
  
Line 595: Line 614:
 
<b>References:</b>
 
<b>References:</b>
  
* http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=21592
+
*http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=21592
* https://issues.slicer.org/view.php?id=2813
+
*https://issues.slicer.org/view.php?id=2813

Revision as of 12:35, 15 April 2020

Home < Documentation < Nightly < Developers < Tutorials < MigrationGuide < Slicer

Contents

Slicer backward incompatible changes

Slicer 5.0: API changes since 4.10

  • Removed protected method vtkMRMLModelDisplayableManager::FindPickedDisplayNodeFromMesh

Python 2 to Python 3

Slicer core has been updated to only support Python 3.

C++ classes and python scripts have been updated to use idioms and constructs only available in Python 3.

Update to python scripts have been done leveraging the CLI provided by https://python-future.org by (1) iteratively applying each one of the associates "fixes", (2) reviewing associated changes and (3) updating as needed.

Updates specific to extensions are discussed in Documentation/Nightly/Developers/Tutorials/MigrationGuide#Slicer_5.0:_Python2_to_Python3

Interactor styles

Limitations of VTK widgets (editable points, lines, curves, etc.) prevented Slicer from having sophisticated user interaction in slice and 3D views. In Slicer5, we replaced VTK widgets with MRML widgets. These widgets are still VTK-based and somewhat similar to VTK widgets, but they operate directly on MRML nodes, they use direct method calls between widgets and their representation, and they use a more efficient and flexible event processing. Instead of hardcoding how viewers behave in response to interaction (mouse move, button click, keyboard, ...) events in an interactor style, all these events are translated to actions and performed in a MRML widget. Most modules are not expected to observe interactor events or styles directly, but if they did, then they may need to be updated accordingly.

  • vtkSliceViewInteractorStyle renamed to vtkMRMLSliceDViewInteractorStyle to reflect that it uses MRML classes directly.
  • vtkThreeDViewInteractorStyle renamed to vtkMRMLThreeDViewInteractorStyle to reflect that it uses MRML classes directly.

slicer.util functions

  • slicer.util.loadVolume (and other node load functions) now return the loaded node instead of a True/False flag. In case of an error, a RuntimeError exception is thrown.
    • Old way of loading a node and get it in a variable: volumeNode = slicer.util.loadVolume('path/to/volume.nrrd', returnNode=True)[1]
    • New way of loading a node and get it in a variable: volumeNode = slicer.util.loadVolume('path/to/volume.nrrd')

Markups

  • vtkCommand::Modified events are no longer invoked when control points are added/removed/modified to improve performance. Modules that need to know If a point position is modified need to add observers to vtkMRMLMarkupsNode::PointAddedEvent, vtkMRMLMarkupsNode::PointRemovedEvent, vtkMRMLMarkupsNode::PointModifiedEvent events. See example in script repository.
  • vtkMRMLMarkupsNode::MarkupAddedEvent is renamed to vtkMRMLMarkupsNode::PointAddedEvent. This is called even when preview point is created. Use vtkMRMLMarkupsNode::PointPositionDefinedEvent to get notification only when position of a point becomes defined (and not during preview).
  • vtkMRMLMarkupsNode::MarkupRemovedEvent is renamed to vtkMRMLMarkupsNode::PointRemovedEvent. This is called even when preview point is removed. Use vtkMRMLMarkupsNode::PointPositionUndefinedEvent to get notification only when position of a point becomes undefined (and not during preview).
  • vtkMRMLMarkupsNode::NthMarkupModifiedEvent is replaced by vtkMRMLMarkupsNode::PointModifiedEvent
  • During placement of markups, a preview markup point is created. If number of already placed markup points needs to be determined then GetNumberOfDefinedControlPoints() method can be used.
  • GetDefaultMarkups...() and SetDefaultMarkups...() methods are removed. Instead default display node can be accessed by GetDefaultMarkupsDisplayNode() method and default values can be get/set in that class.
  • vtkMRMLMarkupsNode::GetNthMarkupSelected() is replaced by GetNthControlPointSelected()
  • vtkMRMLMarkupsNode::PointPositionDefinedEvent event is added. This event is invoked whenever position is defined for a new point.
  • vtkMRMLMarkupsNode::PointPositionUndefinedEvent event is added. This event is invoked whenever point with defined position is removed (point is deleted or its position gets undefined).
  • For more details, see vtkMRMLMarkupsNode

Segmentations

Binary labelmap segmentations can now be represented as shared labelmaps. The previous implementation of binary labelmaps was performance intensive as each labelmap was represented using a separate vtkDataObject. Visualizing and editing segmentations that contained a large number of segments could cause performance issues, due to the large number of vtkActors required, as well as calculating masks and overwriting other segments when editing.

By default, newly created segments will now be contained on the same layer. Segments will only be separated into multiple layers if the user creates an overlapping segment when editing.

Segments are now saved as a 4D volume with shared 3D layers. For a segmentation that only uses one layer, the resulting image is a 3D volume. Before saving, the labelmaps will be collapsed into as few layers as possible.

  • seg.nrrd files now contain two additional attributes for each segment: SegmentX_LabelValue and SegmentX_Layer
  • The label value of a segment can be found using vtkSegment::GetLabelValue()
  • Whether or not a segment is shared can be found using vtkSegmentation::IsSharedBinaryLabelmap()
  • The other segments sharing the same labelmap can be found using vtkSegmentation::GetSegmentIDsSharingBinaryLabelmapRepresentation()
  • Segment editor effects should generally use modifySelectedSegmentByLabelmap rather than SetBinaryLabelmapToSegment to manage layer separation
  • Conversion rules now call PreConvert() and PostConvert() before and after conversion to perform pre and post processing steps on the segmentation as a whole
  • The function signature for vtkSegmentationConverterRule::Convert now accepts a vtkSegment rather than two vtkDataObjects
  • slicer.util.arrayFromSegment has been deprecated. slicer.util.arrayFromSegmentBinaryLabelmap and slicer.util.arrayFromSegmentInternalBinaryLabelmap can be used instead
Erase the contents of a single segment
segmentation = segmentationNode.GetSegmentation()
segmentation.ClearSegment(segmentId)


Move a segment from a shared labelmap to a separate layer
segmentation = segmentationNode.GetSegmentation()
segmentation.SeparateSegmentLabelmap(segmentId)
Combine all binary labelmaps to as few layers as possible
segmentation = segmentationNode.GetSegmentation()
segmentation.CollapseBinaryLabelmaps(forceToSingleLayer=false)

Get a read-only labelmap for a single segment:

labelmap = slicer.vtkOrientedImageData()
segmentationNode.GetBinaryLabelmapRepresentation(segmentId, labelmap)

(similarly, use GetClosedSurfaceRepresentation with an additional vtk.vtkPolyData parameter to get a read-only surface mesh)

or

labelmapNumpyArray = slicer.util.arrayFromSegmentBinaryLabelmap(segmentationNode, segmentId)
Get a modifiable shared labelmap
labelmap = slicer.vtkOrientedImageData()
segmentationNode.GetBinaryLabelmapInternalRepresentation(segmentId, labelmap)

(similarly, use GetClosedSurfaceInternalRepresentation to get a modifiable surface mesh)

or

labelmapNumpyArray = slicer.util.arrayFromSegmentInternalBinaryLabelmap(segmentationNode, segmentId)
Export segments to models

Model hierarchies no longer exist in Slicer5, but instead various kinds of hierarchies are now replaced by "subject hierarchy", which can accommodate any node types in a single hierarchy. Accordingly, `ExportSegmentsToModelHierarchy`, `ExportAllSegmentsToModelHierarchy`, etc. are replaced by `ExportSegmentsToModels`, `ExportAllSegmentsToModels`, which take a subject hierarchy folder item ID as input. Documentation/Nightly See code example in script repository.

Volume rendering

vtkMRMLVolumeRenderingDisplayNode::SetAndObserveVolumeNodeID method was removed, as display node base class already maintains a pointer to the displayed (volume) node. To associate a volume display node with a volume node, call

volumeNode->AddAndObserveDisplayNodeID(volumeRenderingDisplayNode->GetID());

after both nodes are added to the scene.


5.0 : Avoid typedef of anonymous structure

https://reviews.llvm.org/D74103

Due to a recent (but retroactive) C++ rule change, only sufficiently

C-compatible classes are permitted to be given a typedef name for

linkage purposes. Add an enabled-by-default warning for these cases, and

rephrase our existing error for the case where we encounter the typedef

name for linkage after we've already computed and used a wrong linkage

in terms of the new rule.

Slicer/Libs/MRML/Core/vtkMRMLTableStorageNode.h:95:17:

warning: anonymous non-C-compatible type given name for linkage purposes by typedef declaration; add a tag name here [-Wnon-c-typedef-for-linkage]

  typedef struct

                ^

                ColumnInfo

Slicer/Libs/MRML/Core/vtkMRMLTableStorageNode.h:99:5:

note: type is not C-compatible due to this default member initializer

    int ScalarType = VTK_STRING;

    ^~~~~~~~~~~~~~

Slicer/Libs/MRML/Core/vtkMRMLTableStorageNode.h:102:5:

note: type is given name 'ColumnInfo' for linkage purposes by this typedef declaration

  } ColumnInfo;

    ^

For consistency, Use 'using' to a named structure definintion for all

structures.


Slicer 4.11: Variable CMAKE_DEFAULT_BUILD_TYPE renamed to Slicer_DEFAULT_BUILD_TYPE

Setting the default build type for single config generator may be done setting Slicer_DEFAULT_BUILD_TYPE instead of CMAKE_DEFAULT_BUILD_TYPE.

Error message similar to:

  CMake Error:
     Generator

       Visual Studio 15 2017

     does not support variable

       CMAKE_DEFAULT_BUILD_TYPE

     but it has been specified.

References:

https://github.com/Slicer/Slicer/pull/4799

Slicer 4.11: teem python module renamed to vtkTeem, explicit import required

  • Since the module provides VTK classes interfacing with "teem", the name is now representative of the class it contains.
  • vtkTeem classes are expected to be used by explicitly importing the module.

Replace code like this:

import teem

class CalculateTensorScalars(object):
  def __init__(self):
    self.dti_math = teem.vtkDiffusionTensorMathematics()

By this:

import vtkTeem

class CalculateTensorScalars(object):
  def __init__(self):
    self.dti_math = vtkTeem.vtkDiffusionTensorMathematics()

Slicer 4.11: Display window/level (brightness/contrast) adjustment

  • A new "Window/level" mouse interaction mode was introduced. Volume display window/level can only be changed if this mode is activated by clicking the corresponding button in the toolbar. The new mouse mode prevents accidental modification of volume window/level (when for example the user accidentally clicked too far from a markup) and it also allows more sophisticated window/level adjustments.
  • New region-based auto window/level feature added: activate "Window/level" mouse mode and use Ctrl + left-click-and-drag to highlight a region and optimize window/level for that (pressing Escape or right-click cancels the operation).
  • Auto window/level reset: activate "Window/level" mouse mode and double-click the left mouse button.
  • Improved auto window/level algorithm to prevent too bright display of images. Window/level is set to display values between 0.1th and 99.9th percentile of gray levels. See details here: https://discourse.slicer.org/t/feedback-requested-how-to-improve-mouse-interaction-in-views/6420.
  • Removed class vtkImageBimodalAnalysis

Slicer 4.10: Registration of runTest function done in ScriptedLoadableModule base class

Following r27617:

  • the ScriptedLoadableModule class takes care of registering the runTest function.
  • the runTest function expects msec keyword argument.

Error message similar to:

Traceback (most recent call last):
  File "/path/to/Slicer-SuperBuild/Slicer-build/bin/Python/slicer/ScriptedLoadableModule.py", line 205, in onReloadAndTest
    test(msec=int(slicer.app.userSettings().value("Developer/SelfTestDisplayMessageDelay")), **kwargs)
TypeError: runTest() got an unexpected keyword argument 'msec'
Reload and Test: Exception!

runTest() got an unexpected keyword argument 'msec'

Replace code like this:

class sceneImport2428(ScriptedLoadableModule):
  [...]
  def __init__(self, parent):
    ScriptedLoadableModule.__init__(self, parent)
    parent.title = "..."
    [...]
    parent.acknowledgementText = "..."
    self.parent = parent 	 
	  	 
    # Add this test to the SelfTest module's list for discovery when the module 	 
    # is created.  Since this module may be discovered before SelfTests itself, 	 
    # create the list if it doesn't already exist. 	 
    try: 	 
      slicer.selfTests 	 
    except AttributeError: 	 
      slicer.selfTests = {} 	 
    slicer.selfTests['sceneImport2428'] = self.runTest 	 
 
  def runTest(self): 	 
    tester = sceneImport2428Test() 	 
    tester.runTest()

  [...]

By this:

class sceneImport2428(ScriptedLoadableModule):
  [...]
  def __init__(self, parent):
    ScriptedLoadableModule.__init__(self, parent)
    parent.title = "..."
    [...]
    parent.acknowledgementText = "..."

  [...]

Slicer 4.9: Update of VTK version from 9.0 to 8.2

Following kitware/VTK@b703d78be, VTK has updated to use version number 8.2 instead of 9.0. This was discussed in on the VTK mailing list in http://vtk.1045678.n5.nabble.com/Discussion-OK-to-change-VTK-s-version-number-from-9-0-to-8-2-tt5748702.html

At first, this VTK commit and its companion kitware/VTK@8a00b357e were both reverted from the Slicer/VTK fork. Then, since having the corresponding changes reverted in VTK was not possible, it was decided to also update Slicer. This was done in the following commits:

  • r27472: COMP: Update c++ classes to support building against VTK >= 9 and VTK >= 8.2
  • r27473: COMP: Update VTK to include version change from 9.0 to 8.2. Fixes #4623

This means that code depending on VTK must also be updated to include similar fixes.

Replace this:

 #if VTK_MAJOR_VERSION >= 9

By this:

 #if VTK_MAJOR_VERSION >= 9 || (VTK_MAJOR_VERSION >= 8 && VTK_MINOR_VERSION >= 2)

and

Replace this:

 #if VTK_MAJOR_VERSION < 9

By this:

 #if VTK_MAJOR_VERSION <= 7 || (VTK_MAJOR_VERSION <= 8 && VTK_MINOR_VERSION <= 1)


Slicer 4.9: ITK_LEGACY_REMOVE is now OFF

In preparation to switch to ITK 5.0, we disable legacy functionality in ITK. This might affect some modules which rely on ITK. Take a look at ITK 4 migration guide before ITK 5 migration guide.

Slicer 4.9: vtkMRMLPlotDataNode renamed to vtkMRMLPlotSeriesNode

Plotting was improved in this commit

Replace this:

 vtkMRMLPlotDataNode

By this:

 vtkMRMLPlotSeriesNode

Slicer 4.9: CMake: Module MIDAS not available

The test infrastructure of your project should be updated to use ExternalData built-in CMake module instead of the specific MIDAS module.

See EMSegment commit r17150 for an example of transition.

This means that instead of using midas_add_test with the MIDAS{path/to/file.ext.md5} syntax for addressing the test data, the function ExternalData_add_target is used by specifying both DATA{path/to/file.ext} and a download target name.

Replace this:

 midas_add_test(NAME test1 COMMAND ...)
 midas_add_test(NAME test2 COMMAND ...)

By this:

 ExternalData_add_test(EMSegmentData NAME test1 COMMAND ...)
 ExternalData_add_test(EMSegmentData NAME test2 COMMAND ...)
 
 [...]
 
 ExternalData_add_target(EMSegmentData)


A key difference with the former approaches is that instead of adding two tests (one named <testName>_fetchData to downoad the data and one running the test command), only one test is added but a common download target is added at the end using ExternalData_add_target function.

This means that test data can now be downloaded in parallel (and cached) at build time instead of testing time.

Slicer 4.9: CMake: Module SlicerMacroCheckExternalProjectDependency not available

Since the module was removed in r26992, consider updating your build system to use CMake module ExternalProjectDependency

Slicer 4.9: CMake: Module SlicerMacroEmptyExternalProject not available

Since the module was removed in r26991

Replace this:

include(SlicerMacroEmptyExternalProject)

[...]

SlicerMacroEmptyExternalProject("${proj}" "${${proj}_DEPENDENCIES}")

By this:

include(ExternalProjectDependency)

[...]

ExternalProject_Add_Empty(${proj} DEPENDS ${${proj}_DEPENDENCIES})

Slicer 4.9: CMake: Module SlicerBlockSetCMakeOSXVariables not available

Since it was renamed to SlicerInitializeOSXVariables in r26982

Replace this:

include(SlicerBlockSetCMakeOSXVariables)

By this:

include(SlicerInitializeOSXVariables)

Slicer 4.9: Application: isRelease() function not available

See #Slicer_4.8:_Application:_isRelease.28.29_function_not_available_or_deprecated

Slicer 4.9: slicer.util.getNode() raises exception if node not found

If slicer.util.getNode() is called and the node is not found then instead of just returning None (Slicer 4.8 behavior), the method now raises a MRMLNodeNotFoundException. This makes code debugging easier (the error is reported when it happens), and in general more consistent with Python conventions.

How to update existing code:

It is advisable to only use slicer.util.getNode in tests, or interactively in the Python console, as its behavior is somewhat unpredictable (it may either found a node by name or ID, and result of wildcard search is even less deterministic). In general, it is recommended to use the MRML scene's GetFirstNodeByName and GetNodeByID methods instead.

Replace this:

n = slicer.util.getNode(nodeNameOrID)

By one of these:

If node is to be found by name:

  n = slicer.mrmlScene.GetFirstNodeByName(nodeName)

If node is to be found by ID:

  n = slicer.mrmlScene.GetNodeByID(nodeID)

If node is to be found by name or ID (slower, less predictable, recommended for testing only):

try:
  n = slicer.util.getNode(nodeNameOrID)
except slicer.util.MRMLNodeNotFoundException:
  n = None

More information: https://github.com/Slicer/Slicer/commit/b63484af1b1b413f35396f8f7efb73e870448bd4

Slicer 4.8: Application: isRelease() function not available or deprecated

Error message similar to:

   Missing/deprecated qSlicerCoreApplication::isRelease()

or

   Missing/deprecated slicer.app.isRelease()


Solution:

Use qSlicerCoreApplication::releaseType() == "Stable"

Summary:

Prior to r26420, the variable Slicer_VERSION_TWEAK was used to check if a "stable release" was built. The variable value was set by updating the sources and defining the variable to an integer greater or equal to 0. In other word, if the variable evaluated to an empty string, a nighty or experimental build was being done, if it evaluated to an integer, a stable release build was being done.

The approach had few issues:

  • the name of the variable was confusing
  • identifying a "stable release" only from a source tree revision was not enough. Indeed the environment defining a "release" is the one found on the build machines used to generate the installer.
  • nightly build are also considered as release

To address this, the CMake variable Slicer_RELEASE_TYPE was introduced. As of 2017-10-04, it can be set to Experimental, Nightly or Stable with Experimental being the value hard-coded in the source.

Identifying a build as "stable" is now explicitly done by setting Slicer_RELEASE_TYPE to Stable at configure time.

Also, since the concept of release types was introduced, the function isRelease() has been removed in favor of releaseType().

References:

https://github.com/Slicer/Slicer/pull/354

Slicer Python Module: modulewidget and others removed.

Summary Python classes formerly in "slicer.moduledm", "slicer.modulelogic", "slicer.modulemrml" and "slicer.modulewidget" are now directly available in the slicer module.

See example of change here.

Rational:

See comments in commit messages referenced blow.

References:

https://github.com/Slicer/Slicer/commit/628f83fe7a6f4e0710e306bcaf7c04b9e3e5e6bd

https://github.com/Slicer/Slicer/commit/9cb5668fde1abc8f0430a91ca37fc29277ceeb4e

MRML: Slicer 4.6: Moved up vtkMRMLStorableNode in the MRML node hierarchy.

Rational:

vtkMRMLStorableNode is not a children of vtkMRMLTransformable node anymore, but directly a children of vtkMRMLNode.

This allows making a node storable without requiring it to be also transformable. It is important for several node types (color maps, tables, etc), which require separate storage node but are not transformable.

References:

Error message similar to:

   /tmp/LongitudinalPETCT/MRML/vtkMRMLLongitudinalPETCTStudyNode.cxx: In member function ‘void vtkMRMLLongitudinalPETCTStudyNode::ObserveRegistrationTransform(bool)’:
   /tmp/LongitudinalPETCT/MRML/vtkMRMLLongitudinalPETCTStudyNode.cxx:478:28: error: ‘class vtkMRMLVolumePropertyNode’ has no member named ‘GetParentTransformNode’
                  && propNode->GetParentTransformNode()
                               ^
   /tmp/LongitudinalPETCT/MRML/vtkMRMLLongitudinalPETCTStudyNode.cxx:480:23: error: ‘class vtkMRMLVolumePropertyNode’ has no member named ‘SetAndObserveTransformNodeID’
                propNode->SetAndObserveTransformNodeID(
                          ^
   /tmp/LongitudinalPETCT/MRML/vtkMRMLLongitudinalPETCTStudyNode.cxx:503:23: error: ‘class vtkMRMLVolumePropertyNode’ has no member named ‘SetAndObserveTransformNodeID’
                propNode->SetAndObserveTransformNodeID(NULL);
                          ^

Solution:

Removes lines and/or refactor code


MRML: Slicer 4.5: Introduction of vtkMRMLLabelMapVolumeNode

Rational:

Before vtkMRMLScalarVolumeNode was used for both scalar and label map volumes and the LabelMap custom MRML node attribute was used for distinguishing between them (0=scalar; 1=label map volume).

This made conversion between labelmap/scalar volumes very easy but made it difficult to customize behavior, display, processing of segmentation information.

Now a new vtkMRMLLabelMapVolumeNode class is used for storing segmentation information (still using vtkMRMLScalarVolume used as base class for backward compatibility; but in the future the base class may be changed to reflect that segmentation can be represented in various ways, not just as volumes).

Error message similar to:

 error: ‘class vtkMRMLScalarVolumeNode’ has no member named ‘SetLabelMap’
    outputVolumeNode->SetLabelMap(1);
                      ^

Solution (part1: down cast to vtkMRMLLabelMapVolumeNode, remove call to SetLabelMap)

Replace lines like:

    vtkMRMLNode* outputNode = d->OutputLabelVolumeMRMLNodeComboBox->currentNode();
    vtkMRMLScalarVolumeNode* outputVolumeNode = vtkMRMLScalarVolumeNode::SafeDownCast(outputNode);
    [...]
    outputVolumeNode->SetLabelMap(1);


with:

    vtkMRMLLabelMapVolumeNode* outputVolumeNode =
      vtkMRMLLabelMapVolumeNode::SafeDownCast(d->OutputLabelVolumeMRMLNodeComboBox->currentNode());
    [...]


Solution (part2: Update UI file):

Replace lines like:

 <widget class="qMRMLNodeComboBox" name="InputLabelVolumeMRMLNodeComboBox">
  <property name="nodeTypes">
   <stringlist>
    <string>vtkMRMLScalarVolumeNode</string>
   </stringlist>
  </property>
  [...]
 </widget>

with:

 <widget class="qMRMLNodeComboBox" name="InputLabelVolumeMRMLNodeComboBox">
  <property name="nodeTypes">
   <stringlist>
    <string>vtkMRMLLabelMapVolumeNode</string>      <------------- Update Here
   </stringlist>
  </property>
  [...]
 </widget>


Solution (part3: Update node selector configuration):

Replace lines like:

 nodeSelector.setNodeTypes(QStringList("vtkMRMLScalarVolumeNode"));
 nodeSelector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap", "1");

with:

 nodeSelector.setNodeTypes(QStringList("vtkMRMLLabelMapVolumeNode"));


References:


CLI: Slicer 4.3: Add ITKFactoryRegistration library centralizing ITK IO factory registration

Rational:

 Linking against ITKFactoryRegistration ensures that ITK IO factory are properly registered on all supported platforms.

Error message similar to:

 Undefined symbols for architecture x86_64:
 "itk::itkFactoryRegistration()", referenced from:
 _main in ImageMakerTest.cxx.o
 ld: symbol(s) not found for architecture x86_64

Solution:

Replace lines like:

 target_link_libraries(${CLP}Test ${CLP}Lib)

with:

 target_link_libraries(${CLP}Test ${CLP}Lib ${SlicerExecutionModel_EXTRA_EXECUTABLE_TARGET_LIBRARIES})

References: