Difference between revisions of "Documentation/Nightly/Modules/VolumeRendering"

From Slicer Wiki
Jump to: navigation, search
Tag: 2017 source edit
(Replaced content with "<noinclude>{{documentation/versioncheck}} </noinclude> {{documentation/banner | text = [https://slicer.readthedocs.io/en/latest/user_guide/modules/volumerendering.html T...")
Tags: 2017 source edit, Replaced
 
Line 1: Line 1:
<noinclude>{{documentation/versioncheck}}</noinclude>
+
<noinclude>{{documentation/versioncheck}}
<!-- ---------------------------- -->
+
</noinclude>
{{documentation/{{documentation/version}}/module-header}}
 
<!-- ---------------------------- -->
 
  
<!-- ---------------------------- -->
+
{{documentation/banner
{{documentation/{{documentation/version}}/module-section|Introduction and Acknowledgements}}
+
| text  = [https://slicer.readthedocs.io/en/latest/user_guide/modules/volumerendering.html This page has been moved to read-the-docs.]
{{documentation/{{documentation/version}}/module-introduction-start|{{documentation/modulename}} }}
+
| background-color = 8FBC8F }}
{{documentation/{{documentation/version}}/module-introduction-row}}
 
{{documentation/{{documentation/version}}/module-acknowledgements}}
 
: '''Contact:''' Julien Finet, <email>julien.finet@kitware.com</email><br>
 
{{documentation/{{documentation/version}}/module-introduction-row}}
 
{{documentation/{{documentation/version}}/module-introduction-logo-gallery
 
|{{collaborator|logo|kitware}}|{{collaborator|longname|kitware}}
 
|{{collaborator|logo|isomics}}|{{collaborator|longname|isomics}}
 
|{{collaborator|logo|spl}}|{{collaborator|longname|spl}}
 
|{{collaborator|logo|namic}}|{{collaborator|longname|namic}}
 
}}
 
{{documentation/{{documentation/version}}/module-introduction-end}}
 
 
 
<!-- ---------------------------- -->
 
{{documentation/{{documentation/version}}/module-section|Module Description}}
 
{{documentation/{{documentation/version}}/module-description}}
 
Only single-component scalar volumes can be used for volume rendering. [[Documentation/{{documentation/version}}/Modules/VectorToScalarVolume|Vector to Scalar Volume]] module can convert vector volume to scalar volume.
 
 
 
<!-- ---------------------------- -->
 
{{documentation/{{documentation/version}}/module-section|Use Cases}}
 
<gallery widths="200px" perrow="4">
 
Image:Tumor-Volume-Rendering-PostGad-2011.png|Tumor post pad <br><small>(preset: MR-Default)</small>
 
Image:Modules-VolumeRendering-LabelMap.png|Segmented (labelmap) knee<br><small>(interpolation: nearest neighbor, shading: off)</small>
 
Image:QSlicerVolumeRendering-default.png|Default view of the module.<br><small>Inputs and Advanced... are hidden by default</small>
 
Image:VolumeRenderingSettings.png|Volume Rendering settings<br><small>''Edit -> Application Settings -> Volume Rendering settings''</small>
 
</gallery>
 
 
 
<!-- ---------------------------- -->
 
{{documentation/{{documentation/version}}/module-section|Tutorials}}
 
 
 
Tutorial about [[Slicer3:Volume_Rendering_Tutorials|using the volume rendering module]].
 
 
 
===Labelmap rendering===
 
[[File:Modules-VolumeRendering-LabelMap.png|right|500px]]
 
A labelmap is a volume, and as such it can be visualized using the Volume Rendering method. It can be an alternative from [[Documentation/{{documentation/version}}/Modules/ModelMaker|creating surface models]] from a labelmap.
 
# First you need to load your labelmap.
 
## Make sure you check the "Labelmap" check box at load time.
 
## Make sure the labelmap is a Unsigned Char image, not Unsigned/Signed Short, Int or Long. If needed, you can [[Documentation/{{documentation/version}}/Modules/CastScalarVolume| cast]] the labelmap to UCHAR.
 
# Open the Volume Rendering module
 
## Click on the eye to start the Volume Rendering.
 
# To turn off shading:
 
## Go to Advanced../Volume Properties/Advanced group box and uncheck the "Shade" checkbox
 
# To turn on/off a specific label:
 
## Go to the Advanced.../Volume Properties/Scalar Opacity Mapping group box
 
## Toggle down the '>>' button to show the Opacity controls.
 
## Browse each label with the "Point:" spinbox. When the spinbox shows the current label value,
 
## Set the Opacity spinbox value to 0.0/1.0 to hide/show the label.
 
 
 
===Render 2 volumes in 2 views===
 
[[File:DualVR.png|right|500px]]
 
# [[Documentation/{{documentation/version}}/SlicerApplication/MainApplicationGUI#Layouts|Change layout]] into "Dual 3D"
 
# [[Documentation/{{documentation/version}}/SlicerApplication/LoadingData|Load]] your 2 volumes
 
# [[Documentation/{{documentation/version}}/SlicerApplication/MainApplicationGUI#Module_Selection_.26_Navigation|Open]] Volume Rendering module
 
# For the first volume:
 
## Open the "Inputs" section
 
## Uncheck "View2". Only "View1" should be checked.
 
## Don't click the "eye" icon yet.
 
# Select the second volume.
 
## Check "View2".
 
## Uncheck "View1". Only "View2" should be checked.
 
## Click the eye icon for the VR to show up in View2
 
# Select the 1st volume
 
## Click the eye icon for the VR to show up in View1
 
 
 
<!-- ---------------------------- -->
 
{{documentation/{{documentation/version}}/module-section|Panels and their use}}
 
[[File:VolumeRenderingPanel.png|right|]]
 
{{documentation/{{documentation/version}}/module-parametersdescription}}
 
 
 
<!-- ---------------------------- -->
 
{{documentation/{{documentation/version}}/module-section|Similar Modules}}
 
[[Documentation/{{documentation/version}}/Modules/Volumes|Volumes]]
 
 
 
<!-- ---------------------------- -->
 
{{documentation/{{documentation/version}}/module-section|References}}
 
Publications related to this module go here. Links to pdfs would be useful.
 
For extensions: link to the source code repository and additional documentation
 
 
 
 
 
<!-- ---------------------------- -->
 
{{documentation/{{documentation/version}}/module-section|Information for Developers}}
 
 
 
===Key [[Documentation/{{documentation/version}}/Developers/MRML|nodes]] and classes===
 
* [http://slicer.org/doc/html/classvtkMRMLVolumeRenderingDisplayNode.html vtkMRMLVolumeRenderingDisplayNode] controls the volume rendering properties. Each volume rendering technique has its own subclass.
 
* [http://slicer.org/doc/html/classvtkSlicerVolumeRenderingLogic.html vtkSlicerVolumeRenderingLogic] contains utility functions
 
* [http://slicer.org/doc/html/classvtkMRMLScalarVolumeNode.html vtkMRMLScalarVolumeNode] contains the volume itself
 
* [http://slicer.org/doc/html/classvtkMRMLVolumePropertyNode.html vtkMRMLVolumePropertyNode] points to the transfer functions
 
* [http://slicer.org/doc/html/classvtkMRMLAnnotationROINode.html vtkMRMLAnnotationROINode] controls the clipping planes
 
* [http://slicer.org/doc/html/classvtkMRMLVolumeRenderingDisplayableManager.html vtkMRMLVolumeRenderingDisplayableManager] adds the volume renderings into the views
 
 
 
=== Format of Volume Property (.vp) file ===
 
 
 
<pre>
 
1 => interpolation type
 
1 => shading enabled
 
0.9 => diffuse reflection
 
0.1 => ambient reflection
 
0.2 => specular reflection
 
10 => specular reflection power
 
14 -3024 0 -86.9767 0 45.3791 0.169643 139.919 0.589286 347.907 0.607143 1224.16 0.607143 3071 0.616071 => scalar opacity transfer function (total number of values, each control point is defined by a pair of values: intensity and opacity)
 
4 0 1 255 1 => gradient opacity transfer function (total number of values, each control point is defined by a pair of values: intensity gradient and opacity)
 
28 -3024 0 0 0 -86.9767 0 0.25098 1 45.3791 1 0 0 139.919 1 0.894893 0.894893 347.907 1 1 0.25098 1224.16 1 1 1 3071 0.827451 0.658824 1 => color transfer function (total number of values, each control point is defined by 4 of values: intensity and R, G, B color components)
 
</pre>
 
 
 
===How Tos===
 
====How to programmatically volume render your volume node====
 
{|width = "100%"
 
! style="border-bottom: 1px solid darkgrey;font-size: 75%;"|C++
 
! style="border-bottom: 1px solid darkgrey;font-size: 75%;"|Python
 
|-
 
| valign="top" |
 
qSlicerAbstractCoreModule* volumeRenderingModule =
 
  qSlicerCoreApplication::application()->moduleManager()->module("VolumeRendering");
 
vtkSlicerVolumeRenderingLogic* volumeRenderingLogic =
 
  volumeRenderingModule ? vtkSlicerVolumeRenderingLogic::SafeDownCast(volumeRenderingModule->logic()) : 0;
 
vtkMRMLVolumeNode* volumeNode = mrmlScene->GetNodeByID('vtkMRMLScalarVolumeNode1');
 
if (volumeRenderingLogic)
 
  {
 
  vtkSmartPointer<vtkMRMLVolumeRenderingDisplayNode> displayNode =
 
    vtkSmartPointer<vtkMRMLVolumeRenderingDisplayNode>::Take(volumeRenderingLogic->CreateVolumeRenderingDisplayNode());
 
  mrmlScene->AddNode(displayNode);
 
  volumeNode->AddAndObserveDisplayNodeID(displayNode->GetID());
 
  volumeRenderingLogic->UpdateDisplayNodeFromVolumeNode(displayNode, volumeNode);
 
  }
 
See [[Documentation/{{documentation/version}}/Developers/Tutorials/CreateLoadableModule#Dependency_between_modules|here]] for more about volume dependency.
 
| valign="top" |
 
>>> logic = slicer.modules.volumerendering.logic()
 
>>> volumeNode = slicer.mrmlScene.GetNodeByID('vtkMRMLScalarVolumeNode1')
 
>>> displayNode = logic.CreateVolumeRenderingDisplayNode()
 
>>> displayNode.UnRegister(logic)
 
>>> slicer.mrmlScene.AddNode(displayNode)
 
>>> volumeNode.AddAndObserveDisplayNodeID(displayNode.GetID())
 
>>> logic.UpdateDisplayNodeFromVolumeNode(displayNode, volumeNode)
 
|}
 
 
 
====How to programmatically apply a custom color/opacity transfer function====
 
{|width = "100%"
 
! style="border-bottom: 1px solid darkgrey;font-size: 75%;"|C++
 
! style="border-bottom: 1px solid darkgrey;font-size: 75%;"|Python
 
|-
 
| valign="top" |
 
vtkColorTransferFunction* colors = ...
 
vtkPiecewiseFunction* opacities = ...
 
vtkMRMLVolumeRenderingDisplayNode* displayNode = ...
 
vtkMRMLVolumePropertyNode* propertyNode = displayNode->GetVolumePropertyNode();
 
propertyNode->SetColor(colorTransferFunction);
 
propertyNode->SetScalarOpacity(opacities);
 
// optionally set the gradients opacities with SetGradientOpacity
 
The logic has utility functions to help you create those transfer functions:
 
volumeRenderingLogic->[http://slicer.org/doc/html/classvtkSlicerVolumeRenderingLogic.html#ab8dbda38ad81b39b445b01e1bf8c7a86 SetWindowLevelToVolumeProp](...)
 
volumeRenderingLogic->[http://slicer.org/doc/html/classvtkSlicerVolumeRenderingLogic.html#a1dcbe614493f3cbb9aa50c68a64764ca SetThresholdToVolumeProp](...)
 
volumeRenderingLogic->[http://slicer.org/doc/html/classvtkSlicerVolumeRenderingLogic.html#a359314889c2b386fd4c3ffe5414522da SetLabelMapToVolumeProp](...)
 
| valign="top" |
 
>>> propertyNode = displayNode.GetVolumePropertyNode()
 
>>> ...
 
|}
 
 
 
====How to programmatically limit volume rendering to a subset of the volume====
 
{|width = "100%"
 
! style="border-bottom: 1px solid darkgrey;font-size: 75%;"|C++
 
! style="border-bottom: 1px solid darkgrey;font-size: 75%;"|Python
 
|-
 
| valign="top" |
 
[http://slicer.org/doc/html/classvtkMRMLAnnotationROINode.html vtkMRMLAnnotationROINode]* roiNode =...
 
vtkMRMLVolumeRenderingDisplayNode* displayNode = ...
 
displayNode->SetAndObserveROINodeID(roiNode->GetID());
 
displayNode->SetCroppingEnabled(1);
 
| valign="top" |
 
>>> displayNode.SetAndObserveROINodeID(roiNode.GetID())
 
>>> displayNode.CroppingEnabled = 1
 
|}
 
 
 
====How to register a new Volume Rendering mapper====
 
You need to derive from [http://slicer.org/doc/html/classvtkMRMLVolumeRenderingDisplayNode.html vtkMRMLVolumeRenderingDisplayNode] and register your class within [http://slicer.org/doc/html/classvtkSlicerVolumeRenderingLogic.html vtkSlicerVolumeRenderingLogic].
 
 
 
{|width = "100%"
 
! style="border-bottom: 1px solid darkgrey;font-size: 75%;"|C++
 
! style="border-bottom: 1px solid darkgrey;font-size: 75%;"|Python
 
|-
 
| valign="top" |
 
 
 
void qSlicerMyABCVolumeRenderingModule::setup()
 
{
 
  vtkMRMLThreeDViewDisplayableManagerFactory::GetInstance()->
 
    RegisterDisplayableManager("vtkMRMLMyABCVolumeRenderingDisplayableManager");
 
 
  this->Superclass::setup();
 
 
  qSlicerAbstractCoreModule* volumeRenderingModule =
 
    qSlicerCoreApplication::application()->moduleManager()->module("VolumeRendering");
 
  if (volumeRenderingModule)
 
    {
 
    vtkNew<vtkMRMLMyABCVolumeRenderingDisplayNode> displayNode;
 
    vtkSlicerVolumeRenderingLogic* volumeRenderingLogic =
 
      vtkSlicerVolumeRenderingLogic::SafeDownCast(volumeRenderingModule->logic());
 
    volumeRenderingLogic->RegisterRenderingMethod(
 
      "My ABC Volume Rendering", displayNode->GetClassName());
 
    }
 
  else
 
    {
 
    qWarning() << "Volume Rendering module is not found";
 
    }
 
}
 
If you want to expose control widgets for your volume rendering method, then register your widget with [http://slicer.org/doc/html/classqSlicerVolumeRenderingModuleWidget.html#acd9cdb60f1fd260f3ebf74428bb7c45b addRenderingMethodWidget()]
 
|}
 
 
 
==== How to register custom volume rendering presets====
 
Custom presets can be added to the volume rendering module by calling AddPreset() method of the volume rendering module logic. The example below shows how to define multiple custom volume rendering presets in an external MRML scene file and add them to the volume rendering module user interface.
 
 
 
Create a 'MyPresets.mrml' file that describes two custom volume rendering presets:
 
<pre>
 
<MRML version="Slicer4.4.0">
 
 
 
  <VolumeProperty id="vtkMRMLVolumeProperty1" name="MyPreset1"    references="IconVolume:vtkMRMLVectorVolumeNode1;" interpolation="1" shade="1" diffuse="0.66" ambient="0.1" specular="0.62" specularPower="14" scalarOpacity="10 -3.52844023704529 0 56.7852325439453 0 79.2550277709961 0.428571432828903 415.119384765625 1 641 1" gradientOpacity="4 0 1 160.25 1" colorTransfer="16 0 0 0 0 98.7223 0.196078431372549 0.945098039215686 0.956862745098039 412.406 0 0.592157 0.807843 641 1 1 1" />
 
  <VectorVolume id="vtkMRMLVectorVolumeNode1" references="storage:vtkMRMLVolumeArchetypeStorageNode1;" /> 
 
  <VolumeArchetypeStorage id="vtkMRMLVolumeArchetypeStorageNode1" fileName="MyPreset1.png"  fileListMember0="MyPreset1.png" />
 
 
 
  <VolumeProperty id="vtkMRMLVolumeProperty2" name="MyPreset2"    references="IconVolume:vtkMRMLVectorVolumeNode2;" interpolation="1" shade="1" diffuse="0.66" ambient="0.1" specular="0.62" specularPower="14" scalarOpacity="10 -3.52844023704529 0 56.7852325439453 0 79.2550277709961 0.428571432828903 415.119384765625 1 641 1" gradientOpacity="4 0 1 160.25 1" colorTransfer="16 0 0 0 0 98.7223 0.196078431372549 0.945098039215686 0.956862745098039 412.406 0 0.592157 0.807843 641 1 1 1" />
 
  <VectorVolume id="vtkMRMLVectorVolumeNode2" references="storage:vtkMRMLVolumeArchetypeStorageNode2;" /> 
 
  <VolumeArchetypeStorage id="vtkMRMLVolumeArchetypeStorageNode2" fileName="MyPreset2.png"  fileListMember0="MyPreset2.png" />
 
 
 
</MRML>
 
</pre>
 
 
 
For this example, thumbnail images for the presets should be located in the same directory as 'MyPresets.mrml', with the file names 'MyPreset1.png' and 'MyPreset2.png'.
 
 
 
Use the following code to read all the custom presets from 'MyPresets.mrml' and load it into the scene:
 
 
 
<pre>
 
presetsScenePath = "MyPresets.mrml"
 
 
 
# Read presets scene
 
customPresetsScene = slicer.vtkMRMLScene()
 
vrPropNode = slicer.vtkMRMLVolumePropertyNode()
 
customPresetsScene.RegisterNodeClass(vrPropNode)
 
customPresetsScene.SetURL(presetsScenePath)
 
customPresetsScene.Connect()
 
 
 
# Add presets to volume rendering logic
 
vrLogic = slicer.modules.volumerendering.logic()
 
presetsScene = vrLogic.GetPresetsScene()
 
vrNodes = customPresetsScene.GetNodesByClass("vtkMRMLVolumePropertyNode")
 
vrNodes.UnRegister(None)
 
for itemNum in range(vrNodes.GetNumberOfItems()):
 
  node = vrNodes.GetItemAsObject(itemNum)
 
  vrLogic.AddPreset(node)
 
</pre>
 
 
 
<!-- ---------------------------- -->
 
{{documentation/{{documentation/version}}/module-footer}}
 
<!-- ---------------------------- -->
 

Latest revision as of 04:48, 19 August 2020

Home < Documentation < Nightly < Modules < VolumeRendering