/*# --------------------------------------------------------------------- # # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image # pour la Sant�) # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton # Previous Authors : Laurent Guigues, Jean-Pierre Roux # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil # # This software is governed by the CeCILL-B license under French law and # abiding by the rules of distribution of free software. You can use, # modify and/ or redistribute the software under the terms of the CeCILL-B # license as circulated by CEA, CNRS and INRIA at the following URL # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html # or in the file LICENSE.txt. # # As a counterpart to the access to the source code and rights to copy, # modify and redistribute granted by the license, users are provided only # with a limited warranty and the software's author, the holder of the # economic rights, and the successive licensors have only limited # liability. # # The fact that you are presently reading this means that you have had # knowledge of the CeCILL-B license and that you accept its terms. # ------------------------------------------------------------------------ */ /*========================================================================= Program: wxMaracas Module: $RCSfile: wxSegmentationFM3DWidget.cxx,v $ Language: C++ Date: $Date: 2012/11/15 14:15:18 $ Version: $Revision: 1.2 $ 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 #include #include #include #include "vtkMarchingCubes.h" #include "vtkPolyDataMapper.h" #include "vtkActor.h" #include "wxSegmentationFM3DWidget.h" //------------------------------------------------------------------- //------------------------------------------------------------------- //------------------------------------------------------------------- BEGIN_EVENT_TABLE( wxSegmentationFM3DWidget, wxPanel ) EVT_MENU( 12121, wxSegmentationFM3DWidget::OnRefreshView ) // EVT_MENU( 12122, wxSegmentationFM3DWidget::OnDClickLeft ) END_EVENT_TABLE( ); wxSegmentationFM3DWidget::wxSegmentationFM3DWidget( wxWindow* parent, marImageData *marimageData ,double voxelSize) : wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL) { _voxelSize = voxelSize; _marimageData = marimageData; _wxvtk3Dbaseview_Clipping3D_C = NULL; _wxvtkmpr3Dview_C = NULL; _wxvtkclipping3Dview_C = NULL; wxSplitterWindow* mainSplitter = new wxSplitterWindow(this,-1); wxSplitterWindow *pnlSplitter = new wxSplitterWindow( mainSplitter , -1); int ww,hh; _MPRWidget2 = new wxMPRWidget2(pnlSplitter,_marimageData,voxelSize); wxPanel * contour3DView = Create3DViewContour( pnlSplitter , _MPRWidget2->GetVtkMPRBaseData()); this->GetSize(&ww,&hh); pnlSplitter -> SplitVertically( _MPRWidget2, contour3DView , 600); //PANEL DE OPERACIONES //------------------------------------------------------------------ wxPanel* panelOperaciones = new wxPanel(mainSplitter, -1); wxFlexGridSizer *fgs = new wxFlexGridSizer(2); fgs->Add( new wxStaticText(panelOperaciones, -1, _T("Fast Marching Controls"))); fgs->Add(new wxStaticText(panelOperaciones, -1, _T(""))); fgs->Add(new wxStaticText(panelOperaciones, -1, _T(""))); fgs->Add(new wxStaticText(panelOperaciones, -1, _T(""))); fgs->Add(new wxStaticText(panelOperaciones, -1, _T("Alpha"))); slAlpha = new wxSlider(panelOperaciones, -1, 50, 1, 400, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_LABELS); fgs->Add(slAlpha); fgs->Add(new wxStaticText(panelOperaciones, -1, _T("Beta"))); slBeta = new wxSlider(panelOperaciones, -1, 128, 0, 800, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_LABELS); fgs->Add(slBeta); btnSegment = new wxButton(panelOperaciones, -1, _T("Segment")); fgs->Add(btnSegment); btnUndo = new wxButton(panelOperaciones, -1, _T("Undo")); fgs->Add(btnUndo); fgs->Add(new wxStaticText(panelOperaciones, -1, _T(""))); fgs->Add(new wxStaticText(panelOperaciones, -1, _T(""))); fgs->Add( new wxStaticText(panelOperaciones, -1, _T("Mesh Controls"))); fgs->Add(new wxStaticText(panelOperaciones, -1, _T(""))); fgs->Add(new wxStaticText(panelOperaciones, -1, _T(""))); fgs->Add(new wxStaticText(panelOperaciones, -1, _T(""))); fgs->Add(new wxStaticText(panelOperaciones, -1, _T("Opacity"))); slVolumeOpacity = new wxSlider(panelOperaciones, -1,50,1,100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_LABELS); fgs->Add(slVolumeOpacity); fgs->Add(new wxStaticText(panelOperaciones, -1, _T("Sigma"))); slSigmaLevel = new wxSlider(panelOperaciones, -1,100,1,300, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_LABELS); fgs->Add(slSigmaLevel); fgs->Add(new wxStaticText(panelOperaciones, -1, _T("Convergence"))); slLaplacianConvergence = new wxSlider(panelOperaciones, -1,3000,1,3000, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_LABELS); fgs->Add(slLaplacianConvergence); fgs->Add(new wxStaticText(panelOperaciones, -1, _T("Iterations"))); slLaplacianIterations = new wxSlider(panelOperaciones, -1,100,1,2000, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_LABELS); fgs->Add(slLaplacianIterations); panelOperaciones->SetSizer(fgs); btnUndo->Disable(); slSigmaLevel->Disable(); slVolumeOpacity->Disable(); slLaplacianConvergence->Disable(); slLaplacianIterations->Disable(); Connect(slAlpha->GetId(), wxEVT_SCROLL_THUMBRELEASE, (wxObjectEventFunction) &wxSegmentationFM3DWidget::OnChangeAlpha); Connect(slBeta->GetId(), wxEVT_SCROLL_THUMBRELEASE, (wxObjectEventFunction) &wxSegmentationFM3DWidget::OnChangeBeta); Connect(btnSegment->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction) &wxSegmentationFM3DWidget::OnBtnSegment); Connect(btnUndo->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction) &wxSegmentationFM3DWidget::OnBtnUndo); Connect(slVolumeOpacity->GetId(), wxEVT_SCROLL_THUMBRELEASE, (wxObjectEventFunction) &wxSegmentationFM3DWidget::OnChangeOpacity); Connect(slSigmaLevel->GetId(), wxEVT_SCROLL_THUMBRELEASE, (wxObjectEventFunction) &wxSegmentationFM3DWidget::OnChangeSigmaLevel); Connect(slLaplacianConvergence->GetId(),wxEVT_SCROLL_THUMBRELEASE, (wxObjectEventFunction) &wxSegmentationFM3DWidget::OnChangeLaplacianConvergence); Connect(slLaplacianIterations->GetId(), wxEVT_SCROLL_THUMBRELEASE, (wxObjectEventFunction) &wxSegmentationFM3DWidget::OnChangeLaplacianIteration); //------------------------------------------------------------------- mainSplitter->SplitVertically(pnlSplitter, panelOperaciones, 600); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL ); sizer->Add(mainSplitter,1, wxGROW,0); pnlSplitter -> SetMinimumPaneSize( 50 ); this -> SetSizer(sizer); // MODELO //------------------------------------------------------------------ alphaValue = 0.5; betaValue = 128; opacityValue = 0.5; convergenceValue = 1; iterationsValue = 100; filtroSegmentacion = new itkFM3D(); //------------------------------------------------------------------ // RENDERIZACION VTK //------------------------------------------------------------------ f_gauss = vtkImageGaussianSmooth::New(); f_laplace = vtkSmoothPolyDataFilter::New(); f_cubes = vtkMarchingCubes::New(); f_mapper = vtkPolyDataMapper::New(); f_cubes->SetInput(f_gauss->GetOutput()); f_cubes->SetValue(0,128); f_laplace->SetInput(f_cubes->GetOutput()); f_mapper->SetInput(f_laplace->GetOutput()); f_mapper->ScalarVisibilityOff(); f_actor = vtkActor::New(); f_actor->SetMapper(f_mapper); f_actor->GetProperty()->SetColor(0.9,0.5,0.5); //------------------------------------------------------------------ } //---------------------------------------------------------------------------- wxSegmentationFM3DWidget::~wxSegmentationFM3DWidget( ) { if (_wxvtk3Dbaseview_Clipping3D_C != NULL) { delete _wxvtk3Dbaseview_Clipping3D_C; } if (_wxvtkmpr3Dview_C != NULL) { delete _wxvtkmpr3Dview_C; } if (_wxvtkclipping3Dview_C != NULL) { delete _wxvtkclipping3Dview_C; } } //---------------------------------------------------------------------------- wxPanel* wxSegmentationFM3DWidget::Create3DViewContour( wxWindow *parent, vtkMPRBaseData *vtkmprbasedata) { wxWindow *wxwindow; wxPanel *panel=new wxPanel(parent,-1); wxSplitterWindow *panelClipping3D = new wxSplitterWindow( panel , -1); _wxvtk3Dbaseview_Clipping3D_C = new wxVtk3DBaseView( panelClipping3D ); _wxvtkclipping3Dview_C = new wxVtkClipping3DView(_wxvtk3Dbaseview_Clipping3D_C); vtkClipping3DDataViewer *vtkclipping3Ddataviewer = new vtkClipping3DDataViewer(); vtkclipping3Ddataviewer->SetVtkMPRBaseData(vtkmprbasedata); vtkclipping3Ddataviewer->Configure(); _wxvtkclipping3Dview_C->SetVtkClipping3DDataViewer(vtkclipping3Ddataviewer); _wxvtkmpr3Dview_C = new wxVtkMPR3DView( _wxvtk3Dbaseview_Clipping3D_C ); vtkMPR3DDataViewer *vtkmpr3Ddataviewer = new vtkMPR3DDataViewer(); vtkmpr3Ddataviewer->SetVtkMPRBaseData(vtkmprbasedata); vtkmpr3Ddataviewer->Configure(); _wxvtkmpr3Dview_C->SetVtkMPR3DDataViewer(vtkmpr3Ddataviewer); wxWindow *window3D = _wxvtk3Dbaseview_Clipping3D_C->GetWxVTKRenderWindowInteractor(); wxPanel *panelControl = new wxPanel(panelClipping3D,-1); wxPanel *controlPanelMPR3D = _wxvtkmpr3Dview_C->CreateControlPanel(panelControl); wxPanel *controlPanelClipping3D = _wxvtkclipping3Dview_C->CreateControlPanel(panelControl); // wxBoxSizer *sizerCtrol = new wxBoxSizer(wxVERTICAL); wxFlexGridSizer *sizerCtrol = new wxFlexGridSizer(1); sizerCtrol->Add(controlPanelMPR3D , 1, wxALL|wxEXPAND, 2); sizerCtrol->Add(controlPanelClipping3D , 1, wxALL|wxEXPAND, 2); panelControl->SetAutoLayout(true); panelControl->SetSizer(sizerCtrol); panelControl->SetSize(400,350); panelControl->Layout(); int ww,hh; wxWindow *pp=this; while (pp->GetParent()!=NULL) pp=pp->GetParent(); pp->GetSize(&ww,&hh); //EEDxx2.4 // panelClipping3D -> SetMinimumPaneSize( -50 ); panelClipping3D -> SplitHorizontally( panelControl,window3D, (int)(hh*0.20) ); wxwindow=panelClipping3D; wxBoxSizer *sizerH1 = new wxBoxSizer(wxHORIZONTAL); sizerH1->Add(wxwindow , 1, wxALL|wxEXPAND, 0); panel->SetAutoLayout(true); panel->SetSizer(sizerH1); panel->SetSize(400,400); panel->Layout(); //EEDxx2.4 // panel->FitInside(); // FitInside(); return panel; } //---------------------------------------------------------------------------- void wxSegmentationFM3DWidget::ConfigureVTK(){ _MPRWidget2->ConfigureVTK(); _wxvtk3Dbaseview_Clipping3D_C -> Configure(); _wxvtkmpr3Dview_C -> Configure(); _wxvtkclipping3Dview_C -> Configure(); vtkInteractorStyle3DView *vtkinteractorstyle3Dview = new vtkInteractorStyle3DView(); vtkinteractorstyle3Dview->SetWxVtkMPR3DView(_wxvtkmpr3Dview_C); vtkinteractorstyle3Dview->SetWxVtkClipping3DView(_wxvtkclipping3Dview_C); _wxvtk3Dbaseview_Clipping3D_C->GetInteractorStyleBaseView()->AddInteractorStyleMaracas( vtkinteractorstyle3Dview ); } //---------------------------------------------------------------------------- vtkMPRBaseData *wxSegmentationFM3DWidget::GetVtkMPRBaseData(){ return _MPRWidget2->GetVtkMPRBaseData(); } //---------------------------------------------------------------------------- vtkPlane2DView *wxSegmentationFM3DWidget::GetVtkPlane2DView() { return _MPRWidget2->GetVtkPlane2DView(); } //---------------------------------------------------------------------------- void wxSegmentationFM3DWidget::OnRefreshView(wxCommandEvent & event) { RefreshView(); } //---------------------------------------------------------------------------- void wxSegmentationFM3DWidget::RefreshView() { this->_MPRWidget2->RefreshView(); _wxvtkmpr3Dview_C -> RefreshView(); _wxvtkclipping3Dview_C -> Refresh(); _wxvtk3Dbaseview_Clipping3D_C -> Refresh(); } /** * This method is invoked when the segmentation button is pressed * */ void wxSegmentationFM3DWidget::OnBtnSegment(wxCommandEvent& event){ wxBusyCursor wait; double x =_MPRWidget2->GetVtkMPRBaseData()->GetX(); double y =_MPRWidget2->GetVtkMPRBaseData()->GetY(); double z = _MPRWidget2->GetVtkMPRBaseData()->GetZ(); filtroSegmentacion->AddSeed(x,y,z); filtroSegmentacion->SetAlpha(this->alphaValue); filtroSegmentacion->SetBeta(this->betaValue); vtkImageData* resultado = filtroSegmentacion->segment(_MPRWidget2->GetVtkMPRBaseData()->GetImageData() ); f_gauss->SetInput(resultado); f_gauss->SetStandardDeviation(this->sigmaValue); f_laplace->SetNumberOfIterations(this->iterationsValue); f_laplace->SetConvergence(this->convergenceValue); f_laplace->Update(); f_actor->GetProperty()->SetOpacity(this->opacityValue); vtkRenderer *ren = _wxvtkmpr3Dview_C->GetWxvtk3Dbaseview()->GetRenderer(); ren->AddActor(f_actor); RefreshView(); btnUndo->Enable(); slVolumeOpacity->Enable(); slSigmaLevel->Enable(); slLaplacianConvergence->Enable(); slLaplacianIterations->Enable(); } /** * This method is invoked when the slAlpha scroll change its value * */ void wxSegmentationFM3DWidget::OnChangeAlpha(wxScrollEvent& event){ alphaValue = ((double)slAlpha->GetValue()); alphaValue = alphaValue / 100; } /** * This method is invoked when the slBeta scroll change its value * */ void wxSegmentationFM3DWidget::OnChangeBeta(wxScrollEvent& event){ betaValue = ((double)slBeta->GetValue()); } /** * Carga la imagen resultado de la segmentacion FM ITK * */ void wxSegmentationFM3DWidget::OnBtnUndo(wxCommandEvent& event){ if (f_actor != NULL){ vtkRenderer *ren = _wxvtkmpr3Dview_C->GetWxvtk3Dbaseview()->GetRenderer(); ren->RemoveActor(f_actor); RefreshView(); btnUndo->Disable(); slSigmaLevel->Disable(); slVolumeOpacity->Disable(); slLaplacianConvergence->Disable(); slLaplacianIterations->Disable(); } } /** * Este metodo cambia la opacidad del actor que representa la segmentacion realizada * */ void wxSegmentationFM3DWidget::OnChangeOpacity(wxScrollEvent& event){ if (f_actor != NULL){ opacityValue = ((double)slVolumeOpacity->GetValue())/100.0; f_actor->GetProperty()->SetOpacity(opacityValue); RefreshView(); } } /** * Cambia el valor de la desviacion estandar del filtro gaussiano aplicado al * volumen resultado de la segmentacion */ void wxSegmentationFM3DWidget::OnChangeSigmaLevel(wxScrollEvent& event){ if(f_actor != NULL){ this->sigmaValue = ((double)slSigmaLevel->GetValue())/300.0; f_gauss->SetStandardDeviation(this->sigmaValue); f_laplace->Update(); RefreshView(); } } /** * Cambia el valor de la convergencia del filtro de suavizado laplaciano aplicado * a la superficie que representa el volumen resultado de la segmentacion */ void wxSegmentationFM3DWidget::OnChangeLaplacianConvergence(wxScrollEvent& event){ if(f_actor != NULL){ this->convergenceValue = ((double)slLaplacianConvergence->GetValue())/3000.0; f_laplace->SetConvergence(this->convergenceValue); f_laplace->Update(); RefreshView(); } } /** * Cambia el numero de iteraciones del filtro de suavizado laplaciano aplicado a la superficie * que representa el volumen resultado de la segmentacion */ void wxSegmentationFM3DWidget::OnChangeLaplacianIteration(wxScrollEvent& event){ if(f_actor != NULL){ this->iterationsValue = slLaplacianIterations->GetValue(); f_laplace->SetNumberOfIterations(this->iterationsValue); f_laplace->Update(); RefreshView(); } } // EOF - wxSegmentationFM3DWidget.cxx