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 "vtkKWWidgetsPaths.h"
28 #include "vtkToolkits.h"
30 #include <vtksys/SystemTools.hxx>
34 //----------------------------------------------------------------------------
35 vtkStandardNewMacro( vtkKWSlicer );
36 vtkCxxRevisionMacro(vtkKWSlicer, "$Revision: 1.2 $");
38 //----------------------------------------------------------------------------
39 vtkKWSlicer::vtkKWSlicer()
42 this->RenderWidget = NULL;
44 this->ImageViewer = NULL;
45 this->SliceScale = NULL;
46 this->WindowLevelPresetSelector = NULL;
47 this->AnimationWidget = NULL;
50 //----------------------------------------------------------------------------
51 vtkKWSlicer::~vtkKWSlicer()
55 this->Frame->Delete();
59 this->SliceScale->Delete();
61 if (this->ImageViewer)
63 this->ImageViewer->Delete();
65 if (this->RenderWidget)
67 this->RenderWidget->Delete();
69 if (this->WindowLevelPresetSelector)
71 this->WindowLevelPresetSelector->Delete();
73 if (this->AnimationWidget)
75 this->AnimationWidget->Delete();
79 //----------------------------------------------------------------------------
80 void vtkKWSlicer::CreateWidget()
82 // Check if already created
84 if (this->IsCreated())
86 vtkErrorMacro("class already created");
90 // Call the superclass to create the whole widget
92 this->Superclass::CreateWidget();
94 vtkKWApplication *app = this->GetApplication();
97 Frame = vtkKWSplitFrame::New();
98 Frame->SetFrame1MinimumSize(150);
99 Frame->SetFrame2MinimumSize(250);
100 Frame->SetOrientationToVertical ();
101 Frame->SetExpandableFrameToFrame2();
102 Frame->SetParent(this);
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
108 if (!this->RenderWidget)
110 this->RenderWidget = vtkKWRenderWidget::New();
112 this->RenderWidget->SetParent(Frame->GetFrame2());
113 this->RenderWidget->Create();
114 this->RenderWidget->CornerAnnotationVisibilityOn();
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());
123 // Create a volume reader
125 vtkXMLImageDataReader *reader = vtkXMLImageDataReader::New();
127 char data_path[2048];
128 sprintf(data_path, "%s/Data/head100x100x47.vti", KWWidgets_EXAMPLES_DIR);
129 if (!vtksys::SystemTools::FileExists(data_path))
132 "%s/..%s/Examples/Data/head100x100x47.vti",
133 app->GetInstallationDirectory(), KWWidgets_INSTALL_DATA_DIR);
135 reader->SetFileName(data_path);
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 // Reset the window/level and the camera
154 double *range = reader->GetOutput()->GetScalarRange();
155 this->ImageViewer->SetColorWindow(range[1] - range[0]);
156 this->ImageViewer->SetColorLevel(0.5 * (range[1] + range[0]));
158 this->RenderWidget->ResetCamera();
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
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>");
172 // Create a scale to control the slice
174 if (!this->SliceScale)
176 this->SliceScale = vtkKWScale::New();
178 this->SliceScale->SetParent(Frame->GetFrame1());
179 this->SliceScale->Create();
180 // this->SliceScale->SetCommand(this, "SetSliceFromScaleCallback");
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());
190 // Create a menu button to control the orientation
192 vtkKWMenuButtonWithSpinButtonsWithLabel *orientation_menubutton =
193 vtkKWMenuButtonWithSpinButtonsWithLabel::New();
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();
203 app->Script("pack %s -side top -expand n -fill x",
204 orientation_menubutton->GetWidgetName());
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());
212 vtkKWMenuButton *mb = orientation_menubutton->GetWidget()->GetWidget();
213 vtkKWMenu *menu = OrientationMenu = mb->GetMenu();
215 menu->AddRadioButton("X-Y"); //, this, "SetSliceOrientationToXYCallback");
216 menu->AddRadioButton("X-Z"); //, this, "SetSliceOrientationToXZCallback");
217 menu->AddRadioButton("Y-Z"); //, this, "SetSliceOrientationToYZCallback");
223 // Create a window/level preset selector
225 vtkKWFrameWithLabel *wl_frame = vtkKWFrameWithLabel::New();
226 wl_frame->SetParent(this); //->GetMainPanelFrame());
228 wl_frame->SetLabelText("Window/Level Presets");
230 app->Script("pack %s -side top -anchor nw -expand n -fill x -pady 2",
231 wl_frame->GetWidgetName());
233 if (!this->WindowLevelPresetSelector)
235 this->WindowLevelPresetSelector = vtkKWWindowLevelPresetSelector::New();
237 this->WindowLevelPresetSelector->SetParent(wl_frame->GetFrame());
238 this->WindowLevelPresetSelector->Create();
239 this->WindowLevelPresetSelector->ThumbnailColumnVisibilityOn();
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");
251 app->Script("pack %s -side top -anchor nw -expand n -fill x",
252 this->WindowLevelPresetSelector->GetWidgetName());
254 // Create a simple animation widget
256 vtkKWFrameWithLabel *animation_frame = vtkKWFrameWithLabel::New();
257 animation_frame->SetParent(this); //->GetMainPanelFrame());
258 animation_frame->Create();
259 animation_frame->SetLabelText("Movie Creator");
261 app->Script("pack %s -side top -anchor nw -expand n -fill x -pady 2",
262 animation_frame->GetWidgetName());
264 if (!this->AnimationWidget)
266 this->AnimationWidget = vtkKWSimpleAnimationWidget::New();
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");
275 app->Script("pack %s -side top -anchor nw -expand n -fill x",
276 this->AnimationWidget->GetWidgetName());
278 this->UpdateSliceRanges();
281 this->AddCallbackCommandObserver( this->SliceScale,
282 vtkKWScale::ScaleValueChangingEvent);
283 this->AddCallbackCommandObserver( menu,
284 vtkKWMenu::MenuItemInvokedEvent);
287 // Deallocate local objects
290 orientation_menubutton->Delete();
291 // wl_frame->Delete();
292 // animation_frame->Delete();
297 //----------------------------------------------------------------------------
298 void vtkKWSlicer::ProcessCallbackCommandEvents(
299 vtkObject *caller, unsigned long event, void *calldata)
301 std::cout << "###### vtkKWSlicer::ProcessCallbackCommandEvents" << std::endl;
302 if (caller == this->SliceScale &&
303 event == vtkKWScale::ScaleValueChangingEvent)
305 this->SetSliceFromScaleCallback(*((double*)calldata));
307 if (caller == this->OrientationMenu &&
308 event == vtkKWMenu::MenuItemInvokedEvent)
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();
317 // this->SetSliceFromScaleCallback(*((double*)calldata));
321 // We received a notification from the application that its value was
322 // changed. Let's propagate that value to our scale widget
324 if (caller == myapp && event == vtkCommand::ModifiedEvent)
326 this->Scale->SetValue(myapp->GetMyValue());
329 this->Superclass::ProcessCallbackCommandEvents(caller, event, calldata);
331 //----------------------------------------------------------------------------
333 //----------------------------------------------------------------------------
334 void vtkKWSlicer::SetImage(vtkImageData* image)
336 Image = vtkImageData::New();
337 Image->ShallowCopy(image);
340 //----------------------------------------------------------------------------
342 //----------------------------------------------------------------------------
343 void vtkKWSlicer::UpdateImage()
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();
355 //----------------------------------------------------------------------------
357 //----------------------------------------------------------------------------
358 void vtkKWSlicer::SetSliceFromScaleCallback(double value)
360 this->ImageViewer->SetSlice((int)value);
361 this->ImageViewer->Render();
364 //----------------------------------------------------------------------------
365 void vtkKWSlicer::SetSliceCallback(int slice)
367 this->ImageViewer->SetSlice(slice);
370 //----------------------------------------------------------------------------
371 int vtkKWSlicer::GetSliceCallback()
373 return this->ImageViewer->GetSlice();
376 //----------------------------------------------------------------------------
377 int vtkKWSlicer::GetSliceMinCallback()
379 return this->ImageViewer->GetSliceMin();
382 //----------------------------------------------------------------------------
383 int vtkKWSlicer::GetSliceMaxCallback()
385 return this->ImageViewer->GetSliceMax();
388 //----------------------------------------------------------------------------
389 void vtkKWSlicer::UpdateSliceRanges()
391 this->SliceScale->SetRange(
392 this->ImageViewer->GetSliceMin(), this->ImageViewer->GetSliceMax());
393 this->SliceScale->SetValue(this->ImageViewer->GetSlice());
396 this->AnimationWidget->SetSliceRange(
397 this->ImageViewer->GetSliceMin(), this->ImageViewer->GetSliceMax());
401 //----------------------------------------------------------------------------
402 void vtkKWSlicer::SetSliceOrientationToXYCallback()
404 this->ImageViewer->SetSliceOrientationToXY();
405 this->UpdateSliceRanges();
408 //----------------------------------------------------------------------------
409 void vtkKWSlicer::SetSliceOrientationToXZCallback()
411 this->ImageViewer->SetSliceOrientationToXZ();
412 this->UpdateSliceRanges();
415 //----------------------------------------------------------------------------
416 void vtkKWSlicer::SetSliceOrientationToYZCallback()
418 this->ImageViewer->SetSliceOrientationToYZ();
419 this->UpdateSliceRanges();
422 //----------------------------------------------------------------------------
423 void vtkKWSlicer::WindowLevelPresetApplyCallback(int id)
425 if (this->WindowLevelPresetSelector->HasPreset(id))
427 this->ImageViewer->SetColorWindow(
428 this->WindowLevelPresetSelector->GetPresetWindow(id));
429 this->ImageViewer->SetColorLevel(
430 this->WindowLevelPresetSelector->GetPresetLevel(id));
431 this->ImageViewer->Render();
434 //----------------------------------------------------------------------------
435 int vtkKWSlicer::WindowLevelPresetAddCallback()
437 int id = this->WindowLevelPresetSelector->AddPreset();
438 this->WindowLevelPresetUpdateCallback(id);
439 this->WindowLevelPresetSelector->SelectPreset(id);
443 //----------------------------------------------------------------------------
444 void vtkKWSlicer::WindowLevelPresetUpdateCallback(int id)
446 this->WindowLevelPresetSelector->SetPresetWindow(
447 id, this->ImageViewer->GetColorWindow());
448 this->WindowLevelPresetSelector->SetPresetLevel(
449 id, this->ImageViewer->GetColorLevel());
450 this->WindowLevelPresetHasChangedCallback(id);
453 //----------------------------------------------------------------------------
454 void vtkKWSlicer::WindowLevelPresetHasChangedCallback(int id)
456 this->WindowLevelPresetSelector->
457 BuildPresetThumbnailAndScreenshotFromRenderWindow(
458 id, this->RenderWidget->GetRenderWindow());
463 #endif // USE_KWWIDGETS