Class: VtkTkImageViewerWidget

Inherits:
TkWindow
  • Object
show all
Defined in:
lib/VTK/tk/vtkTkImageViewerWidget.rb

Constant Summary collapse

TkCommandNames =

A vtkTkImageViewerWidget for Ruby.

Use GetImageViewer() to get the vtkImageViewer.

Create with the keyword double=1 in order to generate a
double-buffered viewer.

Create with the keyword focus_on_enter=1 to enable
focus-follows-mouse.  The default is for a click-to-focus mode.
['vtkTkImageViewerWidget'.freeze].freeze

Instance Method Summary collapse

Constructor Details

#initialize(master, kw = {}) ⇒ VtkTkImageViewerWidget

Returns a new instance of VtkTkImageViewerWidget.



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
# File 'lib/VTK/tk/vtkTkImageViewerWidget.rb', line 28

def initialize(master, kw={})
=begin
      Constructor.

      Keyword arguments:

        iv -- Use passed image viewer instead of creating a new one.

        double -- If True, generate a double-buffered viewer.
        Defaults to False.

        focus_on_enter -- If True, use a focus-follows-mouse mode.
        Defaults to False where the widget will use a click-to-focus
        mode.
=end
  # load the necessary extensions into tk
  vtkLoadRubyTkWidgets()

  _symbolkey2str(kw)

  if kw['iv']
    @ImageViewer = kw['iv']
  else
    @ImageViewer = Vtk::ImageViewer.new
  end

  doubleBuffer = 0
  if kw['double']
    doubleBuffer = 1
    kw.delete('double')
  end
 
  # check if focus should follow mouse
  if kw['focus_on_enter']
    @FocusOnEnter = 1
  else
    @FocusOnEnter = 0
  end

  kw['iv'] = @ImageViewer.GetAddressAsString("vtkImageViewer")
  kw['widgetname'] = 'vtkTkImageViewerWidget'
  super(master, kw)

  if doubleBuffer
    @ImageViewer.GetRenderWindow.DoubleBufferOn
  end

  self.BindTkImageViewer
end

Instance Method Details

#_GrabFocusObject



161
162
163
164
# File 'lib/VTK/tk/vtkTkImageViewerWidget.rb', line 161

def _GrabFocus
  @OldFocus = self.focus
  self.focus
end

#BindTkImageViewerObject



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
# File 'lib/VTK/tk/vtkTkImageViewerWidget.rb', line 86

def BindTkImageViewer
  imager = @ImageViewer.GetRenderer
      
  # stuff for window level text.
  mapper = Vtk::TextMapper.new
  mapper.SetInput("none")
  t_prop = mapper.GetTextProperty
  t_prop.SetFontFamilyToTimes
  t_prop.SetFontSize(18)
  t_prop.BoldOn
  t_prop.ShadowOn
      
  @LevelMapper = mapper

  actor = Vtk::Actor2D.new
  actor.SetMapper(mapper)
  actor.SetLayerNumber(1)
  actor.GetPositionCoordinate.SetValue(4,22)
  actor.GetProperty.SetColor(1,1,0.5)
  actor.SetVisibility(0)
  imager.AddActor2D(actor)

  @LevelActor = actor
              
  mapper = Vtk::TextMapper.new
  mapper.SetInput("none")
  t_prop = mapper.GetTextProperty
  t_prop.SetFontFamilyToTimes
  t_prop.SetFontSize(18)
  t_prop.BoldOn
  t_prop.ShadowOn
  
  @WindowMapper = mapper

  actor = Vtk::Actor2D.new
  actor.SetMapper(mapper)
  actor.SetLayerNumber(1)
  actor.GetPositionCoordinate.SetValue(4,4)
  actor.GetProperty.SetColor(1,1,0.5)
  actor.SetVisibility(0)
  imager.AddActor2D(actor)

  @WindowActor = actor

  @LastX = 0
  @LastY = 0
  @OldFocus = 0
  @InExpose = 0
  
  # bindings
  # window level
  self.bind("ButtonPress-1"){|e,s| s||s=self; s.StartWindowLevelInteraction(e.x,e.y) }
  self.bind("B1-Motion"){|e,s| s||s=self; s.UpdateWindowLevelInteraction(e.x,e.y) }
  self.bind("ButtonRelease-1"){|e,s| s||s=self; s.EndWindowLevelInteraction }
  
  # Get the value
  self.bind("ButtonPress-3"){|e,s| s||s=self; s.StartQueryInteraction(e.x,e.y) }
  self.bind("B3-Motion"){|e,s| s||s=self; s.UpdateQueryInteraction(e.x,e.y) }
  self.bind("ButtonRelease-3"){|e,s| s||s=self; s.EndQueryInteraction }

  self.bind("Expose"){|e,s| s||s=self; s.ExposeTkImageViewer }
  self.bind("Enter"){|e,s| s||s=self; s.EnterTkViewer }
  self.bind("Leave"){|e,s| s||s=self; s.LeaveTkViewer }
  self.bind("KeyPress-e"){|e,s| s||s=self; exit }
  self.bind("KeyPress-r"){|e,s| s||s=self; s.ResetTkImageViewer }
end

#EndQueryInteractionObject



277
278
279
280
# File 'lib/VTK/tk/vtkTkImageViewerWidget.rb', line 277

def EndQueryInteraction
  @WindowActor.SetVisibility(0)
  self.Render
end

#EndWindowLevelInteractionObject



208
209
210
211
212
213
# File 'lib/VTK/tk/vtkTkImageViewerWidget.rb', line 208

def EndWindowLevelInteraction
  # make the window level text invisible
  @LevelActor.SetVisibility(0)
  @WindowActor.SetVisibility(0)
  self.Render
end

#EnterTkViewerObject



166
167
168
169
170
171
# File 'lib/VTK/tk/vtkTkImageViewerWidget.rb', line 166

def EnterTkViewer
  if @FocusOnEnter
    self._GrabFocus
  end
  return nil
end

#ExposeTkImageViewerObject



180
181
182
183
184
185
186
187
188
# File 'lib/VTK/tk/vtkTkImageViewerWidget.rb', line 180

def ExposeTkImageViewer
  if @InExpose == 0
    @InExpose = 1
    self.update()
    @ImageViewer.Render()
    @InExpose = 0
  end
  return nil
end

#GetImageViewerObject



78
79
80
# File 'lib/VTK/tk/vtkTkImageViewerWidget.rb', line 78

def GetImageViewer
  return @ImageViewer
end

#LeaveTkViewerObject



173
174
175
176
177
178
# File 'lib/VTK/tk/vtkTkImageViewerWidget.rb', line 173

def LeaveTkViewer
  if @FocusOnEnter && @OldFocus != nil
    @OldFocus.focus
  end
  return nil
end

#RenderObject



82
83
84
# File 'lib/VTK/tk/vtkTkImageViewerWidget.rb', line 82

def Render
  @ImageViewer.Render
end

#ResetTkImageViewerObject



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/VTK/tk/vtkTkImageViewerWidget.rb', line 246

def ResetTkImageViewer
  # Reset: Set window level to show all values
  viewer = @ImageViewer
  input = viewer.GetInput
  if input == nil
    return nil
  end

  # Get the extent in viewer
  z = viewer.GetZSlice

  input.SetUpdateExtent(-99999,99999,-99999,99999,z,z)
  input.Update

  low,high = input.GetScalarRange
 
  viewer.SetColorWindow(high - low)
  viewer.SetColorLevel((high + low) * 0.5)

  self.Render
end

#StartQueryInteraction(x, y) ⇒ Object



268
269
270
271
272
273
274
275
# File 'lib/VTK/tk/vtkTkImageViewerWidget.rb', line 268

def StartQueryInteraction(x,y)
  if ! @FocusOnEnter
    _GrabFocus()
  end
  # Query PixleValue stuff
  @WindowActor.SetVisibility(1)
  self.UpdateQueryInteraction(x,y)
end

#StartWindowLevelInteraction(x, y) ⇒ Object



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/VTK/tk/vtkTkImageViewerWidget.rb', line 190

def StartWindowLevelInteraction(x,y)
  if ! @FocusOnEnter
    _GrabFocus
  end
  viewer = @ImageViewer
  @LastX = x
  @LastY = y
  @Window = viewer.GetColorWindow.to_f
  @Level = viewer.GetColorLevel.to_f

  # make the window level text visible
  @LevelActor.SetVisibility(1)
  @WindowActor.SetVisibility(1)

  self.UpdateWindowLevelInteraction(x,y)
  return nil
end

#UpdateQueryInteraction(x, y) ⇒ Object



282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'lib/VTK/tk/vtkTkImageViewerWidget.rb', line 282

def UpdateQueryInteraction(x,y)
  viewer = @ImageViewer
  input = viewer.GetInput
  z = viewer.GetZSlice

  # y is flipped upside down
  y = self.winfo_height - y

  # make sure point is in the whole extent of the image.
  xMin,xMax,yMin,yMax,zMin,zMax = input.GetWholeExtent
  if (x < xMin || x > xMax || y < yMin || y > yMax || z < zMin || z > zMax)
    return nil
  end

  input.SetUpdateExtent(x,x,y,y,z,z)
  input.Update
  numComps = input.GetNumberOfScalarComponents
  text = ""
  for i in 0...numComps
    val = input.GetScalarComponentAsDouble(x,y,z,i)
    text = "#{text}  #{"%.1f"%val}"
  end

  @WindowMapper.SetInput("(#{"%d"%x}, #{"%d"%y}): #{text}")
      
  self.Render
end

#UpdateWindowLevelInteraction(x, y) ⇒ Object



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/VTK/tk/vtkTkImageViewerWidget.rb', line 215

def UpdateWindowLevelInteraction(x,y)
  # compute normalized delta
  dx = 4.0*(x - @LastX)/self.winfo_width*@Window
  dy = 4.0*(@LastY - y)/self.winfo_height*@Level

  # abs so that direction does not flip
  if @Window < 0.0
    dx = -dx
  end
  if @Level < 0.0
    dy = -dy
  end

  # compute new window level
  window = @Window + dx
  if window < 0.0
    level = @Level + dy
  else
    level = @Level - dy
  end

  viewer = @ImageViewer
  viewer.SetColorWindow(window)
  viewer.SetColorLevel(level)

  @WindowMapper.SetInput("Window: %g" % window)
  @LevelMapper.SetInput("Level: %g" % level)
  
  self.Render
end