3 #include "vtkKWSlicer.h"
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"
27 #include "vtkKWCornerAnnotationEditor.h"
29 //#include "vtkKWWidgetsPaths.h"
30 #include "vtkToolkits.h"
32 #include <vtksys/SystemTools.hxx>
34 extern "C" int Bbkw_Init(Tcl_Interp *interp);
38 //----------------------------------------------------------------------------
39 vtkStandardNewMacro( vtkKWSlicer );
40 vtkCxxRevisionMacro(vtkKWSlicer, "$Revision: 1.4 $");
42 //----------------------------------------------------------------------------
43 vtkKWSlicer::vtkKWSlicer()
46 Bbkw_Init(vtkKWApplication::GetMainInterp ());
49 this->RenderWidget = NULL;
51 this->ImageViewer = NULL;
52 this->SliceScale = NULL;
53 this->WindowLevelPresetSelector = NULL;
54 this->AnimationWidget = NULL;
57 //----------------------------------------------------------------------------
58 vtkKWSlicer::~vtkKWSlicer()
62 this->Frame->Delete();
66 this->SliceScale->Delete();
68 if (this->ImageViewer)
70 this->ImageViewer->Delete();
72 if (this->RenderWidget)
74 this->RenderWidget->Delete();
76 if (this->WindowLevelPresetSelector)
78 this->WindowLevelPresetSelector->Delete();
80 if (this->AnnotationEditor)
82 this->AnnotationEditor->Delete();
84 if (this->AnimationWidget)
86 this->AnimationWidget->Delete();
90 //----------------------------------------------------------------------------
91 void vtkKWSlicer::CreateWidget()
93 // Check if already created
95 if (this->IsCreated())
97 vtkErrorMacro("class already created");
101 // Call the superclass to create the whole widget
103 this->Superclass::CreateWidget();
105 vtkKWApplication *app = this->GetApplication();
109 Frame = vtkKWSplitFrame::New();
110 Frame->SetFrame1MinimumSize(150);
111 Frame->SetFrame2MinimumSize(250);
112 Frame->SetOrientationToVertical ();
113 Frame->SetExpandableFrameToFrame2();
114 Frame->SetParent(this);
116 app->Script("pack %s -side top -expand yes",// -fill both",
117 this->Frame->GetWidgetName());
118 // Add a render widget, attach it to the view frame, and pack
121 if (!this->RenderWidget)
123 this->RenderWidget = vtkKWRenderWidget::New();
125 this->RenderWidget->SetParent(this); //Frame->GetFrame2());
126 this->RenderWidget->Create();
127 this->RenderWidget->CornerAnnotationVisibilityOn();
129 // app->Script("grid %s -row 0 -column 0 -columnspan 2 -sticky nsew -padx 8 -pady 8",
130 app->Script("pack %s -side top -expand y -fill both -padx 2 -pady 2",
131 // app->Script("pack %s -expand y -fill both -anchor c -expand y",
132 this->RenderWidget->GetWidgetName());
133 // this->Script("grid rowconfigure %s 1 -weight 1 -minsize 100",
134 // this->RenderWidget->GetWidgetName());
137 // Create an image viewer
138 // Use the render window and renderer of the renderwidget
140 if (!this->ImageViewer)
142 this->ImageViewer = vtkImageViewer2::New();
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());
151 // The corner annotation has the ability to parse "tags" and fill
152 // them with information gathered from other objects.
153 // For example, let's display the slice and window/level in one corner
154 // by connecting the corner annotation to our image actor and
157 vtkCornerAnnotation *ca = this->RenderWidget->GetCornerAnnotation();
158 ca->SetImageActor(this->ImageViewer->GetImageActor());
159 ca->SetWindowLevel(this->ImageViewer->GetWindowLevel());
160 ca->SetText(2, "<slice>");
161 ca->SetText(3, "<window>\n<level>");
165 // Create a scale to control the slice
167 if (!this->SliceScale)
169 this->SliceScale = vtkKWScale::New();
171 this->SliceScale->SetParent(this); //Frame->GetFrame1());
172 this->SliceScale->Create();
173 // this->SliceScale->SetCommand(this, "SetSliceFromScaleCallback");
175 app->Script("pack %s -side top -expand n -fill x",
176 this->SliceScale->GetWidgetName());
177 //app->Script("grid %s -row 1 -column 1 -sticky nsew -padx 8",
178 //app->Script("pack %s -side right -expand n -fill x -padx 2 -pady 2",
179 // this->SliceScale->GetWidgetName());
180 // this->Script("grid rowconfigure %s 0 -weight 1",
181 // this->SliceScale->GetWidgetName());
183 // Create a menu button to control the orientation
185 vtkKWMenuButtonWithSpinButtonsWithLabel *orientation_menubutton =
186 vtkKWMenuButtonWithSpinButtonsWithLabel::New();
188 orientation_menubutton->SetParent(this); //Frame->GetFrame1());
189 orientation_menubutton->Create();
190 orientation_menubutton->SetLabelText("Orientation:");
191 orientation_menubutton->SetPadX(2);
192 orientation_menubutton->SetPadY(2);
193 orientation_menubutton->SetBorderWidth(2);
194 orientation_menubutton->SetReliefToGroove();
196 app->Script("pack %s -side top -expand n -fill x",
197 orientation_menubutton->GetWidgetName());
199 // this->Script("grid %s -row 1 -column 0",
200 //app->Script("pack %s -side left -anchor nw -expand n -fill x",
201 // orientation_menubutton->GetWidgetName());
202 // this->Script("grid rowconfigure %s 1 -weight 1",
203 // orientation_menubutton->GetWidgetName());
205 vtkKWMenuButton *mb = orientation_menubutton->GetWidget()->GetWidget();
206 vtkKWMenu *menu = OrientationMenu = mb->GetMenu();
208 menu->AddRadioButton("X-Y"); //, this, "SetSliceOrientationToXYCallback");
209 menu->AddRadioButton("X-Z"); //, this, "SetSliceOrientationToXZCallback");
210 menu->AddRadioButton("Y-Z"); //, this, "SetSliceOrientationToYZCallback");
216 // Create a window/level preset selector
217 vtkKWFrameWithLabel *wl_frame = vtkKWFrameWithLabel::New();
218 wl_frame->SetParent(this); //Frame->GetFrame1());
220 wl_frame->SetLabelText("Window/Level Presets");
221 wl_frame->CollapseFrame ();
222 app->Script("pack %s -side top -anchor nw -expand n -fill x -pady 2",
223 wl_frame->GetWidgetName());
225 if (!this->WindowLevelPresetSelector)
227 this->WindowLevelPresetSelector = vtkKWWindowLevelPresetSelector::New();
229 this->WindowLevelPresetSelector->SetParent(wl_frame->GetFrame());
230 this->WindowLevelPresetSelector->Create();
231 this->WindowLevelPresetSelector->ThumbnailColumnVisibilityOn();
235 app->Script("pack %s -side top -anchor nw -expand n -fill x",
236 this->WindowLevelPresetSelector->GetWidgetName());
238 // Create a corner annotation editor
239 this->AnnotationEditor = vtkKWCornerAnnotationEditor::New();
240 this->AnnotationEditor->SetParent(this);
241 this->AnnotationEditor->Create();
242 this->AnnotationEditor->SetRenderWidget(this->RenderWidget);
243 this->AnnotationEditor->GetFrame()->CollapseFrame ();
244 app->Script("pack %s -side top -anchor nw -expand n -fill x",
245 this->AnnotationEditor->GetWidgetName());
248 // Create a simple animation widget
250 vtkKWFrameWithLabel *animation_frame = vtkKWFrameWithLabel::New();
251 animation_frame->SetParent(this); //->GetMainPanelFrame());
252 animation_frame->Create();
253 animation_frame->SetLabelText("Movie Creator");
255 app->Script("pack %s -side top -anchor nw -expand n -fill x -pady 2",
256 animation_frame->GetWidgetName());
258 if (!this->AnimationWidget)
260 this->AnimationWidget = vtkKWSimpleAnimationWidget::New();
262 this->AnimationWidget->SetParent(animation_frame->GetFrame());
263 this->AnimationWidget->Create();
264 this->AnimationWidget->SetRenderWidget(this->RenderWidget);
265 this->AnimationWidget->SetAnimationTypeToSlice();
266 // this->AnimationWidget->SetSliceSetCommand(this, "SetSliceCallback");
267 // this->AnimationWidget->SetSliceGetCommand(this, "GetSliceCallback");
269 app->Script("pack %s -side top -anchor nw -expand n -fill x",
270 this->AnimationWidget->GetWidgetName());
273 this->UpdateSliceRanges();
276 this->AddCallbackCommandObserver( this->SliceScale,
277 vtkKWScale::ScaleValueChangingEvent);
278 this->AddCallbackCommandObserver( menu,
279 vtkKWMenu::MenuItemInvokedEvent);
281 // this->AddCallbackCommandObserver( this->WindowLevelPresetSelector,
283 this->WindowLevelPresetSelector->SetPresetAddCommand(this,
284 "WindowLevelPresetAddCallback");
285 this->WindowLevelPresetSelector->SetPresetApplyCommand(this,
286 "WindowLevelPresetApplyCallback");
287 this->WindowLevelPresetSelector->SetPresetUpdateCommand(
288 this, "WindowLevelPresetUpdateCallback");
289 this->WindowLevelPresetSelector->SetPresetHasChangedCommand(
290 this, "WindowLevelPresetHasChangedCallback");
294 // Deallocate local objects
297 orientation_menubutton->Delete();
298 // wl_frame->Delete();
299 // animation_frame->Delete();
304 //----------------------------------------------------------------------------
305 void vtkKWSlicer::ProcessCallbackCommandEvents(
306 vtkObject *caller, unsigned long event, void *calldata)
308 // std::cout << "###### vtkKWSlicer::ProcessCallbackCommandEvents" << std::endl;
309 if (caller == this->SliceScale &&
310 event == vtkKWScale::ScaleValueChangingEvent)
312 this->SetSliceFromScaleCallback(*((double*)calldata));
314 if (caller == this->OrientationMenu &&
315 event == vtkKWMenu::MenuItemInvokedEvent)
317 int i = *((int*)calldata);
318 // std::cout << i << std::endl;
319 if (i==0) this->SetSliceOrientationToXYCallback();
320 else if (i==1) this->SetSliceOrientationToXZCallback();
321 else if (i==2) this->SetSliceOrientationToYZCallback();
324 // this->SetSliceFromScaleCallback(*((double*)calldata));
328 // We received a notification from the application that its value was
329 // changed. Let's propagate that value to our scale widget
331 if (caller == myapp && event == vtkCommand::ModifiedEvent)
333 this->Scale->SetValue(myapp->GetMyValue());
336 this->Superclass::ProcessCallbackCommandEvents(caller, event, calldata);
338 //----------------------------------------------------------------------------
340 //----------------------------------------------------------------------------
341 void vtkKWSlicer::SetImage(vtkImageData* image)
343 Image = vtkImageData::New();
344 Image->ShallowCopy(image);
347 //----------------------------------------------------------------------------
349 //----------------------------------------------------------------------------
350 void vtkKWSlicer::UpdateImage()
353 if (!this->IsCreated()) return;
354 this->ImageViewer->SetInput(Image);
355 double *range = Image->GetScalarRange();
356 this->ImageViewer->SetColorWindow(range[1] - range[0]);
357 this->ImageViewer->SetColorLevel(0.5 * (range[1] + range[0]));
358 this->RenderWidget->ResetCamera();
359 this->UpdateSliceRanges();
362 //----------------------------------------------------------------------------
364 //----------------------------------------------------------------------------
365 void vtkKWSlicer::SetSliceFromScaleCallback(double value)
367 this->ImageViewer->SetSlice((int)value);
368 this->ImageViewer->Render();
371 //----------------------------------------------------------------------------
372 void vtkKWSlicer::SetSliceCallback(int slice)
374 this->ImageViewer->SetSlice(slice);
377 //----------------------------------------------------------------------------
378 int vtkKWSlicer::GetSliceCallback()
380 return this->ImageViewer->GetSlice();
383 //----------------------------------------------------------------------------
384 int vtkKWSlicer::GetSliceMinCallback()
386 return this->ImageViewer->GetSliceMin();
389 //----------------------------------------------------------------------------
390 int vtkKWSlicer::GetSliceMaxCallback()
392 return this->ImageViewer->GetSliceMax();
395 //----------------------------------------------------------------------------
396 void vtkKWSlicer::UpdateSliceRanges()
398 this->SliceScale->SetRange(
399 this->ImageViewer->GetSliceMin(), this->ImageViewer->GetSliceMax());
400 this->SliceScale->SetValue(this->ImageViewer->GetSlice());
403 this->AnimationWidget->SetSliceRange(
404 this->ImageViewer->GetSliceMin(), this->ImageViewer->GetSliceMax());
408 //----------------------------------------------------------------------------
409 void vtkKWSlicer::SetSliceOrientationToXYCallback()
411 this->ImageViewer->SetSliceOrientationToXY();
412 this->UpdateSliceRanges();
415 //----------------------------------------------------------------------------
416 void vtkKWSlicer::SetSliceOrientationToXZCallback()
418 this->ImageViewer->SetSliceOrientationToXZ();
419 this->UpdateSliceRanges();
422 //----------------------------------------------------------------------------
423 void vtkKWSlicer::SetSliceOrientationToYZCallback()
425 this->ImageViewer->SetSliceOrientationToYZ();
426 this->UpdateSliceRanges();
429 //----------------------------------------------------------------------------
430 void vtkKWSlicer::WindowLevelPresetApplyCallback(int id)
432 if (this->WindowLevelPresetSelector->HasPreset(id))
434 this->ImageViewer->SetColorWindow(
435 this->WindowLevelPresetSelector->GetPresetWindow(id));
436 this->ImageViewer->SetColorLevel(
437 this->WindowLevelPresetSelector->GetPresetLevel(id));
438 this->ImageViewer->Render();
441 //----------------------------------------------------------------------------
442 int vtkKWSlicer::WindowLevelPresetAddCallback()
444 int id = this->WindowLevelPresetSelector->AddPreset();
445 this->WindowLevelPresetUpdateCallback(id);
446 this->WindowLevelPresetSelector->SelectPreset(id);
450 //----------------------------------------------------------------------------
451 void vtkKWSlicer::WindowLevelPresetUpdateCallback(int id)
453 this->WindowLevelPresetSelector->SetPresetWindow(
454 id, this->ImageViewer->GetColorWindow());
455 this->WindowLevelPresetSelector->SetPresetLevel(
456 id, this->ImageViewer->GetColorLevel());
457 this->WindowLevelPresetHasChangedCallback(id);
460 //----------------------------------------------------------------------------
461 void vtkKWSlicer::WindowLevelPresetHasChangedCallback(int id)
463 this->WindowLevelPresetSelector->
464 BuildPresetThumbnailAndScreenshotFromRenderWindow(
465 id, this->RenderWidget->GetRenderWindow());
470 #endif // USE_KWWIDGETS