Skip to content

Commit e2e04e7

Browse files
DOCS: Add custom volume rendering example
1 parent a96f16a commit e2e04e7

File tree

6 files changed

+517
-1
lines changed

6 files changed

+517
-1
lines changed

Docs/examples.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,17 @@
1010
:language: python
1111
:linenos:
1212
```
13+
14+
### Volume Rendering Pipeline
15+
16+
![Volume Rendering Example](images/volume_rendering_example.jpg)
17+
18+
```{literalinclude} ../Examples/Python/CustomVR/CustomVR.py
19+
:language: python
20+
:linenos:
21+
```
22+
23+
```{literalinclude} ../Examples/Python/CustomVR/CustomVRLib/CustomVRPipeline.py
24+
:language: python
25+
:linenos:
26+
```
113 KB
Loading

Docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Welcome to the Slicer Layer Displayable Manager's documentation!
22

3-
![Welcome to Slicer Layer DM](https://raw.githubusercontent.com/KitwareMedical/SlicerLayerDisplayableManager/main/Doc/LayerDisplayableManager.png)
3+
![Welcome to Slicer Layer DM](https://raw.githubusercontent.com/KitwareMedical/SlicerLayerDisplayableManager/main/Docs/LayerDisplayableManager.png)
44

55

66
Slicer Layer DM is a [3D Slicer](https://github.com/Slicer/Slicer/) extension simplifying the creation of new display
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
"""
2+
This example shows how to create a custom volume rendering for a volume node using the SlicerLayerDisplayableManager
3+
extension.
4+
5+
It goes over the following concepts:
6+
- Creates a VR display pipeline on a selected volume node in the scene
7+
- Register the pipeline creation mechanism
8+
9+
Usage:
10+
This example is implemented as a scripted module and can be added as such to Slicer.
11+
Due to import order considerations, the pipeline code is lazy loaded from the CustomVRLib python package.
12+
"""
13+
14+
import qt
15+
import slicer
16+
from slicer.ScriptedLoadableModule import ScriptedLoadableModule, ScriptedLoadableModuleWidget
17+
18+
19+
class CustomVR(ScriptedLoadableModule):
20+
def __init__(self, parent):
21+
ScriptedLoadableModule.__init__(self, parent)
22+
self.parent.title = "Custom VR Pipeline Example"
23+
self.parent.categories = ["qSlicerAbstractCoreModule", "Examples"]
24+
self.parent.dependencies = []
25+
self.parent.contributors = []
26+
self.parent.helpText = ""
27+
self.parent.acknowledgementText = ""
28+
29+
30+
class CustomVRWidget(ScriptedLoadableModuleWidget):
31+
"""
32+
In this example, we will display a custom volume rendering and use VTK compute shader for processing the volume.
33+
To avoid initialization problems, the pipeline registration is done lazily during the setup.
34+
"""
35+
36+
def setup(self) -> None:
37+
from CustomVRLib import registerPipeline
38+
39+
registerPipeline()
40+
ScriptedLoadableModuleWidget.setup(self)
41+
42+
widget = qt.QWidget()
43+
layout = qt.QVBoxLayout(widget)
44+
45+
# Configure volume selector node
46+
self._volumeNodeSelector = slicer.qMRMLNodeComboBox(widget)
47+
self._volumeNodeSelector.nodeTypes = ["vtkMRMLVolumeNode"]
48+
self._volumeNodeSelector.selectNodeUponCreation = True
49+
self._volumeNodeSelector.addEnabled = False
50+
self._volumeNodeSelector.removeEnabled = False
51+
self._volumeNodeSelector.showHidden = False
52+
self._volumeNodeSelector.renameEnabled = True
53+
self._volumeNodeSelector.setMRMLScene(slicer.mrmlScene)
54+
layout.addWidget(self._volumeNodeSelector)
55+
56+
# Configure toggle button
57+
toggleDisplayButton = qt.QPushButton("Toggle display")
58+
toggleDisplayButton.clicked.connect(self._toggleVolumeDisplay)
59+
layout.addWidget(toggleDisplayButton)
60+
layout.addStretch()
61+
62+
self.layout.addWidget(widget)
63+
64+
def _toggleVolumeDisplay(self, *_):
65+
from CustomVRLib import CustomVRPipeline
66+
67+
volumeNode = self._volumeNodeSelector.currentNode()
68+
if not volumeNode:
69+
return
70+
71+
wasVisible = CustomVRPipeline.GetVRNodeVisibility(volumeNode, slicer.mrmlScene)
72+
vrNode = CustomVRPipeline.CreateVRNode(volumeNode, slicer.mrmlScene)
73+
CustomVRPipeline.SetVRNodeVisible(vrNode, not wasVisible)
74+
75+
def onReload(self):
76+
"""
77+
Customization of reload to allow reloading of the CustomVRLib files.
78+
"""
79+
import importlib
80+
81+
packageName = "CustomVRLib"
82+
submodules = ["CustomVRPipeline"]
83+
84+
# Reload the package
85+
module = importlib.import_module(packageName)
86+
importlib.reload(module)
87+
88+
# Reload submodules
89+
for sub in submodules:
90+
fullName = f"{packageName}.{sub}"
91+
submodule = importlib.import_module(fullName)
92+
importlib.reload(submodule)
93+
94+
ScriptedLoadableModuleWidget.onReload(self)

0 commit comments

Comments
 (0)