]> Creatis software - bbtk.git/blob - packages/kw/src/vtkKWSlicer.cxx
adc9bf9d52f675ea2d12c82dc60fab074ebaa71f
[bbtk.git] / packages / kw / src / vtkKWSlicer.cxx
1 #ifdef USE_KWWIDGETS
2
3 #include "vtkKWSlicer.h"
4
5 #include "vtkCornerAnnotation.h"
6 #include "vtkImageData.h"
7 #include "vtkImageViewer2.h"
8 #include "vtkKWApplication.h"
9 #include "vtkKWFrame.h"
10 #include "vtkKWSplitFrame.h"
11 #include "vtkKWFrameWithLabel.h"
12 #include "vtkKWMenu.h"
13 #include "vtkKWMenuButton.h"
14 #include "vtkKWMenuButtonWithSpinButtons.h"
15 #include "vtkKWMenuButtonWithSpinButtonsWithLabel.h"
16 #include "vtkKWNotebook.h"
17 #include "vtkKWRenderWidget.h"
18 #include "vtkKWScale.h"
19 #include "vtkKWSimpleAnimationWidget.h"
20 #include "vtkKWWindow.h"
21 #include "vtkKWWindowLevelPresetSelector.h"
22 #include "vtkObjectFactory.h"
23 #include "vtkRenderWindow.h"
24 #include "vtkRenderWindowInteractor.h"
25 #include "vtkXMLImageDataReader.h"
26
27 //#include "vtkKWWidgetsPaths.h" 
28 #include "vtkToolkits.h"
29
30 #include <vtksys/SystemTools.hxx>
31
32 //namespace bbkw {
33
34 //----------------------------------------------------------------------------
35 vtkStandardNewMacro( vtkKWSlicer );
36 vtkCxxRevisionMacro(vtkKWSlicer, "$Revision: 1.2 $");
37
38 //----------------------------------------------------------------------------
39 vtkKWSlicer::vtkKWSlicer()
40 {
41   this->Frame = NULL;
42   this->RenderWidget = NULL;
43   this->Image = NULL;
44   this->ImageViewer = NULL;
45   this->SliceScale = NULL;
46   this->WindowLevelPresetSelector = NULL;
47   this->AnimationWidget = NULL;
48 }
49
50 //----------------------------------------------------------------------------
51 vtkKWSlicer::~vtkKWSlicer()
52 {
53  if (this->Frame)
54     {
55     this->Frame->Delete();
56     }
57   if (this->SliceScale)
58     {
59     this->SliceScale->Delete();
60     }
61   if (this->ImageViewer)
62     {
63     this->ImageViewer->Delete();
64     }
65   if (this->RenderWidget)
66     {
67     this->RenderWidget->Delete();
68     }
69   if (this->WindowLevelPresetSelector)
70     {
71     this->WindowLevelPresetSelector->Delete();
72     }
73   if (this->AnimationWidget)
74     {
75     this->AnimationWidget->Delete();
76     }
77 }
78
79 //----------------------------------------------------------------------------
80 void vtkKWSlicer::CreateWidget()
81 {
82   // Check if already created
83
84   if (this->IsCreated())
85     {
86     vtkErrorMacro("class already created");
87     return;
88     }
89
90   // Call the superclass to create the whole widget
91
92   this->Superclass::CreateWidget();
93
94   vtkKWApplication *app = this->GetApplication();
95
96   // Add a SplitFrame
97   Frame =  vtkKWSplitFrame::New();
98   Frame->SetFrame1MinimumSize(150);
99   Frame->SetFrame2MinimumSize(250);     
100   Frame->SetOrientationToVertical ();
101   Frame->SetExpandableFrameToFrame2();
102   Frame->SetParent(this);
103   Frame->Create();
104   app->Script("pack %s -side top -expand yes",// -fill both",
105               this->Frame->GetWidgetName());
106   // Add a render widget, attach it to the view frame, and pack
107
108   if (!this->RenderWidget)
109     {
110     this->RenderWidget = vtkKWRenderWidget::New();
111     }
112   this->RenderWidget->SetParent(Frame->GetFrame2());
113   this->RenderWidget->Create();
114   this->RenderWidget->CornerAnnotationVisibilityOn();
115
116   //  app->Script("grid %s -row 0 -column 0 -columnspan 2  -sticky nsew -padx 8 -pady 8",
117   app->Script("pack %s -side top -expand y -fill both -padx 2 -pady 2",
118               //  app->Script("pack %s -expand y -fill both -anchor c -expand y", 
119               this->RenderWidget->GetWidgetName());
120   //  this->Script("grid rowconfigure %s 1 -weight 1 -minsize 100",
121   //               this->RenderWidget->GetWidgetName());
122
123   // Create a volume reader
124   /*
125   vtkXMLImageDataReader *reader = vtkXMLImageDataReader::New();
126
127   char data_path[2048];
128   sprintf(data_path, "%s/Data/head100x100x47.vti", KWWidgets_EXAMPLES_DIR);
129   if (!vtksys::SystemTools::FileExists(data_path))
130     {
131     sprintf(data_path,
132             "%s/..%s/Examples/Data/head100x100x47.vti",
133             app->GetInstallationDirectory(), KWWidgets_INSTALL_DATA_DIR);
134     }
135   reader->SetFileName(data_path);
136   */
137   // Create an image viewer
138   // Use the render window and renderer of the renderwidget
139
140   if (!this->ImageViewer)
141     {
142     this->ImageViewer = vtkImageViewer2::New();
143     }
144   this->ImageViewer->SetRenderWindow(this->RenderWidget->GetRenderWindow());
145   this->ImageViewer->SetRenderer(this->RenderWidget->GetRenderer());
146   //  this->ImageViewer->SetInput(reader->GetOutput());
147   this->ImageViewer->SetupInteractor(
148     this->RenderWidget->GetRenderWindow()->GetInteractor());
149
150
151   // Reset the window/level and the camera
152   /*
153   reader->Update();
154   double *range = reader->GetOutput()->GetScalarRange();
155   this->ImageViewer->SetColorWindow(range[1] - range[0]);
156   this->ImageViewer->SetColorLevel(0.5 * (range[1] + range[0]));
157
158   this->RenderWidget->ResetCamera();
159   */
160   // The corner annotation has the ability to parse "tags" and fill
161   // them with information gathered from other objects.
162   // For example, let's display the slice and window/level in one corner
163   // by connecting the corner annotation to our image actor and
164   // image mapper
165
166   vtkCornerAnnotation *ca = this->RenderWidget->GetCornerAnnotation();
167   ca->SetImageActor(this->ImageViewer->GetImageActor());
168   ca->SetWindowLevel(this->ImageViewer->GetWindowLevel());
169   ca->SetText(2, "<slice>");
170   ca->SetText(3, "<window>\n<level>");
171
172   // Create a scale to control the slice
173
174   if (!this->SliceScale)
175     {
176     this->SliceScale = vtkKWScale::New();
177     }
178   this->SliceScale->SetParent(Frame->GetFrame1());
179   this->SliceScale->Create();
180   //  this->SliceScale->SetCommand(this, "SetSliceFromScaleCallback");
181
182   app->Script("pack %s -side top -expand n -fill x",
183               this->SliceScale->GetWidgetName());
184   //app->Script("grid %s -row 1 -column 1 -sticky nsew -padx 8",
185               //app->Script("pack %s -side right -expand n -fill x -padx 2 -pady 2",
186   //          this->SliceScale->GetWidgetName());
187   //  this->Script("grid rowconfigure %s 0 -weight 1",
188   //               this->SliceScale->GetWidgetName());
189
190   // Create a menu button to control the orientation
191
192   vtkKWMenuButtonWithSpinButtonsWithLabel *orientation_menubutton =
193     vtkKWMenuButtonWithSpinButtonsWithLabel::New();
194
195   orientation_menubutton->SetParent(Frame->GetFrame1());
196   orientation_menubutton->Create();
197   orientation_menubutton->SetLabelText("Orientation:");
198   orientation_menubutton->SetPadX(2);
199   orientation_menubutton->SetPadY(2);
200   orientation_menubutton->SetBorderWidth(2);
201   orientation_menubutton->SetReliefToGroove();
202
203   app->Script("pack %s -side top -expand n -fill x",
204               orientation_menubutton->GetWidgetName());
205
206   //  this->Script("grid %s -row 1 -column 0",
207               //app->Script("pack %s -side left -anchor nw -expand n -fill x",
208   //              orientation_menubutton->GetWidgetName());
209   //  this->Script("grid rowconfigure %s 1 -weight 1",
210   //             orientation_menubutton->GetWidgetName());
211
212   vtkKWMenuButton *mb = orientation_menubutton->GetWidget()->GetWidget();
213   vtkKWMenu *menu = OrientationMenu = mb->GetMenu();
214
215   menu->AddRadioButton("X-Y"); //, this, "SetSliceOrientationToXYCallback");
216   menu->AddRadioButton("X-Z"); //, this, "SetSliceOrientationToXZCallback");
217   menu->AddRadioButton("Y-Z"); //, this, "SetSliceOrientationToYZCallback");
218
219   mb->SetValue("X-Y");
220
221
222   
223   // Create a window/level preset selector
224   /*
225   vtkKWFrameWithLabel *wl_frame = vtkKWFrameWithLabel::New();
226   wl_frame->SetParent(this); //->GetMainPanelFrame());
227   wl_frame->Create();
228   wl_frame->SetLabelText("Window/Level Presets");
229
230   app->Script("pack %s -side top -anchor nw -expand n -fill x -pady 2",
231               wl_frame->GetWidgetName());
232
233   if (!this->WindowLevelPresetSelector)
234     {
235     this->WindowLevelPresetSelector = vtkKWWindowLevelPresetSelector::New();
236     }
237   this->WindowLevelPresetSelector->SetParent(wl_frame->GetFrame());
238   this->WindowLevelPresetSelector->Create();
239   this->WindowLevelPresetSelector->ThumbnailColumnVisibilityOn();
240   
241   this->WindowLevelPresetSelector->SetPresetAddCommand(
242     this, "WindowLevelPresetAddCallback");
243   this->WindowLevelPresetSelector->SetPresetApplyCommand(
244     this, "WindowLevelPresetApplyCallback");
245   this->WindowLevelPresetSelector->SetPresetUpdateCommand(
246     this, "WindowLevelPresetUpdateCallback");
247   this->WindowLevelPresetSelector->SetPresetHasChangedCommand(
248     this, "WindowLevelPresetHasChangedCallback");
249
250
251   app->Script("pack %s -side top -anchor nw -expand n -fill x",
252               this->WindowLevelPresetSelector->GetWidgetName());
253
254   // Create a simple animation widget
255
256   vtkKWFrameWithLabel *animation_frame = vtkKWFrameWithLabel::New();
257   animation_frame->SetParent(this); //->GetMainPanelFrame());
258   animation_frame->Create();
259   animation_frame->SetLabelText("Movie Creator");
260
261   app->Script("pack %s -side top -anchor nw -expand n -fill x -pady 2",
262               animation_frame->GetWidgetName());
263
264   if (!this->AnimationWidget)
265     {
266     this->AnimationWidget = vtkKWSimpleAnimationWidget::New();
267     }
268   this->AnimationWidget->SetParent(animation_frame->GetFrame());
269   this->AnimationWidget->Create();
270   this->AnimationWidget->SetRenderWidget(this->RenderWidget);
271   this->AnimationWidget->SetAnimationTypeToSlice();
272   //  this->AnimationWidget->SetSliceSetCommand(this, "SetSliceCallback");
273   //  this->AnimationWidget->SetSliceGetCommand(this, "GetSliceCallback");
274
275   app->Script("pack %s -side top -anchor nw -expand n -fill x",
276               this->AnimationWidget->GetWidgetName());
277   */
278   this->UpdateSliceRanges();
279
280   // Callbacks
281   this->AddCallbackCommandObserver( this->SliceScale, 
282                                     vtkKWScale::ScaleValueChangingEvent);
283   this->AddCallbackCommandObserver( menu, 
284                                     vtkKWMenu::MenuItemInvokedEvent);
285
286
287   // Deallocate local objects
288
289   //  reader->Delete();
290   orientation_menubutton->Delete();
291   //  wl_frame->Delete();
292   //  animation_frame->Delete();
293   UpdateImage();
294 }
295
296
297 //----------------------------------------------------------------------------
298 void vtkKWSlicer::ProcessCallbackCommandEvents(
299   vtkObject *caller, unsigned long event, void *calldata)
300 {
301   std::cout << "###### vtkKWSlicer::ProcessCallbackCommandEvents" << std::endl;
302   if (caller == this->SliceScale && 
303       event == vtkKWScale::ScaleValueChangingEvent)
304     {
305       this->SetSliceFromScaleCallback(*((double*)calldata));
306     }
307   if (caller == this->OrientationMenu && 
308       event == vtkKWMenu::MenuItemInvokedEvent)
309     {
310       int i = *((int*)calldata);
311       //      std::cout << i << std::endl;
312       if (i==0) this->SetSliceOrientationToXYCallback();
313       else if (i==1) this->SetSliceOrientationToXZCallback();
314       else if (i==2) this->SetSliceOrientationToYZCallback();
315           
316
317       //      this->SetSliceFromScaleCallback(*((double*)calldata));
318     }
319
320   /*
321   // We received a notification from the application that its value was
322   // changed. Let's propagate that value to our scale widget
323
324   if (caller == myapp && event == vtkCommand::ModifiedEvent)
325     {
326     this->Scale->SetValue(myapp->GetMyValue());
327     }
328   */
329   this->Superclass::ProcessCallbackCommandEvents(caller, event, calldata);
330 }
331  //----------------------------------------------------------------------------
332
333  //----------------------------------------------------------------------------
334 void vtkKWSlicer::SetImage(vtkImageData* image)
335 {
336   Image = vtkImageData::New();
337   Image->ShallowCopy(image);
338   UpdateImage();
339 }
340 //----------------------------------------------------------------------------
341
342 //----------------------------------------------------------------------------
343 void vtkKWSlicer::UpdateImage()
344 {
345   if (!Image) return;
346   if (!this->IsCreated()) return;
347   this->ImageViewer->SetInput(Image);
348   double *range = Image->GetScalarRange();
349   this->ImageViewer->SetColorWindow(range[1] - range[0]);
350   this->ImageViewer->SetColorLevel(0.5 * (range[1] + range[0]));
351   this->RenderWidget->ResetCamera(); 
352   this->UpdateSliceRanges();
353   Image->Delete();
354 }
355 //----------------------------------------------------------------------------
356
357 //----------------------------------------------------------------------------
358 void vtkKWSlicer::SetSliceFromScaleCallback(double value)
359 {
360   this->ImageViewer->SetSlice((int)value);
361   this->ImageViewer->Render();
362 }
363
364 //----------------------------------------------------------------------------
365 void vtkKWSlicer::SetSliceCallback(int slice)
366 {
367   this->ImageViewer->SetSlice(slice);
368 }
369
370 //----------------------------------------------------------------------------
371 int vtkKWSlicer::GetSliceCallback()
372 {
373   return this->ImageViewer->GetSlice();
374 }
375
376 //----------------------------------------------------------------------------
377 int vtkKWSlicer::GetSliceMinCallback()
378 {
379   return this->ImageViewer->GetSliceMin();
380 }
381
382 //----------------------------------------------------------------------------
383 int vtkKWSlicer::GetSliceMaxCallback()
384 {
385   return this->ImageViewer->GetSliceMax();
386 }
387
388 //----------------------------------------------------------------------------
389 void vtkKWSlicer::UpdateSliceRanges()
390 {
391   this->SliceScale->SetRange(
392     this->ImageViewer->GetSliceMin(), this->ImageViewer->GetSliceMax());
393   this->SliceScale->SetValue(this->ImageViewer->GetSlice());
394
395   /*
396   this->AnimationWidget->SetSliceRange(
397     this->ImageViewer->GetSliceMin(), this->ImageViewer->GetSliceMax());
398   */
399 }
400
401 //----------------------------------------------------------------------------
402 void vtkKWSlicer::SetSliceOrientationToXYCallback()
403 {
404   this->ImageViewer->SetSliceOrientationToXY();
405   this->UpdateSliceRanges();
406 }
407
408 //----------------------------------------------------------------------------
409 void vtkKWSlicer::SetSliceOrientationToXZCallback()
410 {
411   this->ImageViewer->SetSliceOrientationToXZ();
412   this->UpdateSliceRanges();
413 }
414
415 //----------------------------------------------------------------------------
416 void vtkKWSlicer::SetSliceOrientationToYZCallback()
417 {
418   this->ImageViewer->SetSliceOrientationToYZ();
419   this->UpdateSliceRanges();
420 }
421
422 //----------------------------------------------------------------------------
423 void vtkKWSlicer::WindowLevelPresetApplyCallback(int id)
424 {
425   if (this->WindowLevelPresetSelector->HasPreset(id))
426     {
427     this->ImageViewer->SetColorWindow(
428       this->WindowLevelPresetSelector->GetPresetWindow(id));
429     this->ImageViewer->SetColorLevel(
430       this->WindowLevelPresetSelector->GetPresetLevel(id));
431     this->ImageViewer->Render();
432     }
433 }
434 //----------------------------------------------------------------------------
435 int vtkKWSlicer::WindowLevelPresetAddCallback()
436 {
437   int id = this->WindowLevelPresetSelector->AddPreset();
438   this->WindowLevelPresetUpdateCallback(id);
439   this->WindowLevelPresetSelector->SelectPreset(id);
440   return id;
441 }
442
443 //----------------------------------------------------------------------------
444 void vtkKWSlicer::WindowLevelPresetUpdateCallback(int id)
445 {
446   this->WindowLevelPresetSelector->SetPresetWindow(
447     id, this->ImageViewer->GetColorWindow());
448   this->WindowLevelPresetSelector->SetPresetLevel(
449     id, this->ImageViewer->GetColorLevel());
450   this->WindowLevelPresetHasChangedCallback(id);
451 }
452
453 //----------------------------------------------------------------------------
454 void vtkKWSlicer::WindowLevelPresetHasChangedCallback(int id)
455 {
456   this->WindowLevelPresetSelector->
457     BuildPresetThumbnailAndScreenshotFromRenderWindow(
458       id, this->RenderWidget->GetRenderWindow());
459 }
460
461
462 //} // namespace kw
463 #endif // USE_KWWIDGETS