/*# --------------------------------------------------------------------- # # 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. # ------------------------------------------------------------------------ */ #include "wxPanelCuttingImageData.h" //------------------------------------------------------------------- #include #include #include //------------------------------------------------------------------- //------------------------------------------------------------------- wxPanelCuttingImageData::wxPanelCuttingImageData (wxWindow *parent) : wxPanel( parent, -1) { _imageData=NULL; _histogrammeVector=NULL; _wxvtk3Dbaseview=NULL; _wxvtkbaseView=NULL; CreateInterface(); CreateModel(); Create3DViewObjects(); } //------------------------------------------------------------------- wxPanelCuttingImageData::~wxPanelCuttingImageData() { delete _modelCube; delete _modelSphere; delete _modelCylinder; _vtkcube -> Delete(); _vtksphere -> Delete(); _vtkcylinder -> Delete(); _cubeMapper -> Delete(); _sphereMapper -> Delete(); _cylinderMapper -> Delete(); _cubeActor -> Delete(); _sphereActor -> Delete(); _cylinderActor -> Delete(); // _xyplot->RemoveAllInputs(); _xyplot -> Delete(); _histogrammeVector->Delete(); _renplotter->Delete(); if(_wxvtkbaseView!=NULL){ delete _wxvtkbaseView; } //delete _vtkclipping3Ddataviewer; //fclose(file); } //------------------------------------------------------------------- void wxPanelCuttingImageData::RemoveActors() { _wxvtk3Dbaseview->GetRenderer()->RemoveActor( _actualActor ); } //------------------------------------------------------------------- void wxPanelCuttingImageData::SetWxVtk3DBaseView( wxVtk3DBaseView * wxvtk3Dbaseview ) { _wxvtk3Dbaseview=wxvtk3Dbaseview; } //------------------------------------------------------------------- void wxPanelCuttingImageData::SetVtkClipping3DDataViewer( vtkClipping3DDataViewer *vtkclipping3Ddataviewer ) { this->_vtkclipping3Ddataviewer = vtkclipping3Ddataviewer; } //------------------------------------------------------------------- void wxPanelCuttingImageData::Create3DViewObjects() { // Sphere _vtksphere = vtkSphereSource::New(); _vtksphere->SetThetaResolution (20); _vtksphere->SetPhiResolution (20); _sphereMapper = vtkPolyDataMapper::New(); _sphereMapper->SetInput( _vtksphere->GetOutput() ); _sphereActor = vtkActor::New(); _sphereActor->SetMapper(_sphereMapper); _sphereActor->SetOrigin(0, 0, 0); _sphereActor->SetPosition(0, 0, 0); _sphereActor->GetProperty()->SetColor(1, 0, 0); _sphereActor->SetUserTransform( _modelSphere->GetVtkTransform() ); // cube _vtkcube = vtkCubeSource::New(); _vtkcube->SetXLength (1); _vtkcube->SetYLength (1); _vtkcube->SetZLength (1); _cubeMapper = vtkPolyDataMapper::New(); _cubeMapper->SetInput( _vtkcube->GetOutput() ); _cubeActor = vtkActor::New(); _cubeActor->SetMapper(_cubeMapper); _cubeActor->SetOrigin(0, 0, 0); _cubeActor->SetPosition(0, 0, 0); _cubeActor->GetProperty()->SetColor(1, 0, 0); _cubeActor->SetUserTransform( _modelCube->GetVtkTransform() ); // cylinder _vtkcylinder = vtkCylinderSource::New(); _vtkcylinder->SetResolution(20); _cylinderMapper = vtkPolyDataMapper::New(); _cylinderMapper->SetInput( _vtkcylinder->GetOutput() ); _cylinderActor = vtkActor::New(); _cylinderActor->SetMapper(_cylinderMapper); _cylinderActor->SetOrigin(0, 0, 0); _cylinderActor->SetPosition(0, 0, 0); _cylinderActor->GetProperty()->SetColor(1, 0, 0); _cylinderActor->SetUserTransform( _modelCylinder->GetVtkTransform() ); } //------------------------------------------------------------------- void wxPanelCuttingImageData::CreateModel() { _modelCube = new figureCuttingCubeModel(); _modelSphere = new figureCuttingSphereModel(); _modelCylinder = new figureCuttingCylinderModel(); // _modelCube->SetVtkTransform( _modelCube->GetVtkTransform() ); // _modelSphere->SetVtkTransform( _modelSphere->GetVtkTransform() ); // _modelCylinder->SetVtkTransform( _modelCylinder->GetVtkTransform() ); } //------------------------------------------------------------------- void wxPanelCuttingImageData::InitHistogramme() { double rangeA[2]; if (_imageData==NULL) { rangeA[1]=1; } else { _imageData->GetScalarRange(rangeA); } _xyplot->RemoveAllInputs(); /* if ( _histogrammeVector!=NULL ) { _histogrammeVector -> Delete(); } */ _histogrammeVector = vtkImageData::New(); _histogrammeVector -> SetDimensions ( (int)(rangeA[1]),1,1 ); _histogrammeVector -> SetScalarTypeToUnsignedShort(); _histogrammeVector -> AllocateScalars(); _histogrammeVector -> Update(); unsigned short *p_vol = (unsigned short*)_histogrammeVector->GetScalarPointer(0,0,0); int i,size = (int) (rangeA[1]); for (i=0; i < size; i++) { *p_vol=0; p_vol++; } _xyplot->SetXRange(0, rangeA[1]); _xyplot->SetYRange(0, 10); _xyplot->AddInput( _histogrammeVector ); } //------------------------------------------------------------------- wxWindow *wxPanelCuttingImageData::CreatePlotHistogrammeInterface() { _xyplot = vtkXYPlotActor::New(); InitHistogramme(); _xyplot->GetPositionCoordinate()->SetValue(0.00, 0.00, 0); _xyplot->GetPosition2Coordinate()->SetValue(1.0, 1.00, 0); //relative to Position _xyplot->SetXValuesToArcLength(); _xyplot->SetNumberOfXLabels(6); _xyplot->SetTitle("Histogramme"); _xyplot->SetXTitle("Gray level"); _xyplot->SetYTitle("Occurrences "); _xyplot->GetProperty()->SetColor(1, 0, 0); _xyplot->GetProperty()->SetPointSize(2); vtkTextProperty *tprop = _xyplot->GetTitleTextProperty(); tprop->SetColor( 1,0,1 ); tprop->BoldOff (); _xyplot->SetAxisTitleTextProperty(tprop); _xyplot->SetAxisLabelTextProperty(tprop); _xyplot->PlotPointsOn(); _xyplot->GetProperty()->SetPointSize(3); _wxvtkbaseView = new wxVtkBaseView(this); _wxvtkbaseView->Configure(); _renplotter = vtkRenderer::New(); vtkRenderWindow *renWin = _wxvtkbaseView->GetRenWin(); renWin->AddRenderer( _renplotter ); _renplotter->AddActor2D( _xyplot ); return _wxvtkbaseView->GetWxVTKRenderWindowInteractor(); } //------------------------------------------------------------------- void wxPanelCuttingImageData::CreateInterface() { SetSize(300,500); wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL); // Principal sizer wxBoxSizer *sizerH0 = new wxBoxSizer(wxHORIZONTAL ); // type of segmentation figure wxBoxSizer *sizerH2 = new wxBoxSizer(wxHORIZONTAL ); // scale wxBoxSizer *sizerH3 = new wxBoxSizer(wxHORIZONTAL ); // rotation wxBoxSizer *sizerH4 = new wxBoxSizer(wxHORIZONTAL ); // intern extern wxBoxSizer *sizerH5 = new wxBoxSizer(wxHORIZONTAL ); // Isovalue wxBoxSizer *sizerH6 = new wxBoxSizer(wxHORIZONTAL ); // Buttons wxFlexGridSizer *sizerH7 = new wxFlexGridSizer(2 ); // Volumic information _typeFig = new wxChoice(this,-1); _opacityFig = new wxSlider(this,-1,100,0,100, wxDefaultPosition, wxSize(200,45), wxSL_HORIZONTAL | wxSL_LABELS); _scaleX = new wxSlider(this,-1,6,0,500 , wxDefaultPosition, wxSize(200,45), wxSL_HORIZONTAL | wxSL_LABELS); _scaleY = new wxSlider(this,-1,20,0,500 , wxDefaultPosition, wxSize(200,45), wxSL_HORIZONTAL | wxSL_LABELS); _scaleZ = new wxSlider(this,-1,7,0,500 , wxDefaultPosition, wxSize(200,45), wxSL_HORIZONTAL | wxSL_LABELS); _rotationX = new wxSlider(this,-1,0,-360,360, wxDefaultPosition, wxSize(200,45), wxSL_HORIZONTAL | wxSL_LABELS); _rotationY = new wxSlider(this,-1,0,-360,360, wxDefaultPosition, wxSize(200,45), wxSL_HORIZONTAL | wxSL_LABELS); _rotationZ = new wxSlider(this,-1,0,-360,360, wxDefaultPosition, wxSize(200,45), wxSL_HORIZONTAL | wxSL_LABELS); _volIntern = new wxRadioButton(this,-1, _T("Volume intern " )); _volExtern = new wxRadioButton(this,-1, _T("Volume extern " )); _histogrammeAccumulated = new wxCheckBox(this,-1,_T("Histogramme accumulated")); _isoValue = new wxSlider(this,-1, 200, 0,2000, wxDefaultPosition, wxSize(200,45), wxSL_HORIZONTAL | wxSL_LABELS); _valueBeforeIsoValue = new wxSlider(this,-1,-1,-1,2000, wxDefaultPosition, wxSize(200,45), wxSL_HORIZONTAL | wxSL_LABELS); _valueAfterIsoValue = new wxSlider(this,-1,-1,-1,2000, wxDefaultPosition, wxSize(200,45), wxSL_HORIZONTAL | wxSL_LABELS); wxButton *btnExtract = new wxButton(this, -1,_T("Extract")); _infoToVo = new wxStaticText(this,-1,_T("########################")); _infoSuVoA = new wxStaticText(this,-1,_T("############")); _infoSuVo = new wxStaticText(this,-1,_T("############")); _infoPixLe = new wxStaticText(this,-1,_T("############")); _infoPixHi = new wxStaticText(this,-1,_T("############")); _typeFig->Append(_T("Cylindre")); _typeFig->Append(_T("Cube")); _typeFig->Append(_T("Sphere")); _typeFig->SetSelection(0); _volIntern->SetValue(true); Connect(_typeFig->GetId() , wxEVT_COMMAND_CHOICE_SELECTED , (wxObjectEventFunction) &wxPanelCuttingImageData::OnTypeFig ); Connect(_opacityFig->GetId() , wxEVT_COMMAND_SLIDER_UPDATED , (wxObjectEventFunction) &wxPanelCuttingImageData::OnOpacityFig ); Connect(_rotationX->GetId() , wxEVT_COMMAND_SLIDER_UPDATED , (wxObjectEventFunction) &wxPanelCuttingImageData::OnTransform ); Connect(_rotationY->GetId() , wxEVT_COMMAND_SLIDER_UPDATED , (wxObjectEventFunction) &wxPanelCuttingImageData::OnTransform ); Connect(_rotationZ->GetId() , wxEVT_COMMAND_SLIDER_UPDATED , (wxObjectEventFunction) &wxPanelCuttingImageData::OnTransform ); Connect(_scaleX->GetId() , wxEVT_COMMAND_SLIDER_UPDATED , (wxObjectEventFunction) &wxPanelCuttingImageData::OnTransform ); Connect(_scaleY->GetId() , wxEVT_COMMAND_SLIDER_UPDATED , (wxObjectEventFunction) &wxPanelCuttingImageData::OnTransform ); Connect(_scaleZ->GetId() , wxEVT_COMMAND_SLIDER_UPDATED , (wxObjectEventFunction) &wxPanelCuttingImageData::OnTransform ); Connect(btnExtract->GetId() , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &wxPanelCuttingImageData::OnExtract ); // wxStaticText *text=new wxStaticText(this,-1, " "); sizerH0 -> Add( new wxStaticText(this,-1, _T("Fig. Type: "),wxDefaultPosition, wxSize(50,20)) ,1,wxALL ,0); sizerH0 -> Add( _typeFig ,1,wxALL ,0); sizerH0 -> Add( _opacityFig ,1,wxALL|wxEXPAND ,0); sizerH2 -> Add( new wxStaticText(this,-1,_T("Scale : ")) ,1,wxALL ,0); sizerH2 -> Add( _scaleX ,1,wxALL | wxEXPAND ,0 ); sizerH2 -> Add( _scaleY ,1,wxALL | wxEXPAND ,0 ); sizerH2 -> Add( _scaleZ ,1,wxALL | wxEXPAND ,0 ); sizerH3 -> Add( new wxStaticText(this,-1,_T("Rotation : ")) ,1,wxALL ,0); sizerH3 -> Add( _rotationX ,1,wxALL | wxEXPAND ,0 ); sizerH3 -> Add( _rotationY ,1,wxALL | wxEXPAND ,0 ); sizerH3 -> Add( _rotationZ ,1,wxALL | wxEXPAND ,0 ); sizerH4 -> Add( new wxStaticText(this,-1,_T("Intern / Extern : ")) ,1,wxALL ,0); sizerH4 -> Add( _volIntern ,1,wxALL ,0); sizerH4 -> Add( new wxStaticText(this,-1, _T(" ")) ,1,wxALL ,0); sizerH4 -> Add( _volExtern ,1,wxALL ,0); sizerH5 -> Add( new wxStaticText(this,-1,_T("Isovalue ")) ,1,wxALL ,0); sizerH5 -> Add( _isoValue ,1,wxALL | wxEXPAND ,0 ); sizerH5 -> Add( _valueBeforeIsoValue ,1,wxALL | wxEXPAND ,0 ); sizerH5 -> Add( _valueAfterIsoValue ,1,wxALL | wxEXPAND ,0 ); sizerH6 -> Add( new wxStaticText(this,-1, _T(" ")) ,1,wxALL ,0); sizerH6 -> Add( btnExtract ,1,wxALL ,0); sizerH7 -> Add( new wxStaticText(this,-1,_T("Total Volume: "), wxDefaultPosition, wxSize(200,12)) , 1 , wxALL ,0); sizerH7 -> Add( _infoToVo , 1 , wxALL ,0); sizerH7 -> Add( new wxStaticText(this,-1,_T("SubVolume: "), wxDefaultPosition, wxSize(200,12) ) , 1 , wxALL ,0); sizerH7 -> Add( _infoSuVo , 1 , wxALL ,0); sizerH7 -> Add( new wxStaticText(this,-1,_T("SubVolume (ana.): "), wxDefaultPosition, wxSize(200,12)) , 1 , wxALL ,0); sizerH7 -> Add( _infoSuVoA , 1 , wxALL ,0); sizerH7 -> Add( new wxStaticText(this,-1,_T("Pix < isovalue: ") , wxDefaultPosition, wxSize(200,12)) , 1 , wxALL ,0); sizerH7 -> Add( _infoPixLe , 1 , wxALL ,0); sizerH7 -> Add( new wxStaticText(this,-1,_T("Pix > isovalue: "), wxDefaultPosition, wxSize(200,12)) , 1 , wxALL ,0); sizerH7 -> Add( _infoPixHi , 1 , wxALL ,0); // sizerH7 -> SetMinSize(300, 120); // Figure type topsizer -> Add( sizerH0 ,1,wxALL|wxEXPAND ,0); // Scale topsizer -> Add( sizerH2 ,1,wxALL|wxEXPAND ,0); // Rotation topsizer -> Add( sizerH3 ,1,wxALL|wxEXPAND ,0); // Intern / Extern topsizer -> Add( sizerH4 ,1,wxALL ,0); // Isovalue limite topsizer -> Add( sizerH5 ,1,wxALL |wxEXPAND ,0); // btn Extraction topsizer -> Add( sizerH6 , 1 , wxALL ,0); // Histograme topsizer -> Add( _histogrammeAccumulated ,1, wxALL ,0); // Volumic information topsizer -> Add( sizerH7 , 1 , wxALL|wxEXPAND ,0); // wxBoxSizer *sizerHor = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *sizerHor = new wxBoxSizer(wxVERTICAL); sizerHor -> Add( topsizer , 1 , wxALL | wxEXPAND ,0); wxWindow *panelPlotHistogramme = CreatePlotHistogrammeInterface(); sizerHor -> Add( panelPlotHistogramme , 1 , wxGROW ,0); this->SetAutoLayout(true); this->SetSizer( sizerHor ); this->Layout(); //EEDxx2.4 // this->FitInside(); } //------------------------------------------------------------------- void wxPanelCuttingImageData::OnExtract(wxCommandEvent& event) { wxBusyCursor wait; bool inside; bool volInt, volExt; int xx,yy,zz; unsigned short *pOrg; unsigned short *p_histogramme; int dim[3]; double spc[3]; long int contAfter = 0; long int contBefor = 0; double min=999999999; double max=-999999999; volExt=_volExtern->GetValue(); volInt=_volIntern->GetValue(); int isoValue = _isoValue->GetValue(); int valueBeforeIsoValue = _valueBeforeIsoValue->GetValue(); int valueAfterIsoValue = _valueAfterIsoValue ->GetValue(); InitHistogramme(); p_histogramme = (unsigned short*)_histogrammeVector->GetScalarPointer(0,0,0); _imageData->GetDimensions(dim); _imageData->GetSpacing(spc); _actualCuttingModel->CalculeInversMatrix(); for (xx=0;xxIfPointInside(xx,yy,zz); if ( ((inside==true)&&(volInt==true)) || ((!inside==true)&&(volExt==true)) ) { pOrg=(unsigned short*)_imageData->GetScalarPointer (xx,yy,zz); if ((*pOrg)max) max=*pOrg; } // if inside } // for zz } // for yy } // for xx // Information wxString infoToVo; wxString infoSuVo; wxString infoSuVoA; wxString infoPixLe; wxString infoPixHi; double volumeUnit = spc[0]*spc[1]*spc[2]; long int totalSubVolume = contBefor + contAfter; double contBeforPorc = 100*(double)contBefor/(double)totalSubVolume; double contAfterPorc = 100*(double)contAfter/(double)totalSubVolume; infoToVo.Printf(_T("%dx%dx%d = %d"),dim[0],dim[1],dim[2], dim[0]*dim[1]*dim[2] ); infoSuVo.Printf(_T("%ld") , totalSubVolume); infoSuVoA.Printf(_T("%.2f"), _actualCuttingModel->GetTheoricVolume() ); infoPixLe.Printf(_T("%ld pix. (%.2f %s) - %.2f mm^3"),contBefor, contBeforPorc ,_T("%"),contBefor*volumeUnit); infoPixHi.Printf(_T("%ld pix. (%.2f %s) - %.2f mm^3"),contAfter, contAfterPorc ,_T("%"),contAfter*volumeUnit); _infoToVo->SetLabel(infoToVo); _infoSuVo->SetLabel(infoSuVo); _infoSuVoA->SetLabel(infoSuVoA); _infoPixLe->SetLabel(infoPixLe); _infoPixHi->SetLabel(infoPixHi); // Histogram if ( _histogrammeAccumulated->GetValue()==true ) { int dimHist[3]; _histogrammeVector -> GetDimensions ( dimHist ); int i,size=dimHist[0]; for (i=1; i<=size; i++) { p_histogramme[i] = p_histogramme[i] + p_histogramme[i-1]; } } double range[2]; _histogrammeVector->Update(); _histogrammeVector->GetScalarRange(range); _xyplot->SetYRange( 0 , range[1] ); _xyplot->SetXRange( min , max ); _vtkclipping3Ddataviewer->RefreshSurface(); _wxvtkbaseView->Refresh(); // _wxvtkbaseView->RefreshView(); wxCommandEvent newevent1(wxEVT_COMMAND_MENU_SELECTED,12121); // Refresh _wxvtkbaseView->GetWxVTKRenderWindowInteractor()->GetParent()->ProcessEvent(newevent1); } //------------------------------------------------------------------- void wxPanelCuttingImageData::OnTypeFig(wxCommandEvent& event) { _wxvtk3Dbaseview->GetRenderer()->RemoveActor( _actualActor ); if (_typeFig->GetSelection()==0){ _actualCuttingModel=_modelCylinder; _actualActor=_cylinderActor; } if (_typeFig->GetSelection()==1){ _actualCuttingModel=_modelCube; _actualActor=_cubeActor; } if (_typeFig->GetSelection()==2){ _actualCuttingModel=_modelSphere; _actualActor=_sphereActor; } _wxvtk3Dbaseview->GetRenderer()->AddActor( _actualActor ); RefreshOpacity(); RefreshView(); } //------------------------------------------------------------------- void wxPanelCuttingImageData::RefreshOpacity() { double op= _opacityFig->GetValue()/100.0; _actualActor->GetProperty()->SetOpacity( op ); } //------------------------------------------------------------------- void wxPanelCuttingImageData::OnOpacityFig(wxScrollEvent& event) { RefreshOpacity(); Refresh(); } //------------------------------------------------------------------- void wxPanelCuttingImageData::RefreshView() { SetParamsOfTransformation( ); Refresh(); } //------------------------------------------------------------------- void wxPanelCuttingImageData::Refresh() { _wxvtk3Dbaseview->Refresh(); } //------------------------------------------------------------------- void wxPanelCuttingImageData::SetParamsOfTransformation( ) { double spc[3]; vtkImageData *vtkimagedata = _vtkmprbasedata->GetImageData(); vtkimagedata->GetSpacing(spc); int px = (int) (_vtkmprbasedata->GetX() ); int py = (int) (_vtkmprbasedata->GetY() ); int pz = (int) (_vtkmprbasedata->GetZ() ); int sx = (int) (_scaleX->GetValue() * spc[0] ); int sy = (int) (_scaleY->GetValue() * spc[1] ); int sz = (int) (_scaleZ->GetValue() * spc[2] ); _actualCuttingModel -> SetScale ( sx , sy , sz ); _actualCuttingModel -> SetPosition ( px , py , pz ); _actualCuttingModel -> SetRotation ( _rotationX->GetValue() , _rotationY->GetValue() , _rotationZ->GetValue() ); _actualCuttingModel -> SetSpacing ( spc[0] , spc[1] , spc[2] ); _actualCuttingModel -> CalculeMatrix(); } //------------------------------------------------------------------- void wxPanelCuttingImageData::OnTransform(wxScrollEvent& event) { RefreshView(); } //------------------------------------------------------------------- void wxPanelCuttingImageData::SetVtkMPRBaseData( vtkMPRBaseData *vtkmprbasedata ) { _vtkmprbasedata = vtkmprbasedata; _imageData = _vtkmprbasedata->GetImageData(); } //------------------------------------------------------------------- void wxPanelCuttingImageData::Configure() { _actualCuttingModel=_modelCylinder; _actualActor=_cylinderActor; _wxvtk3Dbaseview->GetRenderer()->AddActor( _actualActor ); SetParamsOfTransformation(); RefreshView(); }