#ifdef USE_KWWIDGETS #include "vtkKWSlicer.h" #include "vtkCornerAnnotation.h" #include "vtkImageData.h" #include "vtkImageViewer2.h" #include "vtkKWApplication.h" #include "vtkKWFrame.h" #include "vtkKWSplitFrame.h" #include "vtkKWFrameWithLabel.h" #include "vtkKWMenu.h" #include "vtkKWMenuButton.h" #include "vtkKWMenuButtonWithSpinButtons.h" #include "vtkKWMenuButtonWithSpinButtonsWithLabel.h" #include "vtkKWNotebook.h" #include "vtkKWRenderWidget.h" #include "vtkKWScale.h" #include "vtkKWSimpleAnimationWidget.h" #include "vtkKWWindow.h" #include "vtkKWWindowLevelPresetSelector.h" #include "vtkObjectFactory.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkXMLImageDataReader.h" #include "vtkKWCornerAnnotationEditor.h" //#include "vtkKWWidgetsPaths.h" #include "vtkToolkits.h" #include extern "C" int Bbkw_Init(Tcl_Interp *interp); //namespace bbkw { //---------------------------------------------------------------------------- vtkStandardNewMacro( vtkKWSlicer ); vtkCxxRevisionMacro(vtkKWSlicer, "$Revision: 1.3 $"); //---------------------------------------------------------------------------- vtkKWSlicer::vtkKWSlicer() { Bbkw_Init(vtkKWApplication::GetMainInterp ()); this->Frame = NULL; this->RenderWidget = NULL; this->Image = NULL; this->ImageViewer = NULL; this->SliceScale = NULL; this->WindowLevelPresetSelector = NULL; this->AnimationWidget = NULL; } //---------------------------------------------------------------------------- vtkKWSlicer::~vtkKWSlicer() { if (this->Frame) { this->Frame->Delete(); } if (this->SliceScale) { this->SliceScale->Delete(); } if (this->ImageViewer) { this->ImageViewer->Delete(); } if (this->RenderWidget) { this->RenderWidget->Delete(); } if (this->WindowLevelPresetSelector) { this->WindowLevelPresetSelector->Delete(); } if (this->AnnotationEditor) { this->AnnotationEditor->Delete(); } if (this->AnimationWidget) { this->AnimationWidget->Delete(); } } //---------------------------------------------------------------------------- void vtkKWSlicer::CreateWidget() { // Check if already created if (this->IsCreated()) { vtkErrorMacro("class already created"); return; } // Call the superclass to create the whole widget this->Superclass::CreateWidget(); vtkKWApplication *app = this->GetApplication(); // Add a SplitFrame /* Frame = vtkKWSplitFrame::New(); Frame->SetFrame1MinimumSize(150); Frame->SetFrame2MinimumSize(250); Frame->SetOrientationToVertical (); Frame->SetExpandableFrameToFrame2(); Frame->SetParent(this); Frame->Create(); app->Script("pack %s -side top -expand yes",// -fill both", this->Frame->GetWidgetName()); // Add a render widget, attach it to the view frame, and pack */ if (!this->RenderWidget) { this->RenderWidget = vtkKWRenderWidget::New(); } this->RenderWidget->SetParent(this); //Frame->GetFrame2()); this->RenderWidget->Create(); this->RenderWidget->CornerAnnotationVisibilityOn(); // app->Script("grid %s -row 0 -column 0 -columnspan 2 -sticky nsew -padx 8 -pady 8", app->Script("pack %s -side top -expand y -fill both -padx 2 -pady 2", // app->Script("pack %s -expand y -fill both -anchor c -expand y", this->RenderWidget->GetWidgetName()); // this->Script("grid rowconfigure %s 1 -weight 1 -minsize 100", // this->RenderWidget->GetWidgetName()); // Create an image viewer // Use the render window and renderer of the renderwidget if (!this->ImageViewer) { this->ImageViewer = vtkImageViewer2::New(); } this->ImageViewer->SetRenderWindow(this->RenderWidget->GetRenderWindow()); this->ImageViewer->SetRenderer(this->RenderWidget->GetRenderer()); // this->ImageViewer->SetInput(reader->GetOutput()); this->ImageViewer->SetupInteractor( this->RenderWidget->GetRenderWindow()->GetInteractor()); // The corner annotation has the ability to parse "tags" and fill // them with information gathered from other objects. // For example, let's display the slice and window/level in one corner // by connecting the corner annotation to our image actor and // image mapper vtkCornerAnnotation *ca = this->RenderWidget->GetCornerAnnotation(); ca->SetImageActor(this->ImageViewer->GetImageActor()); ca->SetWindowLevel(this->ImageViewer->GetWindowLevel()); ca->SetText(2, ""); ca->SetText(3, "\n"); // Create a scale to control the slice if (!this->SliceScale) { this->SliceScale = vtkKWScale::New(); } this->SliceScale->SetParent(this); //Frame->GetFrame1()); this->SliceScale->Create(); // this->SliceScale->SetCommand(this, "SetSliceFromScaleCallback"); app->Script("pack %s -side top -expand n -fill x", this->SliceScale->GetWidgetName()); //app->Script("grid %s -row 1 -column 1 -sticky nsew -padx 8", //app->Script("pack %s -side right -expand n -fill x -padx 2 -pady 2", // this->SliceScale->GetWidgetName()); // this->Script("grid rowconfigure %s 0 -weight 1", // this->SliceScale->GetWidgetName()); // Create a menu button to control the orientation vtkKWMenuButtonWithSpinButtonsWithLabel *orientation_menubutton = vtkKWMenuButtonWithSpinButtonsWithLabel::New(); orientation_menubutton->SetParent(this); //Frame->GetFrame1()); orientation_menubutton->Create(); orientation_menubutton->SetLabelText("Orientation:"); orientation_menubutton->SetPadX(2); orientation_menubutton->SetPadY(2); orientation_menubutton->SetBorderWidth(2); orientation_menubutton->SetReliefToGroove(); app->Script("pack %s -side top -expand n -fill x", orientation_menubutton->GetWidgetName()); // this->Script("grid %s -row 1 -column 0", //app->Script("pack %s -side left -anchor nw -expand n -fill x", // orientation_menubutton->GetWidgetName()); // this->Script("grid rowconfigure %s 1 -weight 1", // orientation_menubutton->GetWidgetName()); vtkKWMenuButton *mb = orientation_menubutton->GetWidget()->GetWidget(); vtkKWMenu *menu = OrientationMenu = mb->GetMenu(); menu->AddRadioButton("X-Y"); //, this, "SetSliceOrientationToXYCallback"); menu->AddRadioButton("X-Z"); //, this, "SetSliceOrientationToXZCallback"); menu->AddRadioButton("Y-Z"); //, this, "SetSliceOrientationToYZCallback"); mb->SetValue("X-Y"); // Create a window/level preset selector vtkKWFrameWithLabel *wl_frame = vtkKWFrameWithLabel::New(); wl_frame->SetParent(this); //Frame->GetFrame1()); wl_frame->Create(); wl_frame->SetLabelText("Window/Level Presets"); wl_frame->CollapseFrame (); app->Script("pack %s -side top -anchor nw -expand n -fill x -pady 2", wl_frame->GetWidgetName()); if (!this->WindowLevelPresetSelector) { this->WindowLevelPresetSelector = vtkKWWindowLevelPresetSelector::New(); } this->WindowLevelPresetSelector->SetParent(wl_frame->GetFrame()); this->WindowLevelPresetSelector->Create(); this->WindowLevelPresetSelector->ThumbnailColumnVisibilityOn(); app->Script("pack %s -side top -anchor nw -expand n -fill x", this->WindowLevelPresetSelector->GetWidgetName()); // Create a corner annotation editor this->AnnotationEditor = vtkKWCornerAnnotationEditor::New(); this->AnnotationEditor->SetParent(this); this->AnnotationEditor->Create(); this->AnnotationEditor->SetRenderWidget(this->RenderWidget); this->AnnotationEditor->GetFrame()->CollapseFrame (); app->Script("pack %s -side top -anchor nw -expand n -fill x", this->AnnotationEditor->GetWidgetName()); // Create a simple animation widget /* vtkKWFrameWithLabel *animation_frame = vtkKWFrameWithLabel::New(); animation_frame->SetParent(this); //->GetMainPanelFrame()); animation_frame->Create(); animation_frame->SetLabelText("Movie Creator"); app->Script("pack %s -side top -anchor nw -expand n -fill x -pady 2", animation_frame->GetWidgetName()); if (!this->AnimationWidget) { this->AnimationWidget = vtkKWSimpleAnimationWidget::New(); } this->AnimationWidget->SetParent(animation_frame->GetFrame()); this->AnimationWidget->Create(); this->AnimationWidget->SetRenderWidget(this->RenderWidget); this->AnimationWidget->SetAnimationTypeToSlice(); // this->AnimationWidget->SetSliceSetCommand(this, "SetSliceCallback"); // this->AnimationWidget->SetSliceGetCommand(this, "GetSliceCallback"); app->Script("pack %s -side top -anchor nw -expand n -fill x", this->AnimationWidget->GetWidgetName()); */ this->UpdateSliceRanges(); // Callbacks this->AddCallbackCommandObserver( this->SliceScale, vtkKWScale::ScaleValueChangingEvent); this->AddCallbackCommandObserver( menu, vtkKWMenu::MenuItemInvokedEvent); // this->AddCallbackCommandObserver( this->WindowLevelPresetSelector, this->WindowLevelPresetSelector->SetPresetAddCommand(this, "WindowLevelPresetAddCallback"); this->WindowLevelPresetSelector->SetPresetApplyCommand(this, "WindowLevelPresetApplyCallback"); this->WindowLevelPresetSelector->SetPresetUpdateCommand( this, "WindowLevelPresetUpdateCallback"); this->WindowLevelPresetSelector->SetPresetHasChangedCommand( this, "WindowLevelPresetHasChangedCallback"); // Deallocate local objects // reader->Delete(); orientation_menubutton->Delete(); // wl_frame->Delete(); // animation_frame->Delete(); UpdateImage(); } //---------------------------------------------------------------------------- void vtkKWSlicer::ProcessCallbackCommandEvents( vtkObject *caller, unsigned long event, void *calldata) { std::cout << "###### vtkKWSlicer::ProcessCallbackCommandEvents" << std::endl; if (caller == this->SliceScale && event == vtkKWScale::ScaleValueChangingEvent) { this->SetSliceFromScaleCallback(*((double*)calldata)); } if (caller == this->OrientationMenu && event == vtkKWMenu::MenuItemInvokedEvent) { int i = *((int*)calldata); // std::cout << i << std::endl; if (i==0) this->SetSliceOrientationToXYCallback(); else if (i==1) this->SetSliceOrientationToXZCallback(); else if (i==2) this->SetSliceOrientationToYZCallback(); // this->SetSliceFromScaleCallback(*((double*)calldata)); } /* // We received a notification from the application that its value was // changed. Let's propagate that value to our scale widget if (caller == myapp && event == vtkCommand::ModifiedEvent) { this->Scale->SetValue(myapp->GetMyValue()); } */ this->Superclass::ProcessCallbackCommandEvents(caller, event, calldata); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkKWSlicer::SetImage(vtkImageData* image) { Image = vtkImageData::New(); Image->ShallowCopy(image); UpdateImage(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkKWSlicer::UpdateImage() { if (!Image) return; if (!this->IsCreated()) return; this->ImageViewer->SetInput(Image); double *range = Image->GetScalarRange(); this->ImageViewer->SetColorWindow(range[1] - range[0]); this->ImageViewer->SetColorLevel(0.5 * (range[1] + range[0])); this->RenderWidget->ResetCamera(); this->UpdateSliceRanges(); Image->Delete(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkKWSlicer::SetSliceFromScaleCallback(double value) { this->ImageViewer->SetSlice((int)value); this->ImageViewer->Render(); } //---------------------------------------------------------------------------- void vtkKWSlicer::SetSliceCallback(int slice) { this->ImageViewer->SetSlice(slice); } //---------------------------------------------------------------------------- int vtkKWSlicer::GetSliceCallback() { return this->ImageViewer->GetSlice(); } //---------------------------------------------------------------------------- int vtkKWSlicer::GetSliceMinCallback() { return this->ImageViewer->GetSliceMin(); } //---------------------------------------------------------------------------- int vtkKWSlicer::GetSliceMaxCallback() { return this->ImageViewer->GetSliceMax(); } //---------------------------------------------------------------------------- void vtkKWSlicer::UpdateSliceRanges() { this->SliceScale->SetRange( this->ImageViewer->GetSliceMin(), this->ImageViewer->GetSliceMax()); this->SliceScale->SetValue(this->ImageViewer->GetSlice()); /* this->AnimationWidget->SetSliceRange( this->ImageViewer->GetSliceMin(), this->ImageViewer->GetSliceMax()); */ } //---------------------------------------------------------------------------- void vtkKWSlicer::SetSliceOrientationToXYCallback() { this->ImageViewer->SetSliceOrientationToXY(); this->UpdateSliceRanges(); } //---------------------------------------------------------------------------- void vtkKWSlicer::SetSliceOrientationToXZCallback() { this->ImageViewer->SetSliceOrientationToXZ(); this->UpdateSliceRanges(); } //---------------------------------------------------------------------------- void vtkKWSlicer::SetSliceOrientationToYZCallback() { this->ImageViewer->SetSliceOrientationToYZ(); this->UpdateSliceRanges(); } //---------------------------------------------------------------------------- void vtkKWSlicer::WindowLevelPresetApplyCallback(int id) { if (this->WindowLevelPresetSelector->HasPreset(id)) { this->ImageViewer->SetColorWindow( this->WindowLevelPresetSelector->GetPresetWindow(id)); this->ImageViewer->SetColorLevel( this->WindowLevelPresetSelector->GetPresetLevel(id)); this->ImageViewer->Render(); } } //---------------------------------------------------------------------------- int vtkKWSlicer::WindowLevelPresetAddCallback() { int id = this->WindowLevelPresetSelector->AddPreset(); this->WindowLevelPresetUpdateCallback(id); this->WindowLevelPresetSelector->SelectPreset(id); return id; } //---------------------------------------------------------------------------- void vtkKWSlicer::WindowLevelPresetUpdateCallback(int id) { this->WindowLevelPresetSelector->SetPresetWindow( id, this->ImageViewer->GetColorWindow()); this->WindowLevelPresetSelector->SetPresetLevel( id, this->ImageViewer->GetColorLevel()); this->WindowLevelPresetHasChangedCallback(id); } //---------------------------------------------------------------------------- void vtkKWSlicer::WindowLevelPresetHasChangedCallback(int id) { this->WindowLevelPresetSelector-> BuildPresetThumbnailAndScreenshotFromRenderWindow( id, this->RenderWidget->GetRenderWindow()); } //} // namespace kw #endif // USE_KWWIDGETS