X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=lib%2FmaracasVisuLib%2Fsrc%2Finterface%2FwxWindows%2Fwidgets%2Finclude%2FwxImageViewerWidget.cxx;fp=lib%2FmaracasVisuLib%2Fsrc%2Finterface%2FwxWindows%2Fwidgets%2Finclude%2FwxImageViewerWidget.cxx;h=bfed25d066d9e0007338dea5112111e1409dde10;hb=a4ee3758aa0477f677fb981e2c4d6e29995e8db8;hp=0000000000000000000000000000000000000000;hpb=cc20770ee090848c31a8f18c277d89f2b904e087;p=creaMaracasVisu.git diff --git a/lib/maracasVisuLib/src/interface/wxWindows/widgets/include/wxImageViewerWidget.cxx b/lib/maracasVisuLib/src/interface/wxWindows/widgets/include/wxImageViewerWidget.cxx new file mode 100644 index 0000000..bfed25d --- /dev/null +++ b/lib/maracasVisuLib/src/interface/wxWindows/widgets/include/wxImageViewerWidget.cxx @@ -0,0 +1,630 @@ +/*========================================================================= + + Program: wxMaracas + Module: $RCSfile: wxImageViewerWidget.cxx,v $ + Language: C++ + Date: $Date: 2009/05/14 13:54:57 $ + Version: $Revision: 1.1 $ + + Copyright: (c) 2002, 2003 + License: + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notice for more information. + +=========================================================================*/ + +#include "wxImageViewerWidget.h" + +#include "vtkRenderer.h" +#include "vtkRenderWindowInteractor.h" //extremely important with VC++ don't remove ! +#include "vtkCommand.h" +#include "vtkPolyData.h" +#include "vtkCellArray.h" +#include "vtkPolyDataMapper.h" +#include "vtkInteractorObserver.h" +#include "vtkInteractorStyleImage.h" + +#include +#include +#include +#include + +#include +//---------------------------------------------------------------------------- +// Callback for the interaction +class marZoomROIObserver : public vtkCommand{ + public: + virtual char const *GetClassName() const { return "marZoomROIObserver";} + static marZoomROIObserver *New(){ + marZoomROIObserver * result; + result = new marZoomROIObserver; + return result; + } +// PS -> { return new marZoomROIObserver; } + + marZoomROIObserver() { this->ImageViewerWdg = NULL; } + virtual void Execute(vtkObject *wdg, unsigned long event, void* calldata) { + if ( this->ImageViewerWdg ) { + this->ImageViewerWdg->ExecuteEvent(wdg, event, calldata); + } + } + wxImageViewerWidget *ImageViewerWdg; +}; +/** +Most of the class was done thanks to this mail, thank you James !! +http://public.kitware.com/pipermail/vtkusers/2003-April/017063.html +*/ + + + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + +wxVtk2DView_TMP::wxVtk2DView_TMP(vtkImageViewer2 *imageviewer2) +{ + _imageviewer2 = imageviewer2; +} +//---------------------------------------------------------------------------- +wxVtk2DView_TMP::~wxVtk2DView_TMP() +{ +} +//---------------------------------------------------------------------------- +vtkRenderer* wxVtk2DView_TMP::GetRenderer() +{ + return _imageviewer2->GetRenderer(); +} +//---------------------------------------------------------------------------- +vtkRenderWindow* wxVtk2DView_TMP::GetRenWin() +{ + return _imageviewer2->GetRenderWindow(); +} +//---------------------------------------------------------------------------- +void wxVtk2DView_TMP::Configure() // virtual +{ + vtkInteractorStyleBaseView *interactorstylebaseview; + interactorstylebaseview = vtkInteractorStyleBaseView2D::New(); + + SetInteractorStyleBaseView(interactorstylebaseview); + wxVTKRenderWindowInteractor *iren = GetWxVTKRenderWindowInteractor(); + interactorstylebaseview->SetInteractor ( iren ); + iren->SetInteractorStyle(interactorstylebaseview); + interactorstylebaseview->SetwxVtkBaseView(this); +} +//---------------------------------------------------------------------------- +void wxVtk2DView_TMP::SetWxVTKRenderWindowInteractor( wxVTKRenderWindowInteractor *wxVTKiren) +{ + _wxVTKiren = wxVTKiren; +} +//---------------------------------------------------------------------------- +wxVTKRenderWindowInteractor *wxVtk2DView_TMP::GetWxVTKRenderWindowInteractor() // virtual +{ + return _wxVTKiren; +} + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + +wxImageViewerWidget::wxImageViewerWidget(wxWindow* parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) : + wxPanel( parent, id, pos, size, style, name ) +{ + _manContControl = NULL; + _mContourModel = NULL; + _mViewContour = NULL; + _Observer = NULL; + + _state=1; + //vtkOutputWindow::GetInstance()->PromptUserOff(); + _wxVTKiren = new wxVTKRenderWindowInteractorEditContour( this, -1 ); + _imageViewer = vtkImageViewer2::New(); + + wxBoxSizer* sizer_1 = new wxBoxSizer(wxVERTICAL); + sizer_1->Add(_wxVTKiren, 1, wxGROW, 0); + SetAutoLayout(true); + SetSizer(sizer_1); + Layout(); + + _intVtkPanWid = NULL; + + +} + +//---------------------------------------------------------------------------- +wxImageViewerWidget::~wxImageViewerWidget(){ + + //imageViewer->GetInput()->Delete(); + if ( _Observer !=NULL ) { _Observer->Delete(); } + + ///\todo I can't find a way to delete a renderWindow on Win32 + ///\todo The following two lines shouldn't be commented + + if ( _imageViewer !=NULL ) { _imageViewer->Delete(); } + //wxVTKiren->SetRenderWhenDisabled( false ); + + if ( _wxVTKiren !=NULL ) { _wxVTKiren->Delete(); } + + + if ( _manContControl !=NULL ) { delete _manContControl; } + if ( _mContourModel !=NULL ) { delete _mContourModel; } + if ( _mViewContour !=NULL ) { delete _mViewContour; } +} + + +//---------------------------------------------------------------------------- +void wxImageViewerWidget::ConstructVTK(vtkImageData *imageData) +{ + _imageViewer->SetInput ( imageData ); + _imageViewer->SetupInteractor ( _wxVTKiren ); + vtkCamera *camera =_imageViewer->GetRenderer()->GetActiveCamera(); + camera->Zoom(2.5); + _imageViewer->GetRenderer()->ResetCamera (); + +// int ww=2000; +// _imageViewer->GetRenderer()->ResetCameraClippingRange(-ww,ww,-ww,ww,-ww,ww); + + //imageViewer->Render(); //NEVER call it explicitely !!! + + //Some images have a bad range, rescale it by default: + imageData->UpdateInformation(); + imageData->SetUpdateExtent( imageData->GetWholeExtent()); + imageData->Update(); + double *range = imageData->GetScalarRange(); +// _imageViewer->SetColorWindow( range[1] - range[0] ); +// _imageViewer->SetColorLevel( 0.5*(range[1] + range[0]) ); + + _Observer = marZoomROIObserver::New(); + _Observer->ImageViewerWdg = this; + + SetState(1); // observer 1 + AddObserver_1(); + _wxVTKiren->SetObserver(_Observer); + + /** + This doesn't seems to be straight forward to overload left button mouse evtn + as vtkImageViewer2 overload window Level event / which is bind to left + mouse click -> as a hack use Middle mouse, (doesn't seems to usefull) + */ + +// wxVTKiren->GetInteractorStyle()->AddObserver(vtkCommand::LeftButtonPressEvent, _Observer); + + + _manContControl = new manualContourControler(); + _mContourModel = new manualContourModel(); + _mViewContour = new manualViewContour(); + + _manContControl->SetZ(100); + _mViewContour->SetModel(_mContourModel); + wxVtk2DView_TMP *wxvtkbaseview_tmp =new wxVtk2DView_TMP(_imageViewer); + _mViewContour->SetWxVtkBaseView( wxvtkbaseview_tmp ); + _mViewContour->SetRange( 2 ); + _manContControl->SetActive(false); + _manContControl->SetModelView(_mContourModel,_mViewContour); + wxvtkbaseview_tmp->SetWxVTKRenderWindowInteractor(_wxVTKiren); + wxvtkbaseview_tmp->Configure(); + wxvtkbaseview_tmp->GetInteractorStyleBaseView()->AddInteractorStyleMaracas( _manContControl ); + + _interactorStyle2DMaracas = vtkInteractorStyle2DMaracas::New(); + _interactorStyle2DMaracas->SetInteractor ( _wxVTKiren ); + _wxVTKiren->SetInteractorStyle(_interactorStyle2DMaracas); + vtkMaracasImageViewer2Callback *cbk = vtkMaracasImageViewer2Callback::New(); + cbk->IV = _imageViewer; + _interactorStyle2DMaracas->AddObserver( vtkCommand::WindowLevelEvent, cbk); + _interactorStyle2DMaracas->AddObserver( vtkCommand::StartWindowLevelEvent, cbk); + _interactorStyle2DMaracas->AddObserver( vtkCommand::ResetWindowLevelEvent, cbk); + cbk->Delete(); + +} + +//---------------------------------------------------------------------------- +void wxImageViewerWidget::SetState(int state){ + _state=state; + _wxVTKiren->SetState(state); +} +//---------------------------------------------------------------------------- +void wxImageViewerWidget::SetStateManualContour(int state){ + _manContControl->SetState(state); +} +//---------------------------------------------------------------------------- +void wxImageViewerWidget::CreateNewManualContour(){ + _manContControl->CreateNewManualContour(); + _manContControl->SetActive(true); + _mViewContour->Refresh(); + Refresh(); +} +//---------------------------------------------------------------------------- +void wxImageViewerWidget::EraseManualContour(){ + _manContControl->DeleteContour(); +} +//---------------------------------------------------------------------------- + +void wxImageViewerWidget::AddObserver_1(){ + + //wxVTKiren->AddObserver(vtkCommand::MiddleButtonPressEvent, _Observer); + //use interactor style to override -for real- the default behavior + _wxVTKiren->GetInteractorStyle()->AddObserver( vtkCommand::MiddleButtonPressEvent , _Observer); + _wxVTKiren->AddObserver(vtkCommand::MouseMoveEvent, _Observer); + //wxVTKiren->AddObserver(vtkCommand::MiddleButtonReleaseEvent, _Observer); + _wxVTKiren->GetInteractorStyle()->AddObserver( vtkCommand::MiddleButtonReleaseEvent , _Observer); + + //EED _wxVTKiren->AddObserver(vtkCommand::MouseWheelForwardEvent, _Observer); + _wxVTKiren->AddObserver( wxEVT_MOUSEWHEEL+10000 , _Observer); + + //EED _wxVTKiren->AddObserver(vtkCommand::MouseWheelBackwardEvent, _Observer); + _wxVTKiren->AddObserver( wxEVT_MOUSEWHEEL+10001 , _Observer); + +} + + +//---------------------------------------------------------------------------- + +void wxImageViewerWidget::AddObserver_2(){ +/* +// _wxVTKiren->AddObserver(vtkCommand::LeftButtonPressEvent , _Observer); +// _wxVTKiren->AddObserver(vtkCommand::LeftButtonReleaseEvent, _Observer); + + _wxVTKiren->AddObserver(vtkCommand::MiddleButtonPressEvent , _Observer); + _wxVTKiren->AddObserver(vtkCommand::MiddleButtonReleaseEvent, _Observer); + +// _wxVTKiren->AddObserver(vtkCommand::RightButtonPressEvent , _Observer); + _wxVTKiren->AddObserver(vtkCommand::MouseMoveEvent , _Observer); +*/ +} + +//---------------------------------------------------------------------------- + +void wxImageViewerWidget::ExecuteEvent(vtkObject *wdg, unsigned long event, void* calldata){ + if (_state==1) { ExecuteEvent1(wdg,event,calldata); } + if (_state==2) { ExecuteEvent2(wdg,event,calldata); } +} + +//---------------------------------------------------------------------------- + +void wxImageViewerWidget::ExecuteEvent1(vtkObject *wdg, unsigned long event, void* calldata){ + + if ( event == vtkCommand::MiddleButtonPressEvent ){ + }else if ( event == vtkCommand::MouseMoveEvent ){ + } + + if ( event == vtkCommand::MiddleButtonReleaseEvent ){ + //EED } else if ( event == vtkCommand::MouseWheelForwardEvent ){ + } else if ( event == wxEVT_MOUSEWHEEL+10000 ){ + wxMouseEvent mouseEvent; + mouseEvent.m_wheelRotation=130; + if (_intVtkPanWid!=NULL) { _intVtkPanWid->CallBackOnMouseWheel(mouseEvent);} + //EED }else if ( event == vtkCommand::MouseWheelBackwardEvent ){ + }else if ( event == wxEVT_MOUSEWHEEL+10001 ){ + wxMouseEvent mouseEvent; + mouseEvent.m_wheelRotation=-130; + if (_intVtkPanWid!=NULL) { _intVtkPanWid->CallBackOnMouseWheel(mouseEvent);} + } +} + +//---------------------------------------------------------------------------- + +void wxImageViewerWidget::ExecuteEvent2(vtkObject *wdg, unsigned long event, void* calldata){ + int X,Y; + _wxVTKiren->GetEventPosition(X, Y); + if (event==wxEVT_LEFT_DOWN ){ + _manContControl->MouseClickLeft(X,Y); + } + + if (event==wxEVT_RIGHT_DOWN ){ + _manContControl->MouseClickRight(X,Y); + } + + if (event==wxEVT_LEFT_UP){ + _manContControl->MouseReleaseLeft(X,Y); + } + + if (event==wxEVT_LEFT_DCLICK){ + _manContControl->MouseDLeft(X,Y); + } + + if (event==wxEVT_MOTION){ + _manContControl->MouseMove(X,Y); + } + + if (event==WXK_CLEAR){ + _manContControl->DeleteActualMousePoint(X,Y); + } +} + +//---------------------------------------------------------------------------- + +void wxImageViewerWidget::SetImage(vtkImageData* imagedata){ + _imageViewer->SetInput(imagedata); + _imageViewer->Render( ); +} + +//---------------------------------------------------------------------------- +int wxImageViewerWidget::GetNumberOfPointsSplineManualContour(){ + return _manContControl->GetNumberOfPointsSplineManualContour(); +} +//---------------------------------------------------------------------------- +double* wxImageViewerWidget::GetVectorPointsXManualContour(){ + return _manContControl->GetVectorPointsXManualContour(); +} +//---------------------------------------------------------------------------- +double* wxImageViewerWidget::GetVectorPointsYManualContour(){ + return _manContControl->GetVectorPointsYManualContour(); +} +//---------------------------------------------------------------------------- +void wxImageViewerWidget::SetZSlice(int z){ +#if (VTK_MAJOR_VERSION >= 5) + _imageViewer->SetSlice( z ); +#else + _imageViewer->SetZSlice( z ); +#endif + +} +//---------------------------------------------------------------------------- +int wxImageViewerWidget::GetZSlice(){ + return _imageViewer->GetZSlice(); +} +//---------------------------------------------------------------------------- +void wxImageViewerWidget::Render(){ + _imageViewer->Render(); +} + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + + +wxImageViewerWidgetRoi::wxImageViewerWidgetRoi(wxWindow* parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) : + wxImageViewerWidget( parent, id, pos, size, style, name ) +{ + _bboxEnabled = false; + _sliceEnabled = false; + _RoiSelected = false; +} +//---------------------------------------------------------------------------- +wxImageViewerWidgetRoi::~wxImageViewerWidgetRoi() +{ + _pts ->Delete(); + _bboxActor ->Delete(); + _bboxMapper ->Delete(); + _pd ->Delete(); +} +//---------------------------------------------------------------------------- +void wxImageViewerWidgetRoi::GetROI( int extent[6] ) +{ + //retrieve a point + double P[3]; + double Q[3]; + _pts->GetPoint(0, P); + _pts->GetPoint(2, Q); + if (P[0]GetInput()->GetExtent( border ); + + if (extent[0] < border[0]) extent[0]=border[0]; + if (extent[1] > border[1]) extent[1]=border[1]; + if (extent[2] < border[2]) extent[2]=border[2]; + if (extent[3] > border[3]) extent[3]=border[3]; + extent[4] = border[4]; + extent[5] = border[5]; + + //grrrrr do not forget about image with spacing <> 1 !! + double spacing[3]; + _imageViewer->GetInput()->GetSpacing( spacing ); + extent[0] = (int)( extent[0]/spacing[0] ); + extent[1] = (int)( extent[1]/spacing[0] ); + extent[2] = (int)( extent[2]/spacing[1] ); + extent[3] = (int)( extent[3]/spacing[1] ); +// extent[4] /= spacing[2]; +// extent[5] /= spacing[2]; + + //Now we should take care of the difficult cases: + //1. The user forgot to select a region, or want the whole region + //2. The user only click one point (-> extent ~ x,x,y,y !!) + + if(extent[1]<=extent[0] || extent[3]<=extent[2]){ + extent[0] = border[0]; + extent[1] = border[1]; + extent[2] = border[2]; + extent[3] = border[3]; + } +} +//---------------------------------------------------------------------------- +void wxImageViewerWidgetRoi::TransfromeCoordViewWorld(int &X, int &Y, int &Z) +{ + _imageViewer->GetRenderer()->SetDisplayPoint(X, Y, Z); + _imageViewer->GetRenderer()->DisplayToWorld(); + double fP[4]; + _imageViewer->GetRenderer()->GetWorldPoint( fP ); + if ( fP[3] ){ + fP[0] /= fP[3]; + fP[1] /= fP[3]; + fP[2] /= fP[3]; + } + X=(int)(fP[0]); + Y=(int)(fP[1]); + Z=(int)(fP[2]); +} +//---------------------------------------------------------------------------- +void wxImageViewerWidgetRoi::ExecuteEvent(vtkObject *wdg, unsigned long event, void* calldata) +{ + int X, Y, Z=0; + int XX,YY,ZZ; + int slice = _imageViewer->GetZSlice(); + int min,max; + min = _imageViewer->GetWholeZMin(); + max = _imageViewer->GetWholeZMax(); + +// EED Borrame if ( event == vtkCommand::MiddleButtonPressEvent ) { + if ( event == vtkCommand::LeftButtonPressEvent ) { +// Dans l'absolu il faudrait 2 modes, un par defaut celui de imageViewer2 qui semble pas mal +// et un deuxieme pour la manipulation exclusive du polydata 2D... + +// if( wxVTKiren->GetShiftKey () ) + { + //def StartZoom(obj, event): + _wxVTKiren->GetEventPosition( X, Y ); + XX=X; YY=Y; ZZ=Z; + TransfromeCoordViewWorld(XX,YY,ZZ); + _pts->SetPoint(0, XX, YY, ZZ); + _pts->SetPoint(1, XX, YY, ZZ); + _pts->SetPoint(2, XX, YY, ZZ); + _pts->SetPoint(3, XX, YY, ZZ); + + _bboxEnabled = true; + _bboxActor->VisibilityOn(); + + _imageViewer->Render(); + } + } else if ( event == vtkCommand::MouseMoveEvent ){ + if ( _bboxEnabled ){ + _RoiSelected=true; + double p0[3]; + _pts->GetPoint(0, p0); + _wxVTKiren->GetEventPosition(X, Y); + XX=X; YY=Y; ZZ=Z; + TransfromeCoordViewWorld(XX,YY,ZZ); + _pts->SetPoint(1, XX , p0[1] , p0[2]); + _pts->SetPoint(2, XX , YY , p0[2]); + _pts->SetPoint(3, p0[0] , YY , p0[2]); + _imageViewer->Render(); + } + } + if ( event == vtkCommand::LeftButtonReleaseEvent ){ + _bboxEnabled = false; + //EED} else if ( event == vtkCommand::MouseWheelForwardEvent ){ + } else if ( event == wxEVT_MOUSEWHEEL+10000 ){ + +// mouse wheel: +// * if no ctrl or shift is press then 5 slices are done +// * if ctrl is press -> 10 slices are done +// * if shirt id press -> 1 slice is done + + if( _wxVTKiren->GetControlKey () ){ + slice += 10; + } else if( _wxVTKiren->GetShiftKey () ) { + slice++; + } else { + //neither ctrl nor shift has been pressed: + slice += 5; + } + + slice = slice > min ? slice : min; + slice = slice < max ? slice : max; + +#if (VTK_MAJOR_VERSION >= 5) + _imageViewer->SetSlice( slice ); +#else + _imageViewer->SetZSlice( slice ); +#endif + + + //This is not nedeed any more since vtkImageViewer2.cxx -r1.9 + //imageViewer->GetRenderer()->ResetCameraClippingRange(); + + wxMouseEvent mouseEvent; + mouseEvent.m_wheelRotation=130; + if (_intVtkPanWid!=NULL) { + _intVtkPanWid->CallBackOnMouseWheel(mouseEvent); + } + _imageViewer->Render(); + + //EED } else if ( event == vtkCommand::MouseWheelBackwardEvent ){ + } else if ( event == wxEVT_MOUSEWHEEL+10001 ){ + +// _sliceEnabled = false; + if( _wxVTKiren->GetControlKey () ){ + slice -= 10; + } else if( _wxVTKiren->GetShiftKey () ) { + slice--; + } else { + //neither ctrl nor shift has been pressed: + slice -= 5; + slice = (slice /5) * 5; + } + + slice = slice > min ? slice : min; + slice = slice < max ? slice : max; + + +#if (VTK_MAJOR_VERSION >= 5) + _imageViewer->SetSlice( slice ); +#else + _imageViewer->SetZSlice( slice ); +#endif + + + //This is not nedeed any more since vtkImageViewer2.cxx -r1.9 + //imageViewer->GetRenderer()->ResetCameraClippingRange(); + + wxMouseEvent mouseEvent; + mouseEvent.m_wheelRotation=-130; + if (_intVtkPanWid!=NULL) { + _intVtkPanWid->CallBackOnMouseWheel(mouseEvent); + } + _imageViewer->Render(); + + } + +} +//---------------------------------------------------------------------------- +void wxImageViewerWidgetRoi::ConstructVTK(vtkImageData *imageData){ + + wxImageViewerWidget::ConstructVTK(imageData); + _interactorStyle2DMaracas->SetObserver(_Observer); + + //Supporting data for callbacks + _pts = vtkPoints::New(); + _pts->SetNumberOfPoints(4); + _pts->SetPoint(0, -1000 , -1000 , -1000 ); + _pts->SetPoint(1, 1000 , -1000 , 0 ); + _pts->SetPoint(2, 1000 , 1000 , 1000 ); + _pts->SetPoint(3, -1000 , 1000 , 0 ); + + + vtkCellArray *lines = vtkCellArray::New(); + lines->InsertNextCell(5); + lines->InsertCellPoint(0); + lines->InsertCellPoint(1); + lines->InsertCellPoint(2); + lines->InsertCellPoint(3); + lines->InsertCellPoint(0); + + _pd = vtkPolyData::New(); + _pd->SetPoints( _pts ); + _pd->SetLines( lines ); + lines->Delete(); //do not delete lines ?? + + + _bboxActor = vtkActor::New(); + _bboxMapper = vtkPolyDataMapper::New(); + + _bboxMapper->SetInput(_pd); + _bboxMapper->ImmediateModeRenderingOn(); + _bboxActor->SetMapper(_bboxMapper); + _bboxActor->GetProperty()->BackfaceCullingOn(); + _bboxActor->GetProperty()->SetDiffuseColor(1,0,0); + _bboxActor->GetProperty()->SetLineWidth(2); + + _imageViewer->GetRenderer()->AddActor( _bboxActor ); +// _imageViewer->Render( ); + +} + +//---------------------------------------------------------------------------- +bool wxImageViewerWidgetRoi::GetRoiSelected(){ + return _RoiSelected; +}