-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathOrthoViewer.py
155 lines (123 loc) · 5.86 KB
/
OrthoViewer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# VTK
from vtk import *
from VtkViewer import *
from CommandSliceSelect import *
class OrthoViewer(VtkViewer):
# Constructor
def __init__(self, vtkBaseClass:VtkBase, orientation, label:str="Orthogonal Viewer"):
super(OrthoViewer, self).__init__(label=label, vtkBaseClass=vtkBaseClass)
# Properties
self.orientation = orientation
self.current_slice = 0
self.min_slice = 0
self.max_slice = 0
self.labelsPositions = [
[0.05, 0.5],
[0.95, 0.5],
[0.5, 0.05],
[0.5, 0.9]
]
# Vtk Stuff
### Image Window Level
self.imageWindowLevel = self.vtkBaseClass.imageWindowLevel
### Image Map To Colors
self.imageMapToColors = self.vtkBaseClass.imageMapToColors
### Grayscale LUT.
self.grayscaleLut = self.vtkBaseClass.grayscaleLut
## Render Window Interactor
self.renderWindowInteractor = self.GetRenderWindow().GetInteractor()
# Interactor Style Image and Events
self.interactorStyleImage = vtk.vtkInteractorStyleImage()
self.interactorStyleImage.SetInteractor(self.renderWindowInteractor)
self.interactorStyleImage.SetInteractionModeToImageSlicing()
self.renderWindowInteractor.SetInteractorStyle(self.interactorStyleImage)
# Picker
self.picker = self.vtkBaseClass.picker
# Property
self.property = self.vtkBaseClass.property
## Reslice Cursor
self.resliceCursor = self.vtkBaseClass.resliceCursor
# Reslice Cursor Widget
self.resliceCursorWidget = vtk.vtkResliceCursorWidget()
self.resliceCursorWidget.SetInteractor(self.renderWindowInteractor)
# Reslice Cursor Line Representation
self.resliceCursorRep = vtk.vtkResliceCursorLineRepresentation()
self.resliceCursorWidget.SetRepresentation(self.resliceCursorRep)
self.resliceCursorRep.GetResliceCursorActor().GetCursorAlgorithm().SetResliceCursor(self.resliceCursor)
self.resliceCursorRep.GetResliceCursorActor().GetCursorAlgorithm().SetReslicePlaneNormal(self.orientation)
self.resliceCursorRep.SetWindowLevel(self.imageWindowLevel.GetWindow(),self.imageWindowLevel.GetLevel())
## To fix problem of not showing the reslice cursor
for i in range(3):
self.resliceCursorRep.GetResliceCursorActor().GetCenterlineProperty(i).SetRepresentationToWireframe()
self.resliceCursorWidget.SetDefaultRenderer(self.renderer)
self.resliceCursorWidget.EnabledOn()
# Command Slice Select
self.commandSliceSelect = self.vtkBaseClass.commandSliceSelect
self.commandSliceSelect.resliceCursorWidgets[self.orientation] = self.resliceCursorWidget
self.commandSliceSelect.resliceCursor = self.resliceCursor
# Renderer Settings
color = [0.02, 0.02, 0.02]
color[self.orientation] = 0
self.renderer.SetBackground(color)
# Add directions text
if self.orientation == SLICE_ORIENTATION_XY:
self.add_directions_text(["R", "L", "A", "P"])
elif self.orientation == SLICE_ORIENTATION_XZ:
self.add_directions_text(["R", "L", "I", "S"])
elif self.orientation == SLICE_ORIENTATION_YZ:
self.add_directions_text(["A", "P", "I", "S"])
# Add observers
self.add_observers()
# Connect on data
def connect_on_data(self, path:str):
super().connect_on_data(path)
self.set_slice_range()
# Add text
def add_text_actor(self, text:str, position:list):
## Label Text Actor
textActor = vtkTextActor()
textActor.SetInput(text)
textActor.GetPositionCoordinate().SetCoordinateSystemToNormalizedViewport()
textActor.GetPositionCoordinate().SetValue(position[0], position[1])
textActor.GetTextProperty().SetFontSize(18)
textActor.GetTextProperty().SetColor(0.8, 0.8, 0)
textActor.GetTextProperty().SetShadow(1)
textActor.GetTextProperty().SetJustificationToCentered()
textActor.GetTextProperty().SetVerticalJustificationToCentered()
textActor.GetTextProperty().SetFontFamilyToTimes()
textActor.GetTextProperty().SetBold(1)
self.renderer.AddActor2D(textActor)
# Add directions text
def add_directions_text(self, list_of_directions:list):
for i,direction_text in zip(range(4),list_of_directions):
self.add_text_actor(text=direction_text, position=self.labelsPositions[i])
# Get slice range
def get_slices_range(self):
return self.min_slice, self.max_slice
# Set slice range
def set_slice_range(self):
self.resliceCursor.Reset()
self.min_slice = int(self.vtkBaseClass.bounds[self.orientation * 2 + 0])
self.max_slice = int(self.vtkBaseClass.bounds[self.orientation * 2 + 1])
# Get slice index
def get_slice(self):
return self.current_slice
# Set slice index
def set_slice(self, slice_index):
center = list(self.resliceCursor.GetCenter())
center[self.orientation] = slice_index
self.resliceCursor.SetCenter(center)
self.resliceCursor.Update()
for i in range(0,3):
self.commandSliceSelect.imagePlaneWidgets[i].UpdatePlacement()
self.commandSliceSelect.resliceCursorWidgets[i].Render()
self.render()
# Update
def update(self):
super().update()
# Render
def render(self):
super().render()
# Events
def add_observers(self):
self.resliceCursorWidget.AddObserver(vtk.vtkResliceCursorWidget.ResliceAxesChangedEvent, self.commandSliceSelect)