From: Juan Prieto Date: Wed, 5 Oct 2011 16:26:53 +0000 (+0000) Subject: changes in qt for volume rendering with gpu support, if you are working with volume... X-Git-Tag: v1.0.4~59 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=8aa8568d0fa7b4e2c8f92372de3859a03c4072d0;p=creaMaracasVisu.git changes in qt for volume rendering with gpu support, if you are working with volume rendering in wx you should compile and signal any problems --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f41736..1d6b3f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,12 +43,11 @@ CREA_PREVENT_IN_SOURCE_BUILD() #SET(USE_GDCM_VTK ON) SET(USE_WXWIDGETS ON) SET(USE_VTK ON) -SET(USE_ITK ON) SET(USE_BOOST ON) OPTION(QT_USE_QTUITOOLS "QT_USE_QTUITOOLS" OFF) IF(QT_USE_QTUITOOLS) - SET(USE_QT4 ON) + SET(USE_QT4 ON) ELSE(QT_USE_QTUITOOLS) SET(USE_QT4 OFF) ENDIF(QT_USE_QTUITOOLS) diff --git a/appli/QtVTKViewer/qtvtkviewer.cxx b/appli/QtVTKViewer/qtvtkviewer.cxx index 76778d4..fb6abc8 100644 --- a/appli/QtVTKViewer/qtvtkviewer.cxx +++ b/appli/QtVTKViewer/qtvtkviewer.cxx @@ -1,22 +1,9 @@ //---------------------------------------------------------------------- -// File: ann_sample.cpp -// Programmer: Sunil Arya and David Mount -// Last modified: 03/04/98 (Release 0.1) -// Description: Sample program for ANN -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. +// File: qtvtkviewer.cxx +// Programmer: Prieto +// Last modified: 25/08/11 (Release 0.1) +// Description: Sample program fro qtvtkviewer //---------------------------------------------------------------------- #include "qtvtkviewerwidget.h" @@ -28,12 +15,11 @@ #include "iostream" - -#include "OpenImageDialog.h" +#include "vtkMetaImageReader.h" +//#include "OpenImageDialog.h" using namespace std; -using namespace creaMaracasVisuKernel; - +//using namespace creaMaracasVisuKernel; int main(int argc, char **argv) { @@ -46,7 +32,7 @@ int main(int argc, char **argv) vtkImageData* img = 0; - if (argc < 2){ + /*if (argc < 2){ OpenImageDialog open(true); img = open.getImageData(); @@ -56,14 +42,14 @@ int main(int argc, char **argv) << std::endl ; return EXIT_FAILURE; } - }else{ + }else*/ + if(argc==2){ std::string inputFilename = argv[1]; vtkMetaImageReader* reader = vtkMetaImageReader::New(); reader->SetFileName(inputFilename.c_str()); reader->Update(); img = reader->GetOutput(); - } @@ -79,12 +65,10 @@ int main(int argc, char **argv) mainwindow->show(); - viewer->setImage(img); + if(img) + viewer->setImage(img); //viewer->SetLookupTable((vtkLookupTable*)colortransfer); - - - return app.exec(); } diff --git a/lib/GUI/Base/SurfaceRenderer/wxMaracasSurfaceRenderingManager.cxx b/lib/GUI/Base/SurfaceRenderer/wxMaracasSurfaceRenderingManager.cxx index 220fecc..ac816f6 100644 --- a/lib/GUI/Base/SurfaceRenderer/wxMaracasSurfaceRenderingManager.cxx +++ b/lib/GUI/Base/SurfaceRenderer/wxMaracasSurfaceRenderingManager.cxx @@ -3,8 +3,8 @@ Program: wxMaracas Module: $RCSfile: wxMaracasSurfaceRenderingManager.cxx,v $ Language: C++ - Date: $Date: 2011/06/28 16:56:13 $ - Version: $Revision: 1.1 $ + Date: $Date: 2011/10/05 16:26:55 $ + Version: $Revision: 1.2 $ Copyright: (c) 2002, 2003 License: @@ -17,6 +17,10 @@ #include "wxMaracasSurfaceRenderingManager.h" #include "wxMaracasSurfaceRenderingManagerDataMhd.h" + +#include "vtkPLYReader.h" +#include "vtkSmartPointer.h" + /** ** Start of the manager class **/ @@ -63,7 +67,7 @@ void wxMaracasSurfaceRenderingManager::Update(int pid)throw(char*){ ** Adds a prop3D to the manager and returns the identifier **/ int wxMaracasSurfaceRenderingManager::addProp3D(int idTP, vtkProp3D* prop3D, std::string dataname) throw(char*){ - checkInvariant(); + //checkInvariant(); if(prop3D != NULL){ wxMaracasSurfaceRenderingManagerData* data = new wxMaracasSurfaceRenderingManagerData(prop3D, dataname, _interactor); prop3Dvect.push_back(data); @@ -85,7 +89,7 @@ int wxMaracasSurfaceRenderingManager::addProp3D(int idTP, vtkProp3D* prop3D, std } int wxMaracasSurfaceRenderingManager::addPropMHD(int idTP, vtkImageData* imagedata, std::string dataname) throw(char*){ checkInvariant(); - if(imagedata != NULL){ + if(imagedata != NULL){ image = imagedata; wxMaracasSurfaceRenderingManagerData* data = new wxMaracasSurfaceRenderingManagerDataMhd(imagedata, dataname, _interactor); prop3Dvect.push_back(data); @@ -112,15 +116,20 @@ int wxMaracasSurfaceRenderingManager::addPropMHD(int idTP, vtkImageData* imageda void wxMaracasSurfaceRenderingManager::addRemoveActor(int propid, bool addremove) throw(char*){ checkInvariant(); - wxMaracasSurfaceRenderingManagerData* data = this->getViewData(propid); - if(data->getProp3D()!=NULL){ + wxMaracasSurfaceRenderingManagerData* data = this->getViewData(propid); + if(data && data->getProp3D()!=NULL){ if(addremove){ _renderer->AddViewProp(data->getProp3D()); }else{ _renderer->RemoveViewProp(data->getProp3D()); } _renderer->Render(); - } + }else { + if(addremove && propid == 0 && image){ + addPropMHD(0, image, "id0"); + } + return; + } } /** ** adds or removes the surface box depending of the bool value @@ -187,17 +196,29 @@ void wxMaracasSurfaceRenderingManager::changeIsoValue(int propid, double min, do vtkProp3D* wxMaracasSurfaceRenderingManager:: getProp3D(std::string filename){ if(filename.compare("")!= 0){ - vtkSTLReader *STLReader=vtkSTLReader::New(); + + vtkSmartPointer polydata = vtkSmartPointer::New(); + std::string ext = filename.substr(filename.find_last_of("."), 4); + if(ext.compare(STL)==0){ + vtkSmartPointer STLReader=vtkSmartPointer::New(); STLReader->SetFileName(filename.c_str()); STLReader->Update(); - vtkPolyDataMapper* dataMapper = vtkPolyDataMapper::New(); - dataMapper->SetInput(STLReader->GetOutput()); - - vtkActor* dataActor = vtkActor::New(); - dataActor->SetMapper(dataMapper); - dataActor->GetProperty()->SetOpacity(1); - - return dataActor; + polydata->DeepCopy(STLReader->GetOutput()); + + }else if(ext.compare(PLY)==0){ + vtkSmartPointer plyreader =vtkSmartPointer::New(); + plyreader->SetFileName(filename.c_str()); + plyreader->Update(); + polydata->DeepCopy(plyreader->GetOutput()); + } + + vtkSmartPointer dataMapper = vtkSmartPointer::New(); + dataMapper->SetInput(polydata); + + vtkActor* dataActor = vtkActor::New(); + dataActor->SetMapper(dataMapper); + dataActor->GetProperty()->SetOpacity(1); + return dataActor; } return NULL; } @@ -219,6 +240,10 @@ vtkImageData* wxMaracasSurfaceRenderingManager::getImageData(){ return image; } +void wxMaracasSurfaceRenderingManager::setImageData(vtkImageData* img){ + image = img; +} + void wxMaracasSurfaceRenderingManager::checkInvariant() throw(char*){ if(this->_renderer==NULL){ throw "Renderer not set"; @@ -227,14 +252,19 @@ void wxMaracasSurfaceRenderingManager::checkInvariant() throw(char*){ wxMaracasSurfaceRenderingManagerData* wxMaracasSurfaceRenderingManager::getViewData(int id) throw(char*){ int i; - for(i = 0; i < (int)(prop3Dvect.size());i++){ - if(prop3Dvect[i]->getId() == id){ - return prop3Dvect[i]; - } - } - throw "id not found in the data"; + for(i = 0; i < (int)(prop3Dvect.size());i++){ + if(prop3Dvect[i]->getId() == id){ + return prop3Dvect[i]; + } + } + return 0; +#ifndef USE_QT + throw "id not found in the data"; +#else + return NULL; +#endif + - return NULL; } int wxMaracasSurfaceRenderingManager::getMaxIsoValue(int propid) throw(char*){ @@ -272,8 +302,10 @@ void wxMaracasSurfaceRenderingManager::deleteActor(int propid) throw (char *){ delete data; prop3Dvect.pop_back(); }else{ +#ifndef USE_QT + throw "id not found in the data"; +#endif - throw "id not found in the data"; } } @@ -282,7 +314,8 @@ void wxMaracasSurfaceRenderingManager::enableBoundingBox(int propid, bool enable wxMaracasSurfaceRenderingManagerData* data = this->getViewData(propid); - data->enableBoxWidget(enable); + if(data) + data->enableBoxWidget(enable); } void wxMaracasSurfaceRenderingManager::Transform(vtkMatrix4x4* tmatrix){ @@ -300,3 +333,7 @@ void wxMaracasSurfaceRenderingManager::saveProp3DSTL(int propid,const char* file data->saveProp3DSTL(filename); } } + +void wxMaracasSurfaceRenderingManager::loadProp3DSTL(const char* filename){ + this->addProp3D(-1, this->getProp3D(filename), filename); +} diff --git a/lib/GUI/Base/SurfaceRenderer/wxMaracasSurfaceRenderingManager.h b/lib/GUI/Base/SurfaceRenderer/wxMaracasSurfaceRenderingManager.h index bd857fe..6342797 100644 --- a/lib/GUI/Base/SurfaceRenderer/wxMaracasSurfaceRenderingManager.h +++ b/lib/GUI/Base/SurfaceRenderer/wxMaracasSurfaceRenderingManager.h @@ -3,8 +3,8 @@ Program: wxMaracas Module: $RCSfile: wxMaracasSurfaceRenderingManager.h,v $ Language: C++ - Date: $Date: 2011/06/28 16:56:13 $ - Version: $Revision: 1.1 $ + Date: $Date: 2011/10/05 16:26:55 $ + Version: $Revision: 1.2 $ Copyright: (c) 2002, 2003 License: @@ -28,6 +28,8 @@ #include "wxMaracasSurfaceRenderingManagerData.h" + + class wxMaracasSurfaceRenderingManager { public: @@ -84,6 +86,8 @@ public: **/ vtkImageData* getImageData(); + virtual void setImageData(vtkImageData* img); + /** ** adds or removes an actor depending of the bool value **/ @@ -129,6 +133,10 @@ public: void enableBoundingBox(int propid, bool enable); void saveProp3DSTL(int propid,const char* filename); + + void loadProp3DSTL(const char* filename); + + private: std::vector prop3Dvect; diff --git a/lib/GUI/Base/VolumeRenderer/volumerendererdata.cxx b/lib/GUI/Base/VolumeRenderer/volumerendererdata.cxx index c19456f..15ca192 100644 --- a/lib/GUI/Base/VolumeRenderer/volumerendererdata.cxx +++ b/lib/GUI/Base/VolumeRenderer/volumerendererdata.cxx @@ -1,33 +1,51 @@ #include "volumerendererdata.h" #include "vtkObjectFactory.h" -vtkCxxRevisionMacro(VolumeRendererData, "$Revision: 1.6 $"); +vtkCxxRevisionMacro(VolumeRendererData, "$Revision: 1.7 $"); vtkStandardNewMacro(VolumeRendererData); VolumeRendererData::VolumeRendererData() { - VolRendData = 0; + VolRendManager = 0; ImageData = 0; Renderer = 0; Interactor = 0; + LookUpTable = 0; + //ImageDataSeparateComponents = false; } void VolumeRendererData::ShowVolume(bool checked){ - if(checked){ - // invariant(); - //cout<<"JPRG::VolumeRendererData::ShowVolume"<addVolume(ImageData, Interactor); + } + if(LookUpTable) + VolRendManager->SetLookupTable(LookUpTable); + vector< vtkProp3D* > props = VolRendManager->getProps3D(); + for(unsigned i = 0; i < props.size(); i++){ + Renderer->AddActor(props[i]); + } + + }else{ + vector< vtkProp3D* > props = VolRendManager->getProps3D(); + for(unsigned i = 0; i < props.size(); i++){ + Renderer->RemoveActor(props[i]); } - VolRendData->SetLookupTable(LookUpTable); - Renderer->AddActor(VolRendData->getProp3D()); - }else{ - Renderer->RemoveActor(VolRendData->getProp3D()); - // VolRendData->Delete(); - // VolRendData = 0; + delete VolRendManager; + VolRendManager = 0; + } + }catch(char* e){ + cout<<"Exception in: "< greyvalues, vector values){ //invariant(); - if(VolRendData==NULL) - { - VolRendData = new VolumeRendererManagerData(ImageData, true); + if(VolRendManager==NULL) + { + ShowVolume(true); } - VolRendData->SetLookupTable(LookUpTable); - VolRendData->setVolumeOpacity(greyvalues,values); + VolRendManager->setVolumeOpacity(greyvalues,values); } void VolumeRendererData::BoundingBoxChanged(bool checked){ // invariant(); - if(VolRendData==NULL) + if(VolRendManager==NULL) { - VolRendData = new VolumeRendererManagerData(ImageData, true); - VolRendData->SetLookupTable(LookUpTable); + ShowVolume(true); } - if(VolRendData && Interactor){ + if(VolRendManager && Interactor){ if(checked){ - VolRendData->EnableBoundingBox(Interactor); + VolRendManager->EnableBoundingBox(Interactor); }else{ - VolRendData->DisableBoundingBox(); + VolRendManager->DisableBoundingBox(); } } } void VolumeRendererData::changeCompositeMIPFunction(int function){ invariant(); - if(VolRendData) - VolRendData->changeCompositeMIPFunction(function); + if(VolRendManager) + VolRendManager->changeCompositeMIPFunction(0, function); +} + +/** + changes the interoplation type of the volume + type = 0 linear + type = 1 nearest + */ +void VolumeRendererData::changeInterpolationType(int type){ + invariant(); + if(VolRendManager) + VolRendManager->changeInterpolationType(type); } diff --git a/lib/GUI/Base/VolumeRenderer/volumerendererdata.h b/lib/GUI/Base/VolumeRenderer/volumerendererdata.h index 95a7eb8..36f605b 100644 --- a/lib/GUI/Base/VolumeRenderer/volumerendererdata.h +++ b/lib/GUI/Base/VolumeRenderer/volumerendererdata.h @@ -2,7 +2,7 @@ #define VOLUMERENDERERDATA_H -#include "volumerenderermanagerdata.h" +#include "volumerenderermanager.h" #include "vtkRenderWindowInteractor.h" #include "vtkObject.h" @@ -15,25 +15,45 @@ public: vtkTypeRevisionMacro(VolumeRendererData,vtkObject); // - vtkSetObjectMacro(ImageData, vtkImageData) - vtkSetObjectMacro(Renderer, vtkRenderer) - vtkSetObjectMacro(LookUpTable, vtkLookupTable) - vtkSetObjectMacro(Interactor, vtkRenderWindowInteractor) + vtkSetObjectMacro(ImageData, vtkImageData); + //vtkSetMacro(ImageDataSeparateComponents, bool); + + vtkSetObjectMacro(Renderer, vtkRenderer); + vtkSetObjectMacro(LookUpTable, vtkLookupTable); + vtkSetObjectMacro(Interactor, vtkRenderWindowInteractor); + + + void BoundingBoxChanged(bool checked); void ShowVolume(bool enable); void OpacityChanged(vector greyvalues, vector values); + /** + chages the ray cast function type + function = 0 composite + function = 1 MIP (maximum intensity pixel) + */ void changeCompositeMIPFunction(int function); + /** + changes the interoplation type of the volume + type = 0 linear + type = 1 nearest + */ + void changeInterpolationType(int type); + protected: VolumeRendererData(); - VolumeRendererManagerData* VolRendData; + VolumeRendererManager* VolRendManager; vtkImageData* ImageData; vtkRenderer* Renderer; vtkLookupTable* LookUpTable; vtkRenderWindowInteractor* Interactor; +// bool ImageDataSeparateComponents; + + private: void invariant(); diff --git a/lib/GUI/Qt/SurfaceRenderer/CMakeLists.txt b/lib/GUI/Qt/SurfaceRenderer/CMakeLists.txt index 9aee379..df0fd89 100644 --- a/lib/GUI/Qt/SurfaceRenderer/CMakeLists.txt +++ b/lib/GUI/Qt/SurfaceRenderer/CMakeLists.txt @@ -56,7 +56,7 @@ IF ( BUILD_${LIBRARY_NAME} ) # If this is NOT done, then the ui_*.h files will not be generated #add_executable(qtproject ${qtproject_SRCS} ${qtproject_UIS_H} ) - FILE(GLOB ${LIBRARY_NAME}_HEADERS "*.h" "*.txx" "${PROJECT_BINARY_DIR}/lib/GUI/Qt/VTK/VolumeRenderer/*.h") + FILE(GLOB ${LIBRARY_NAME}_HEADERS "*.h" "*.txx" "${PROJECT_BINARY_DIR}/lib/GUI/Qt/VTK/SurfaceRenderer/*.h") set(${LIBRARY_NAME}_SOURCES ${${LIBRARY_NAME}_SOURCES} ${${LIBRARY_NAME}_UIS_H}) diff --git a/lib/GUI/Qt/SurfaceRenderer/qtsurfacerenderer.cxx b/lib/GUI/Qt/SurfaceRenderer/qtsurfacerenderer.cxx new file mode 100644 index 0000000..2907ce7 --- /dev/null +++ b/lib/GUI/Qt/SurfaceRenderer/qtsurfacerenderer.cxx @@ -0,0 +1,58 @@ +#include "qtsurfacerenderer.h" +#include "ui_qtsurfacerenderer.h" + + +#include + +QtSurfaceRenderer::QtSurfaceRenderer(QWidget *parent) : + QWidget(parent), + ui(new Ui::QtSurfaceRenderer) +{ + ui->setupUi(this); + + this->ui->tabWidgetSurface->removeTab(1); + this->ui->tabWidgetSurface->removeTab(0); + + + QtSurfaceRendererPanel* surfacepanel = new QtSurfaceRendererPanel(this); + this->ui->tabWidgetSurface->addTab(surfacepanel, QString("Surface Rendering")); + + Renderer = 0; + Interactor = 0; +} + +QtSurfaceRenderer::~QtSurfaceRenderer() +{ + delete ui; +} + +void QtSurfaceRenderer::SetImageData(vtkImageData* img){ + this->ui->tabWidgetSurface->setCurrentIndex(0); + QtSurfaceRendererPanel* surfacepanel = (QtSurfaceRendererPanel*)this->ui->tabWidgetSurface->currentWidget(); + surfacepanel->setInteractor(Interactor); + surfacepanel->setRenderer(Renderer); + surfacepanel->setImageData(img); +} + +void QtSurfaceRenderer::on_pushbuttonAddTab_clicked() +{ + + QtSurfaceRendererPanel* surfacepanel = new QtSurfaceRendererPanel(this); + surfacepanel->setRenderer(Renderer); + surfacepanel->setInteractor(Interactor); + + this->ui->tabWidgetSurface->addTab(surfacepanel, QString("Surface Rendering")); +} + +void QtSurfaceRenderer::on_tabWidgetSurface_tabCloseRequested(int index) +{ + if(index != 0){ + + QtSurfaceRendererPanel* surfacepanel = (QtSurfaceRendererPanel*)this->ui->tabWidgetSurface->currentWidget(); + surfacepanel->enableBoundingBox(0, false); + surfacepanel->deleteActor(0); + + this->ui->tabWidgetSurface->removeTab(index); + } +} + diff --git a/lib/GUI/Qt/SurfaceRenderer/qtsurfacerenderer.h b/lib/GUI/Qt/SurfaceRenderer/qtsurfacerenderer.h new file mode 100644 index 0000000..6ffe36e --- /dev/null +++ b/lib/GUI/Qt/SurfaceRenderer/qtsurfacerenderer.h @@ -0,0 +1,37 @@ +#ifndef QTSURFACERENDERER_H +#define QTSURFACERENDERER_H + +#include +#include "wxMaracasSurfaceRenderingManager.h" + +namespace Ui { + class QtSurfaceRenderer; +} + +class QtSurfaceRenderer : public QWidget,public vtkObject +{ + Q_OBJECT + +public: + explicit QtSurfaceRenderer(QWidget *parent = 0); + + ~QtSurfaceRenderer(); + + vtkSetMacro(Renderer, vtkRenderer*); + vtkSetMacro(Interactor, vtkRenderWindowInteractor*); + + void SetImageData(vtkImageData* img); +private slots: + void on_pushbuttonAddTab_clicked(); + + void on_tabWidgetSurface_tabCloseRequested(int index); + + +private: + Ui::QtSurfaceRenderer *ui; + + vtkRenderer* Renderer; + vtkRenderWindowInteractor* Interactor; +}; + +#endif // QTSURFACERENDERER_H diff --git a/lib/GUI/Qt/SurfaceRenderer/qtsurfacerenderer.ui b/lib/GUI/Qt/SurfaceRenderer/qtsurfacerenderer.ui new file mode 100644 index 0000000..a9af6d4 --- /dev/null +++ b/lib/GUI/Qt/SurfaceRenderer/qtsurfacerenderer.ui @@ -0,0 +1,52 @@ + + + QtSurfaceRenderer + + + + 0 + 0 + 266 + 454 + + + + Form + + + + + + + + + + + + + + 0 + + + Qt::ElideNone + + + true + + + + SN + + pushbuttonAddTab + + + + SN2 + + + + + + + + + diff --git a/lib/GUI/Qt/SurfaceRenderer/qtsurfacerendererpanel.cxx b/lib/GUI/Qt/SurfaceRenderer/qtsurfacerendererpanel.cxx index 8a190bd..b675aa6 100644 --- a/lib/GUI/Qt/SurfaceRenderer/qtsurfacerendererpanel.cxx +++ b/lib/GUI/Qt/SurfaceRenderer/qtsurfacerendererpanel.cxx @@ -8,6 +8,7 @@ #include "Color.xpm" #include "Save.xpm" +#include "OpenImage.xpm" QtSurfaceRendererPanel::QtSurfaceRendererPanel(QWidget *parent) : QWidget(parent), @@ -18,21 +19,21 @@ QtSurfaceRendererPanel::QtSurfaceRendererPanel(QWidget *parent) : this->ui->pushButtonColorChooser->setIcon(QIcon(Color_xpm)); this->ui->pushButtonSave->setIcon(QIcon(Save_xpm)); + this->ui->pushButtonOpen->setIcon(QIcon(OpenImage_xpm)); } QtSurfaceRendererPanel::~QtSurfaceRendererPanel() -{ +{ delete ui; } -void QtSurfaceRendererPanel::SetImageData(vtkImageData* img){ - this->addPropMHD(0, img, ""); - this->enableBoundingBox(0, false); - +void QtSurfaceRendererPanel::setImageData(vtkImageData* img){ double *range =img->GetScalarRange(); - this->ui->horizontalSliderMinIso->setRange(range[0], range[1] - 1); + this->ui->horizontalSliderMinIso->setRange(range[0], range[1]); - this->ui->horizontalSliderMaxIso->setRange(range[0] + 1, range[1]); + this->ui->horizontalSliderMaxIso->setRange(range[0], range[1]); + + wxMaracasSurfaceRenderingManager::setImageData(img); } void QtSurfaceRendererPanel::on_OpacitySlider_valueChanged(int value) @@ -77,6 +78,10 @@ void QtSurfaceRendererPanel::on_pushButtonColorChooser_clicked() void QtSurfaceRendererPanel::on_checkBox_clicked(bool checked) { this->addRemoveActor(0, checked); + if(!checked){ + this->ui->checkBoxBoundingBox->setCheckState(Qt::Unchecked); + this->on_checkBoxBoundingBox_clicked(false); + } } void QtSurfaceRendererPanel::on_horizontalSliderMaxIso_valueChanged(int value) @@ -107,12 +112,12 @@ void QtSurfaceRendererPanel::onIsoValueChanged(){ void QtSurfaceRendererPanel::on_pushButtonSave_clicked() { QString filename = QFileDialog::getSaveFileName(this, - tr("Save STL File"), + tr("Save Mesh File"), QDir::currentPath(), - tr("STL files (*.stl);") ); + tr("Mesh files (*.stl *.ply)") ); if( !filename.isNull() ){ - filename.append(".stl"); + //filename.append(".stl"); this->saveProp3DSTL(0, filename.toStdString().c_str()); } @@ -123,3 +128,17 @@ void QtSurfaceRendererPanel::on_checkBoxBoundingBox_clicked(bool checked) this->enableBoundingBox(0, checked); } + +void QtSurfaceRendererPanel::on_pushButtonOpen_clicked(bool checked) +{ + +} + +void QtSurfaceRendererPanel::on_pushButtonOpen_clicked() +{ + QString filename = QFileDialog::getOpenFileName(this, tr("Load Mesh File"), QDir::currentPath(), tr("Mesh files (*.stl *.ply)")); + + if(!filename.isNull()){ + this->loadProp3DSTL(filename.toStdString().c_str()); + } +} diff --git a/lib/GUI/Qt/SurfaceRenderer/qtsurfacerendererpanel.h b/lib/GUI/Qt/SurfaceRenderer/qtsurfacerendererpanel.h index 3810f56..d583d11 100644 --- a/lib/GUI/Qt/SurfaceRenderer/qtsurfacerendererpanel.h +++ b/lib/GUI/Qt/SurfaceRenderer/qtsurfacerendererpanel.h @@ -18,8 +18,7 @@ public: explicit QtSurfaceRendererPanel(QWidget *parent = 0); ~QtSurfaceRendererPanel(); - void SetImageData(vtkImageData* img); - + virtual void setImageData(vtkImageData* img); private slots: void on_OpacitySlider_valueChanged(int value); @@ -40,6 +39,11 @@ private slots: void on_checkBoxBoundingBox_clicked(bool checked); + void on_pushButtonOpen_clicked(bool checked); + + void on_pushButtonOpen_clicked(); + + private: Ui::QtSurfaceRendererPanel *ui; diff --git a/lib/GUI/Qt/SurfaceRenderer/qtsurfacerendererpanel.ui b/lib/GUI/Qt/SurfaceRenderer/qtsurfacerendererpanel.ui index 3d9550b..2af643b 100644 --- a/lib/GUI/Qt/SurfaceRenderer/qtsurfacerendererpanel.ui +++ b/lib/GUI/Qt/SurfaceRenderer/qtsurfacerendererpanel.ui @@ -6,7 +6,7 @@ 0 0 - 145 + 197 299 @@ -21,7 +21,7 @@ - + false @@ -68,14 +68,25 @@ - + + + + + + + + ../../../../data/Icons/OpenImage.xpm../../../../data/Icons/OpenImage.xpm + + + + Qt::Horizontal - + @@ -112,14 +123,14 @@ - + Qt::Horizontal - + diff --git a/lib/GUI/Qt/Viewers/CMakeLists.txt b/lib/GUI/Qt/Viewers/CMakeLists.txt index a72202c..e32e338 100644 --- a/lib/GUI/Qt/Viewers/CMakeLists.txt +++ b/lib/GUI/Qt/Viewers/CMakeLists.txt @@ -106,7 +106,6 @@ IF ( BUILD_${LIBRARY_NAME} ) # USER! : The default is to create a Dynamic Library. # if you need to create a static library # comment out the following line : - SET(${LIBRARY_NAME}_INSTALL_TREE_RELATIVE_INCLUDE_PATHS include/creaMaracasVisu) SET(${LIBRARY_NAME}_INSTALL_FOLDER creaMaracasVisu) CREA_ADD_LIBRARY( ${LIBRARY_NAME} ) diff --git a/lib/GUI/Qt/Viewers/qtvtkviewer.cpp b/lib/GUI/Qt/Viewers/qtvtkviewer.cpp index 8a67db4..d4c0685 100644 --- a/lib/GUI/Qt/Viewers/qtvtkviewer.cpp +++ b/lib/GUI/Qt/Viewers/qtvtkviewer.cpp @@ -1,12 +1,14 @@ #include "qtvtkviewer.h" +#include "vtkImageMapToColors.h" + QtVTKViewer::QtVTKViewer(QWidget* parent) : QVTKWidget(parent) { this->GetRenderWindow()->AddRenderer(vtkRenderer::New()); - this->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->SetBackground(0,0,0); + this->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->SetBackground(1,1,1); SuperImagePlaneWidget::initialize(this->GetRenderWindow()->GetInteractor()); @@ -71,3 +73,9 @@ void QtVTKViewer::mousePressEvent(QMouseEvent* event){ #endif } } + +void QtVTKViewer::SetOutputFormatToRGBA(){ + _xwidget->GetColorMap()->SetOutputFormatToRGBA(); + _ywidget->GetColorMap()->SetOutputFormatToRGBA(); + _zwidget->GetColorMap()->SetOutputFormatToRGBA(); +} diff --git a/lib/GUI/Qt/Viewers/qtvtkviewer.h b/lib/GUI/Qt/Viewers/qtvtkviewer.h index 15b8a76..a72b4c5 100644 --- a/lib/GUI/Qt/Viewers/qtvtkviewer.h +++ b/lib/GUI/Qt/Viewers/qtvtkviewer.h @@ -17,6 +17,7 @@ public: typedef ImagePlaneWidget SuperImagePlaneWidget; + void SetOutputFormatToRGBA(); private: void invariant(); @@ -31,7 +32,7 @@ private: * finding an object in the scene * */ - double _rayorigin[4]; + double _rayorigin[4]; protected: // overloaded mouse press handler diff --git a/lib/GUI/Qt/Viewers/qtvtkviewerwidget.cxx b/lib/GUI/Qt/Viewers/qtvtkviewerwidget.cxx index 8f586fe..7229daa 100644 --- a/lib/GUI/Qt/Viewers/qtvtkviewerwidget.cxx +++ b/lib/GUI/Qt/Viewers/qtvtkviewerwidget.cxx @@ -4,14 +4,17 @@ QtVTKViewerWidget::QtVTKViewerWidget(QWidget *parent) : - QWidget(parent) + QWidget(parent), + ui(new Ui::QtVTKViewerWidget) { - setupUi(this); + ui->setupUi(this); + + ui->m_VolumeRender->SetRenderer(this->getRenderer()); + ui->m_VolumeRender->SetInteractor(ui->_qtvtkviewer->GetRenderWindow()->GetInteractor()); + + ui->m_SurfaceRender->SetRenderer(this->getRenderer()); + ui->m_SurfaceRender->SetInteractor(ui->_qtvtkviewer->GetRenderWindow()->GetInteractor()); - this->m_VolumeRender->SetRenderer(this->getRenderer()); - this->m_VolumeRender->SetInteractor(this->_qtvtkviewer->GetRenderWindow()->GetInteractor()); - this->m_SurfaceRender->setRenderer(this->getRenderer()); - this->m_SurfaceRender->setInteractor(this->_qtvtkviewer->GetRenderWindow()->GetInteractor()); } QtVTKViewerWidget::~QtVTKViewerWidget() @@ -20,21 +23,63 @@ QtVTKViewerWidget::~QtVTKViewerWidget() } vtkRenderer* QtVTKViewerWidget::getRenderer(){ - return this->_qtvtkviewer->GetRenderWindow()->GetRenderers()->GetFirstRenderer(); + return ui->_qtvtkviewer->GetRenderWindow()->GetRenderers()->GetFirstRenderer(); } void QtVTKViewerWidget::setImage(vtkImageData* img){ - this->_qtvtkviewer->setImage(img); - this->m_VolumeRender->SetImageData(img); - this->m_SurfaceRender->SetImageData(img); + + + ui->_qtvtkviewer->setImage(img); + ui->m_VolumeRender->SetImageData(img); + ui->m_SurfaceRender->SetImageData(img); + + int *extent = img->GetExtent(); + + + ui->horizontalSliderX->setRange(extent[0], extent[1]); + ui->horizontalSliderY->setRange(extent[2], extent[3]); + ui->horizontalSliderZ->setRange(extent[4], extent[5]); + } void QtVTKViewerWidget::SetLookupTable(vtkLookupTable *lookuptable){ - this->_qtvtkviewer->SetLookupTable(lookuptable); - this->m_VolumeRender->SetLookUpTable(lookuptable); + + ui->_qtvtkviewer->SetLookupTable(lookuptable); + ui->m_VolumeRender->SetLookUpTable(lookuptable); } void QtVTKViewerWidget::on_checkBoxShowPlanes_clicked(){ - this->_qtvtkviewer->showPlanes(checkBoxShowPlanes->isChecked()); + ui->_qtvtkviewer->showPlanes(ui->checkBoxShowPlanes->isChecked()); +} + +void QtVTKViewerWidget::SetOutputFormatToRGBA(){ + ui->_qtvtkviewer->SetOutputFormatToRGBA(); +} + +void QtVTKViewerWidget::on_checkBoxShowImageActor_clicked(bool checked) +{ + if(!(ui->_qtvtkviewer->showImageActors(checked))){ + ui->checkBoxShowImageActor->setCheckState(Qt::Unchecked); + } +} + +void QtVTKViewerWidget::on_horizontalSliderX_valueChanged(int value) +{ + + ui->lineEditX->setText(QString::number(value)); + ui->_qtvtkviewer->setSliceXImageActor(value); + +} + +void QtVTKViewerWidget::on_horizontalSliderY_valueChanged(int value) +{ + ui->lineEditY->setText(QString::number(value)); + ui->_qtvtkviewer->setSliceYImageActor(value); +} + +void QtVTKViewerWidget::on_horizontalSliderZ_valueChanged(int value) +{ + ui->lineEditZ->setText(QString::number(value)); + ui->_qtvtkviewer->setSliceZImageActor(value); } diff --git a/lib/GUI/Qt/Viewers/qtvtkviewerwidget.h b/lib/GUI/Qt/Viewers/qtvtkviewerwidget.h index 70be614..7f94621 100644 --- a/lib/GUI/Qt/Viewers/qtvtkviewerwidget.h +++ b/lib/GUI/Qt/Viewers/qtvtkviewerwidget.h @@ -14,7 +14,7 @@ namespace Ui { class QtVTKViewerWidget; } -class QtVTKViewerWidget : public QWidget, Ui_QtVTKViewerWidget +class QtVTKViewerWidget : public QWidget { Q_OBJECT @@ -28,9 +28,23 @@ public: void SetLookupTable(vtkLookupTable *lookuptable); + void SetOutputFormatToRGBA(); + private slots: void on_checkBoxShowPlanes_clicked(); + void on_checkBoxShowImageActor_clicked(bool checked); + + void on_horizontalSliderX_valueChanged(int value); + + void on_horizontalSliderY_valueChanged(int value); + + void on_horizontalSliderZ_valueChanged(int value); + +private: + Ui::QtVTKViewerWidget *ui; + bool _firstset; + }; #endif // QTVTKVIEWERWIDGET_H diff --git a/lib/GUI/Qt/Viewers/qtvtkviewerwidget.ui b/lib/GUI/Qt/Viewers/qtvtkviewerwidget.ui index 553d4b9..d7d8ae4 100644 --- a/lib/GUI/Qt/Viewers/qtvtkviewerwidget.ui +++ b/lib/GUI/Qt/Viewers/qtvtkviewerwidget.ui @@ -23,41 +23,165 @@ - 2 + 0 0 0 - 98 - 28 + 155 + 505 Image Widget - - - true - + - 10 + 0 20 - 111 - 22 + 201 + 246 - - Show Planes - - - true - - - false - + + + + + true + + + Show Planes + + + true + + + false + + + + + + + + + Show Image Actor + + + + + + + Qt::Horizontal + + + + 18 + 20 + + + + + + + + + + X slice = + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Qt::Horizontal + + + + + + + Y slice = + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Qt::Horizontal + + + + + + + Z slice = + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Qt::Horizontal + + + + + + + + @@ -65,8 +189,8 @@ 0 0 - 98 - 28 + 155 + 505 @@ -78,7 +202,7 @@ 0 0 181 - 121 + 221 @@ -101,13 +225,13 @@ Surface Rendering - + 0 0 - 151 - 271 + 221 + 381 @@ -122,6 +246,9 @@ 0 + toolBox + toolBox + toolBox @@ -140,12 +267,61 @@ 1 - QtSurfaceRendererPanel + QtSurfaceRenderer QWidget -
qtsurfacerendererpanel.h
+
qtsurfacerenderer.h
1
- + + + checkBoxShowImageActor + clicked(bool) + horizontalSliderX + setEnabled(bool) + + + 81 + 132 + + + 81 + 182 + + + + + checkBoxShowImageActor + clicked(bool) + horizontalSliderY + setEnabled(bool) + + + 128 + 122 + + + 124 + 236 + + + + + checkBoxShowImageActor + clicked(bool) + horizontalSliderZ + setEnabled(bool) + + + 48 + 120 + + + 87 + 297 + + + + diff --git a/lib/GUI/Qt/VolumeRenderer/qtvolumerendererpanel.cxx b/lib/GUI/Qt/VolumeRenderer/qtvolumerendererpanel.cxx index f0a431d..779621c 100644 --- a/lib/GUI/Qt/VolumeRenderer/qtvolumerendererpanel.cxx +++ b/lib/GUI/Qt/VolumeRenderer/qtvolumerendererpanel.cxx @@ -20,10 +20,14 @@ void QtVolumeRendererPanel::on_checkBoxShowVolume_clicked(bool checked) { try{ ShowVolume(checked); - on_opacitySlider_valueChanged(this->ui->opacitySlider->value()); + //JCP 27/09/12 + //on_opacitySlider_valueChanged(this->ui->opacitySlider->value()); }catch(char * e){ cout<GetScalarRange(); vector greylevel; - greylevel.push_back(range[0]); + greylevel.push_back(0); + greylevel.push_back(1); greylevel.push_back(range[1]); vector vectvalue; + vectvalue.push_back(0); vectvalue.push_back(value/100.0); vectvalue.push_back(value/100.0); @@ -72,3 +78,24 @@ void QtVolumeRendererPanel::on_radioButtonComposite_clicked(bool checked) this->changeCompositeMIPFunction(0); } } + +void QtVolumeRendererPanel::on_radioButtonLinear_clicked(bool checked) +{ + if(checked){ + this->changeInterpolationType(0); + } +} + +void QtVolumeRendererPanel::on_radioButtonNearest_clicked(bool checked) +{ + if(checked){ + this->changeInterpolationType(1); + } +} + +void QtVolumeRendererPanel::on_radioButtonMinIP_clicked(bool checked) +{ + if(checked){ + this->changeCompositeMIPFunction(2); + } +} diff --git a/lib/GUI/Qt/VolumeRenderer/qtvolumerendererpanel.h b/lib/GUI/Qt/VolumeRenderer/qtvolumerendererpanel.h index 22750e7..5cd1d1c 100644 --- a/lib/GUI/Qt/VolumeRenderer/qtvolumerendererpanel.h +++ b/lib/GUI/Qt/VolumeRenderer/qtvolumerendererpanel.h @@ -28,6 +28,12 @@ private slots: void on_radioButtonComposite_clicked(bool checked); + void on_radioButtonLinear_clicked(bool checked); + + void on_radioButtonNearest_clicked(bool checked); + + void on_radioButtonMinIP_clicked(bool checked); + private: Ui::QtVolumeRendererPanel *ui; void invariant(); diff --git a/lib/GUI/Qt/VolumeRenderer/qtvolumerendererpanel.ui b/lib/GUI/Qt/VolumeRenderer/qtvolumerendererpanel.ui index de48745..9859706 100644 --- a/lib/GUI/Qt/VolumeRenderer/qtvolumerendererpanel.ui +++ b/lib/GUI/Qt/VolumeRenderer/qtvolumerendererpanel.ui @@ -6,15 +6,15 @@ 0 0 - 186 - 137 + 275 + 213 Form - - + + @@ -41,37 +41,106 @@ - - - + + + + + + Ray Cast Function + + + + + + Change the Ray Cast Function To Composite (All) + Composite true + + true + buttonGroup - + + + Change the Ray Cast Function To Maximum Intensity Pixel + - MIP + MaxIP false + + true + buttonGroup + + + + Change the Ray Cast Function To Minimum Intensity Pixel + + + MinIP + + + true + + + buttonGroup + + + + + + + + + + + Interpolation + + + + + + + Linear + + + true + + + buttonGroup_2 + + + + + + + Nearest + + + buttonGroup_2 + + + - + @@ -146,12 +215,12 @@ setEnabled(bool) - 57 - 21 + 134 + 93 - 110 - 25 + 524 + 93 @@ -162,49 +231,50 @@ setEnabled(bool) - 61 - 30 + 134 + 93 - 57 - 126 + 77 + 626 checkBoxShowVolume toggled(bool) - radioButtonComposite + radioButtonLinear setEnabled(bool) - 41 - 23 + 134 + 93 - 36 - 54 + 29 + 495 checkBoxShowVolume toggled(bool) - radioButtonMIP + radioButtonNearest setEnabled(bool) - 69 - 16 + 134 + 93 - 143 - 46 + 532 + 495 + true diff --git a/lib/Kernel/VTKObjects/SurfaceRenderer/wxMaracasSurfaceRenderingManagerData.cxx b/lib/Kernel/VTKObjects/SurfaceRenderer/wxMaracasSurfaceRenderingManagerData.cxx index b302cac..510ec5c 100644 --- a/lib/Kernel/VTKObjects/SurfaceRenderer/wxMaracasSurfaceRenderingManagerData.cxx +++ b/lib/Kernel/VTKObjects/SurfaceRenderer/wxMaracasSurfaceRenderingManagerData.cxx @@ -3,6 +3,7 @@ #include #include "vtkSTLWriter.h" +#include "vtkPLYWriter.h" /******************************************************************************************** ** Start of data viewmanagerData @@ -114,12 +115,25 @@ void wxMaracasSurfaceRenderingManagerData::setDataname(std::string dataname){ void wxMaracasSurfaceRenderingManagerData::saveProp3DSTL(const char* filename){ if(_dataMapper){ - vtkSmartPointer stlWriter = - vtkSmartPointer::New(); - stlWriter->SetFileName(filename); - stlWriter->SetInput(_dataMapper->GetInput()); - stlWriter->SetFileTypeToBinary(); - stlWriter->Write(); + + std::string filena(filename); + std::string ext = filena.substr(filena.find_last_of("."), 4); + if(ext.compare(PLY) == 0){ + vtkSmartPointer plywriter = + vtkSmartPointer::New(); + plywriter->SetFileName(filename); + plywriter->SetInput(_dataMapper->GetInput()); + plywriter->Write(); + }else if(ext.compare(PLY) == 0){ + vtkSmartPointer stlWriter = + vtkSmartPointer::New(); + stlWriter->SetFileName(filename); + stlWriter->SetInput(_dataMapper->GetInput()); + stlWriter->SetFileTypeToBinary(); + stlWriter->Write(); + }else{ + cout<<"unsupported format"<HandlesOn (); - _boxWidgetS1->EnabledOn(); + _boxWidgetS1->EnabledOff(); }else{ _dataMapper->SetInput(_cleanFilter->GetOutput()); } @@ -91,6 +91,8 @@ void wxMaracasSurfaceRenderingManagerDataMhd::enableBoxWidget(bool enable){ }else{ _boxWidgetS1->EnabledOff(); } + }else{ + cout<<"box widget not initialized!"<SetInteractor( interactor ); _ywidget->SetInteractor( interactor ); _zwidget->SetInteractor( interactor ); + } +bool ImagePlaneWidget::showImageActors(bool show){ + if(show && m_Interactor){ + if(!_imageactorx){ + initializeImageActors(); + } + m_Interactor->GetRenderWindow ()->GetRenderers ()->GetFirstRenderer ()->AddViewProp(_imageactorx); + m_Interactor->GetRenderWindow ()->GetRenderers ()->GetFirstRenderer ()->AddViewProp(_imageactory); + m_Interactor->GetRenderWindow ()->GetRenderers ()->GetFirstRenderer ()->AddViewProp(_imageactorz); + return true; + }else if(_imageactorx){ + m_Interactor->GetRenderWindow ()->GetRenderers ()->GetFirstRenderer ()->RemoveViewProp(_imageactorx); + m_Interactor->GetRenderWindow ()->GetRenderers ()->GetFirstRenderer ()->RemoveViewProp(_imageactory); + m_Interactor->GetRenderWindow ()->GetRenderers ()->GetFirstRenderer ()->RemoveViewProp(_imageactorz); + return true; + } + + return false; +} + +void ImagePlaneWidget::initializeImageActors(){ + + int *w_ext = _img->GetWholeExtent(); + //cout<SetInput(_img); + xslice = (w_ext[4] + w_ext[5])/2; + _imageactorx->SetDisplayExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], xslice, xslice); + + _imageactory = vtkImageActor::New(); + _imageactory->SetInput(_img); + yslice = (w_ext[2] + w_ext[3])/2; + _imageactory->SetDisplayExtent(w_ext[0], w_ext[1], yslice, yslice, w_ext[4], w_ext[5]); + + _imageactorz = vtkImageActor::New(); + _imageactorz->SetInput(_img); + zslice = (w_ext[0] + w_ext[1])/2; + _imageactorz->SetDisplayExtent(zslice, zslice, w_ext[2], w_ext[3], w_ext[4], w_ext[5]); + + +} void ImagePlaneWidget::setImage(vtkImageData* img){ _img = img; @@ -93,3 +147,23 @@ void ImagePlaneWidget::invariant(){ throw "The widgets are not initialized"; } } + + +void ImagePlaneWidget::setSliceXImageActor(int value){ + int *w_ext = _img->GetWholeExtent(); + xslice = value; + _imageactorx->SetDisplayExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], xslice, xslice); + m_Interactor->Render(); +} +void ImagePlaneWidget::setSliceYImageActor(int value){ + int *w_ext = _img->GetWholeExtent(); + yslice = value; + _imageactory->SetDisplayExtent(w_ext[0], w_ext[1], yslice, yslice, w_ext[4], w_ext[5]); + m_Interactor->Render(); +} +void ImagePlaneWidget::setSliceZImageActor(int value){ + int *w_ext = _img->GetWholeExtent(); + zslice = value; + _imageactorz->SetDisplayExtent(zslice, zslice, w_ext[2], w_ext[3], w_ext[4], w_ext[5]); + m_Interactor->Render(); +} diff --git a/lib/Kernel/VTKObjects/ViewerWidgets/imageplanewidget.h b/lib/Kernel/VTKObjects/ViewerWidgets/imageplanewidget.h index 1dae6bd..60678be 100644 --- a/lib/Kernel/VTKObjects/ViewerWidgets/imageplanewidget.h +++ b/lib/Kernel/VTKObjects/ViewerWidgets/imageplanewidget.h @@ -7,6 +7,8 @@ #include "vtkImagePlaneWidget.h" #include "vtkImageData.h" #include "vtkColorTransferFunction.h" +#include "vtkImageViewer2.h" +#include "vtkSmartPointer.h" class ImagePlaneWidget { @@ -19,17 +21,36 @@ public: virtual void SetColorTable(vtkColorTransferFunction *lookuptable); - virtual void showPlanes(bool show); + virtual void showPlanes(bool show); - void initialize(vtkRenderWindowInteractor* interactor); + virtual bool showImageActors(bool show); + + void setSliceXImageActor(int value); + void setSliceYImageActor(int value); + void setSliceZImageActor(int value); protected: vtkImageData* _img; vtkImagePlaneWidget* _xwidget; vtkImagePlaneWidget* _ywidget; vtkImagePlaneWidget* _zwidget; + vtkImageActor * _imageactorx; + vtkImageActor* _imageactory; + vtkImageActor* _imageactorz; + + int xslice; + int yslice; + int zslice; + + void initialize(vtkRenderWindowInteractor* interactor); + + void initializeImageActors(); + private: void invariant(); + + vtkRenderWindowInteractor* m_Interactor; + }; #endif // IMAGEPLANEWIDGET_H diff --git a/lib/Kernel/VTKObjects/VolumeRenderer/volumerenderermanager.cxx b/lib/Kernel/VTKObjects/VolumeRenderer/volumerenderermanager.cxx index dcc3c11..6689541 100644 --- a/lib/Kernel/VTKObjects/VolumeRenderer/volumerenderermanager.cxx +++ b/lib/Kernel/VTKObjects/VolumeRenderer/volumerenderermanager.cxx @@ -5,8 +5,8 @@ Program: wxMaracas Module: $RCSfile: volumerenderermanager.cxx,v $ Language: C++ - Date: $Date: 2011/05/31 19:03:03 $ - Version: $Revision: 1.1 $ + Date: $Date: 2011/10/05 16:27:04 $ + Version: $Revision: 1.2 $ Copyright: (c) 2002, 2003 License: @@ -19,6 +19,15 @@ #include #include + +#include "vtkImageLuminance.h" +#include "vtkImageAppendComponents.h" +#include "vtkSmartPointer.h" + +#include + +using namespace std; + /** ** Start of the manager class **/ @@ -27,6 +36,13 @@ VolumeRendererManager::VolumeRendererManager(){ _idCount=0; } VolumeRendererManager::~VolumeRendererManager(){ + _renderer = 0; + _idCount=0; + image = 0; + for(unsigned i = 0; i < prop3Dvect.size();i++){ + prop3Dvect[i]->Delete(); + } + prop3Dvect.clear(); } /** @@ -52,6 +68,261 @@ void VolumeRendererManager::Update(int ppid){ _renderer->Render(); } +/** +* @pre The image can have one or multiple components per voxel, and volume rendering is performed seprately over the + three of them. If the image has multiple components and the separate components flag is set to false, then + the vtkImageAppendComponents is used to create a single image. +* @post The volume rendering is performed over the image vol +* @param vtkImageData* the image volume +* @param bool separatecomponents, if the image has multiple components, then a mapper is used for each of the channels + if this flag is set to false and the volume has multiple components, vtkImageAppendComponents is used to create + a single representation of the image. +*/ +int VolumeRendererManager::addVolume(vtkImageData* img, vtkRenderWindowInteractor* interactor, bool independentcomponents){ + if(img->GetNumberOfScalarComponents() > 1 && !independentcomponents){ + + + image = img; + + + vtkSmartPointer< vtkImageLuminance > luminance = vtkSmartPointer< vtkImageLuminance >::New(); + luminance->SetInput(img); + luminance->Update(); + + vtkSmartPointer< vtkImageAppendComponents > append = vtkSmartPointer< vtkImageAppendComponents >::New(); + append->SetInput(0, img); + append->SetInput(1, luminance->GetOutput()); + append->Update(); + + + + VolumeRendererManagerData* data = new VolumeRendererManagerData(append->GetOutput(), true); + data->SetIndependentComponents(independentcomponents); + + + prop3Dvect.push_back(data); + + data->setId(_idCount); + _idCount++; + + return _idCount-1; + + + /*image = img; + + vector< vtkImageData* > vectimg; + GetImages(img, vectimg); + vtkBoxWidget* boxw = 0; + for(unsigned i = 0; i < vectimg.size(); i++){ + VolumeRendererManagerData* data = new VolumeRendererManagerData(vectimg[i], ""); + + vtkColorTransferFunction* colorf = data->GetColorFunction(); + colorf->RemoveAllPoints(); + double r = 0, g = 0, b = 0; + for(unsigned j = 0; j < 255; j++){ + + if(i == 0){ + r = j/255.0; + g = 0; + b = 0; + }else if(i == 1){ + r = 0; + g = j/255.0; + b = 0; + }else if(i == 2){ + r = 0; + g = 0; + b = j/255.0; + } + + colorf->AddRGBPoint(j, r, g, b); + } + + prop3Dvect.push_back(data); + + data->setId(_idCount); + _idCount++; + + if(!boxw){ + EnableBoundingBox(interactor, data->getId()); + DisableBoundingBox(data->getId()); + boxw = data->GetBoxWidget(); + }else{ + data->SetBoxWidget(boxw); + } + } + + boxw->RemoveAllObservers(); + + vtkBoxWidgetCallback *callback = vtkBoxWidgetCallback::New(); + + for(unsigned i = 0; i < prop3Dvect.size(); i++){ + VolumeRendererManagerData* data = prop3Dvect[i]; + callback->AddMapper(data->GetVolumeMapper()); + } + + boxw->AddObserver(vtkCommand::InteractionEvent, callback); + callback->Delete(); + + return _idCount-1;*/ + + /*vtkImageData* imgshort = 0; + imgshort = vtkImageData::New(); + imgshort->SetNumberOfScalarComponents(1); + imgshort->SetExtent(img->GetExtent()); + imgshort->SetSpacing(img->GetSpacing()); + imgshort->SetOrigin(img->GetOrigin()); + imgshort->SetScalarTypeToUnsignedShort(); + imgshort->AllocateScalars(); + GetImageDouble(img, imgshort); + + VolumeRendererManagerData* data = new VolumeRendererManagerData(imgshort, ""); + + vtkColorTransferFunction* colorf = data->GetColorFunction(); + colorf->RemoveAllPoints(); + + map< unsigned short, vector< double > > colormap; + + int *extent = img->GetExtent(); + + for(unsigned i = extent[0]; i < extent[1]; i++){ + for(unsigned j = extent[2]; j < extent[3]; j++){ + for(unsigned k = extent[4]; k < extent[5]; k++){ + + unsigned char *imgpoint = ((unsigned char*)img->GetScalarPointer(i, j, k)); + double temp = (double)(0.299*imgpoint[0] + 0.587*imgpoint[1] + 0.114*imgpoint[2]); + unsigned short val = temp*255.0; + + vector< double > rgb; + rgb.push_back(0.299*imgpoint[0]); + rgb.push_back(0.587*imgpoint[1]); + rgb.push_back(0.114*imgpoint[2]); + + colormap[val] = rgb; + } + } + } + + + + map< unsigned short, vector< double > >::iterator it; + for(it = colormap.begin(); it != colormap.end(); ++it){ + + colorf->AddRGBPoint((*it).first, (*it).second[0] / 255.0, (*it).second[1] / 255.0, (*it).second[2] / 255.0); + } + + prop3Dvect.push_back(data); + + data->setId(_idCount); + EnableBoundingBox(interactor, data->getId()); + DisableBoundingBox(data->getId()); + _idCount++;*/ + + + }else{ + image = img; + + VolumeRendererManagerData* data = new VolumeRendererManagerData(img, ""); + prop3Dvect.push_back(data); + + + data->setId(_idCount); + _idCount++; + + EnableBoundingBox(interactor, data->getId()); + DisableBoundingBox(data->getId()); + + + + return data->getId(); + + } +} + +/** + * @pre the image is not null and has more than one scalar component + * @post Each component in the image is put in a single image + * @param vtkImageData* img, multiple component image i.e. an image of vectors like an rgb + * @return vtkImageData* double type image + */ +void VolumeRendererManager::GetImageDouble(vtkImageData* img, vtkImageData* imgushort){ + + + int *extent = img->GetExtent(); + + for(unsigned i = extent[0]; i < extent[1]; i++){ + for(unsigned j = extent[2]; j < extent[3]; j++){ + for(unsigned k = extent[4]; k < extent[5]; k++){ + if(img->GetScalarType() == VTK_UNSIGNED_CHAR){ + unsigned char *imgpoint = ((unsigned char*)img->GetScalarPointer(i, j, k)); + + unsigned short *vectimgpoint = (unsigned short*)imgushort->GetScalarPointer(i, j, k); + double temp = (double)(0.299*imgpoint[0] + 0.587*imgpoint[1] + 0.114*imgpoint[2]); + *vectimgpoint = temp*255.0; + + } + } + } + } +} + +/** + * @pre the image is not null and has more than one scalar component + * @post Each component in the image is separated to form a different image + * @param vtkImageData* img, multiple component image i.e. an image of vectors like an rgb + * @return vector a vector of images, one for each component + */ +void VolumeRendererManager::GetImages(vtkImageData* img, vector& vectimg){ + + for(unsigned i = 0; i < img->GetNumberOfScalarComponents(); i++){ + vectimg.push_back(vtkImageData::New()); + vectimg[i]->SetNumberOfScalarComponents(1); + vectimg[i]->SetExtent(img->GetExtent()); + vectimg[i]->SetSpacing(img->GetSpacing()); + vectimg[i]->SetOrigin(img->GetOrigin()); + vectimg[i]->SetScalarType(img->GetScalarType()); + vectimg[i]->AllocateScalars(); + } + + int *extent = img->GetExtent(); + + for(unsigned i = extent[0]; i < extent[1]; i++){ + for(unsigned j = extent[2]; j < extent[3]; j++){ + for(unsigned k = extent[4]; k < extent[5]; k++){ + if(img->GetScalarType() == VTK_UNSIGNED_CHAR){ + unsigned char *imgpoint = ((unsigned char*)img->GetScalarPointer(i, j, k)); + + for(unsigned l = 0; l < vectimg.size(); l++){ + unsigned char *vectimgpoint = (unsigned char*)vectimg[l]->GetScalarPointer(i, j, k); + *vectimgpoint = imgpoint[l]; + } + }else if(img->GetScalarType() == VTK_CHAR){ + char *imgpoint = ((char*)img->GetScalarPointer(i, j, k)); + + for(unsigned l = 0; l < vectimg.size(); l++){ + char *vectimgpoint = ( char*)vectimg[l]->GetScalarPointer(i, j, k); + *vectimgpoint = imgpoint[l]; + } + }else if(img->GetScalarType() == VTK_UNSIGNED_SHORT){ + unsigned short *imgpoint = ((unsigned short*)img->GetScalarPointer(i, j, k)); + + for(unsigned l = 0; l < vectimg.size(); l++){ + unsigned short *vectimgpoint = (unsigned short*)vectimg[l]->GetScalarPointer(i, j, k); + *vectimgpoint = imgpoint[l]; + } + }else if(img->GetScalarType() == VTK_SHORT){ + short *imgpoint = ((short*)img->GetScalarPointer(i, j, k)); + + for(unsigned l = 0; l < vectimg.size(); l++){ + short *vectimgpoint = ( short*)vectimg[l]->GetScalarPointer(i, j, k); + *vectimgpoint = imgpoint[l]; + } + } + } + } + } +} + /** ** Adds a prop3D to the manager and returns the identifier **/ @@ -200,5 +471,83 @@ vtkColorTransferFunction* VolumeRendererManager::GetColorFunction(int volumeid){ } void VolumeRendererManager::changeCompositeMIPFunction(int id, int function) throw (char *){ + if(id == -1){ + for(unsigned i = 0; i < prop3Dvect.size(); i++) + prop3Dvect[i]->changeCompositeMIPFunction(function); + }else{ getViewData(id)->changeCompositeMIPFunction(function); + } +} + +/** + Changes the interpolation of the volume rendering. + type == 0 for linear interpolation + type == 1 for nearest interpolation + */ +void VolumeRendererManager::changeInterpolationType(int type, int propid){ + if(propid == -1){ + for(unsigned i = 0; i < prop3Dvect.size(); i++) + prop3Dvect[i]->changeInterpolationType(type); + }else{ + getViewData(propid)->changeInterpolationType(type); + } +} + +/** + * Set the lookuptable to the volumes in memory + * if the id is set then it only changes the lookup table for a specific volume + */ +void VolumeRendererManager::SetLookupTable(vtkLookupTable* lookup, int id){ + if(id == -1){ + for(unsigned i = 0; i < prop3Dvect.size(); i++) + prop3Dvect[i]->SetLookupTable(lookup); + }else{ + getViewData(id)->SetLookupTable(lookup); + } + +} + +/** + * @returns all the props3D in this manager +*/ +vector< vtkProp3D* > VolumeRendererManager::getProps3D(){ + + vector< vtkProp3D* > propvects; + for(unsigned i = 0; i < prop3Dvect.size(); i++){ + propvects.push_back(prop3Dvect[i]->getProp3D()); + } + return propvects; +} + +/** + * @param std::vector greylevel, the corresponding greylevel in the image + * @param std::vector value, the corresponding value for the opacity + * @param int propid, the correspoding id, by default it applies the changes to the first volume in the array + */ +void VolumeRendererManager::setVolumeOpacity(std::vector greylevel, std::vector value, int propid){ + if(propid == -1){ + for(unsigned i = 0; i < prop3Dvect.size(); i++) + prop3Dvect[i]->setVolumeOpacity(greylevel, value); + }else{ + getViewData(propid)->setVolumeOpacity(greylevel, value); + } +} + +void VolumeRendererManager::EnableBoundingBox(vtkRenderWindowInteractor* interactor, int propid){ + if(propid == -1){ + for(unsigned i = 0; i < prop3Dvect.size(); i++) + prop3Dvect[i]->EnableBoundingBox(interactor); + }else{ + getViewData(propid)->EnableBoundingBox(interactor); + } +} + +void VolumeRendererManager::DisableBoundingBox(int propid){ + + if(propid == -1){ + for(unsigned i = 0; i < prop3Dvect.size(); i++) + prop3Dvect[i]->DisableBoundingBox(); + }else{ + getViewData(propid)->DisableBoundingBox(); + } } diff --git a/lib/Kernel/VTKObjects/VolumeRenderer/volumerenderermanager.h b/lib/Kernel/VTKObjects/VolumeRenderer/volumerenderermanager.h index 72a9124..bf7c680 100644 --- a/lib/Kernel/VTKObjects/VolumeRenderer/volumerenderermanager.h +++ b/lib/Kernel/VTKObjects/VolumeRenderer/volumerenderermanager.h @@ -4,8 +4,8 @@ Program: wxMaracas Module: $RCSfile: volumerenderermanager.h,v $ Language: C++ - Date: $Date: 2011/05/31 19:03:03 $ - Version: $Revision: 1.1 $ + Date: $Date: 2011/10/05 16:27:04 $ + Version: $Revision: 1.2 $ Copyright: (c) 2002, 2003 License: @@ -50,6 +50,18 @@ public: **/ int addVolume(int idTP, vtkImageData* img, std::string dataname) throw (char*); + /** + * @pre The image can have one or multiple components per voxel, and volume rendering is performed seprately over the + three of them. If the image has multiple components and the separate components flag is set to false, then + the vtkImageAppendComponents is used to create a single image. + * @post The volume rendering is performed over the image vol + * @param vtkImageData* the image volume + * @param bool independentcomponents, if the image has multiple components, the mapper will be created either for managing + an rgb image plus a luminance channel (the luminance will be calculated using the luminance image filter) + to control the opacity or to manage the multiple components in a single image + */ + int addVolume(vtkImageData* img, vtkRenderWindowInteractor* interactor, bool independentcomponents = false); + /** ** loads a prop3D from a nSTL file **/ @@ -106,6 +118,37 @@ public: vtkPiecewiseFunction* GetTransferFunction(int volumeid); vtkColorTransferFunction* GetColorFunction(int volumeid); + + + /** + Changes the interpolation of the volume rendering. + type == 0 for linear interpolation + type == 1 for nearest interpolation + */ + void changeInterpolationType(int type, int propid = -1); + + /** + * Set the lookuptable to the volumes in memory + * if the id is set then it only changes the lookup table for a specific volume + */ + void SetLookupTable(vtkLookupTable* lookup, int id = -1); + + /** + * @returns all the props3D in this manager + */ + vector< vtkProp3D* > getProps3D(); + + /** + * @param std::vector greylevel, the corresponding greylevel in the image + * @param std::vector value, the corresponding value for the opacity + * @param int propid, the correspoding id, by default it applies the changes to the first volume in the array + */ + void setVolumeOpacity(std::vector greylevel, std::vector value, int propid = -1); + + + void EnableBoundingBox(vtkRenderWindowInteractor* interactor, int propid = -1); + + void DisableBoundingBox(int propid = -1); private: std::vector prop3Dvect; @@ -114,6 +157,21 @@ private: int _idCount; + /** + * @pre the image is not null and has more than one scalar component + * @post Each component in the image is separated to form a different image + * @param vtkImageData* img, multiple component image i.e. an image of vectors like an rgb + * @return vector a vector of images, one for each component + */ + void GetImages(vtkImageData* img, vector& images); + + /** + * @pre the image is not null and has more than one scalar component + * @post Each component in the image is put in a single image + * @param vtkImageData* img, multiple component image i.e. an image of vectors like an rgb + * @return vtkImageData* double type image + */ + void GetImageDouble(vtkImageData* img, vtkImageData* imgdouble); diff --git a/lib/Kernel/VTKObjects/VolumeRenderer/volumerenderermanagerdata.cxx b/lib/Kernel/VTKObjects/VolumeRenderer/volumerenderermanagerdata.cxx index f267e3f..3e6ad74 100644 --- a/lib/Kernel/VTKObjects/VolumeRenderer/volumerenderermanagerdata.cxx +++ b/lib/Kernel/VTKObjects/VolumeRenderer/volumerenderermanagerdata.cxx @@ -9,9 +9,20 @@ #include "boxSurfaceObserver.h" #include "vtkProperty.h" +#include + +#if VTK_MAJOR_VERSION >= 5 + #if VTK_MINOR_VERSION >= 6 + #include "vtkGPUVolumeRayCastMapper.h" + #endif +#endif using namespace std; +VolumeRendererManagerData::VolumeRendererManagerData(vtkImageData* vol, bool usegpu){ + Initialize(vol, "", usegpu); +} + VolumeRendererManagerData::VolumeRendererManagerData(vtkImageData* vol, std::string dataname){ Initialize(vol, dataname); @@ -26,35 +37,30 @@ VolumeRendererManagerData::VolumeRendererManagerData(vtkImageData* vol, vtkRende } -VolumeRendererManagerData::VolumeRendererManagerData(vtkImageData* vol, bool usegpu, std::string dataname){ - Initialize(vol, dataname, usegpu); -} - void VolumeRendererManagerData::Initialize(vtkImageData* vol, std::string dataname, bool usegpu){ + _id = 0; _vol = vol; _dataname = dataname; - _tfun = vtkPiecewiseFunction::New(); - _ctfun = vtkColorTransferFunction::New(); _volumePlanes = vtkPlanes::New(); _volumeProperty = vtkVolumeProperty::New(); _volumeProperty->SetInterpolationTypeToLinear(); //_volumeProperty->ShadeOn(); - _volumeProperty->DisableGradientOpacityOn(); - _volumeProperty->SetColor(_ctfun); + _volumeProperty->DisableGradientOpacityOn(); + _tfun = vtkPiecewiseFunction::New(); _volumeProperty->SetScalarOpacity(_tfun ); - + _ctfun = vtkColorTransferFunction::New(); _newvol = vtkVolume::New(); - _newvol->SetProperty(_volumeProperty ); + _newvol->SetProperty(_volumeProperty ); + - _volumeMapper = 0; - _volumeMappergpu = 0; _compositeFunction = 0; _MIPFunction = 0; - _boxWidgetS1 = 0; + + BoxWidget = 0; /* EED9Juin2011 if(usegpu && _vol->GetDataDimension() > 2){ @@ -82,33 +88,31 @@ void VolumeRendererManagerData::Initialize(vtkImageData* vol, std::string datana } */ - vtkVolumeMapper *volMapperTmp; - if(usegpu && _vol->GetDataDimension() > 2){ - #if (VTK_MAYOR_VERSION>=5 && VTK_MINOR_VERSION>=6) - _volumeMappergpu = vtkGPUVolumeRayCastMapper::New(); - _volumeMappergpu->AutoAdjustSampleDistancesOn(); - volMapperTmp = _volumeMappergpu; - #else - _compositeFunction = vtkVolumeRayCastCompositeFunction::New(); - _MIPFunction = vtkVolumeRayCastMIPFunction::New(); - _volumeMapper = vtkVolumeRayCastMapper::New(); - _volumeMapper->SetVolumeRayCastFunction(_compositeFunction); - _volumeMapper->AutoAdjustSampleDistancesOn(); - volMapperTmp = _volumeMapper; - #endif - }else{ - _compositeFunction = vtkVolumeRayCastCompositeFunction::New(); - _MIPFunction = vtkVolumeRayCastMIPFunction::New(); - _volumeMapper = vtkVolumeRayCastMapper::New(); - _volumeMapper->SetVolumeRayCastFunction(_compositeFunction); - _volumeMapper->AutoAdjustSampleDistancesOn(); - volMapperTmp = _volumeMapper; - } + VolumeMapper = 0; +#if VTK_MAJOR_VERSION >= 5 + #if VTK_MINOR_VERSION >= 6 + vtkGPUVolumeRayCastMapper * volumeMappergpu = vtkGPUVolumeRayCastMapper::New(); + volumeMappergpu->AutoAdjustSampleDistancesOn(); + VolumeMapper = volumeMappergpu; + #endif +#else + + _volumeProperty->SetColor(_ctfun); + + + _compositeFunction = vtkVolumeRayCastCompositeFunction::New(); + _MIPFunction = vtkVolumeRayCastMIPFunction::New(); + vtkVolumeRayCastMapper* volumeMapper = vtkVolumeRayCastMapper::New(); + volumeMapper->SetVolumeRayCastFunction(_compositeFunction); + volumeMapper->AutoAdjustSampleDistancesOn(); + VolumeMapper = volumeMapper; +#endif - volMapperTmp->SetClippingPlanes( _volumePlanes ); - _newvol->SetMapper(volMapperTmp ); - volMapperTmp->SetInput( _vol ); - volMapperTmp->Update(); + + VolumeMapper->SetClippingPlanes( _volumePlanes ); + _newvol->SetMapper(VolumeMapper ); + VolumeMapper->SetInput( _vol ); + VolumeMapper->Update(); _newvol->Update(); } @@ -126,54 +130,71 @@ VolumeRendererManagerData::~VolumeRendererManagerData() _compositeFunction->Delete(); if(_MIPFunction) _MIPFunction->Delete(); - if(_volumeMapper) - _volumeMapper->Delete(); - if(_volumeMappergpu) - _volumeMappergpu->Delete(); - if(_boxWidgetS1){ + if(VolumeMapper) + VolumeMapper->Delete(); + + if(BoxWidget){ DisableBoundingBox(); } } +void VolumeRendererManagerData::SetIndependentComponents(bool independent){ + + if(!independent){ + _volumeProperty->IndependentComponentsOff(); + }else{ + _volumeProperty->IndependentComponentsOn(); + } +} void VolumeRendererManagerData::EnableBoundingBox(vtkRenderWindowInteractor* interactor) { //EED9Juin2011 if(_volumeMappergpu){ - if(_boxWidgetS1==NULL){ - _boxWidgetS1 = vtkBoxWidget::New(); - _boxWidgetS1->SetInteractor( interactor ); - _boxWidgetS1->SetPlaceFactor(1.01); - _boxWidgetS1->SetInput( _vol ); - _boxWidgetS1->InsideOutOn(); - _boxWidgetS1->PlaceWidget(); + if(!BoxWidget){ + BoxWidget = vtkBoxWidget::New(); + BoxWidget->SetInteractor( interactor ); + BoxWidget->SetPlaceFactor(1.01); + + BoxWidget->SetInput( _vol ); + BoxWidget->InsideOutOn(); + BoxWidget->PlaceWidget(); + vtkBoxWidgetCallback *callback = vtkBoxWidgetCallback::New(); - if (_volumeMapper!=0){ - callback->SetMapper(_volumeMapper); - } else { - callback->SetMapper(_volumeMappergpu); - } - _boxWidgetS1->AddObserver(vtkCommand::InteractionEvent, callback); + callback->SetMapper(VolumeMapper); + + + BoxWidget->AddObserver(vtkCommand::InteractionEvent, callback); callback->Delete(); - _boxWidgetS1->EnabledOn(); - _boxWidgetS1->GetSelectedFaceProperty()->SetOpacity(0.0); + + BoxWidget->EnabledOn(); + BoxWidget->GetSelectedFaceProperty()->SetOpacity(0.0); + cout<<"JPRG::VolumeRendererManagerData::EnableBoundingBox::CREATE"<EnabledOn(); + cout<<"JPRG::VolumeRendererManagerData::EnableBoundingBox"<EnabledOn(); + } //EED9Juin2011 } } void VolumeRendererManagerData::DisableBoundingBox(){ - if(_boxWidgetS1){ + + if(BoxWidget){ + BoxWidget->EnabledOff(); + //BoxWidget->Delete(); + //BoxWidget = 0; + cout<<"JPRG::VolumeRendererManagerData::DisableBoundingBox"<EnabledOff(); - //_boxWidgetS1->Delete(); - //_boxWidgetS1 = 0; + + } } @@ -228,7 +249,7 @@ void VolumeRendererManagerData::checkInvariant()throw (char *){ if(!_MIPFunction){ throw "No MIP function initialized"; } - if(!_volumeMapper && !_volumeMappergpu){ + if(!VolumeMapper){ throw "No volume mapper initialized"; } } @@ -272,26 +293,68 @@ void VolumeRendererManagerData::setDataname(std::string dataname){ } void VolumeRendererManagerData::changeCompositeMIPFunction(int function){ - checkInvariant(); - if(_volumeMapper){ + //checkInvariant(); + if(VolumeMapper){ +#if VTK_MAJOR_VERSION >= 5 + #if VTK_MINOR_VERSION >= 6 + if(dynamic_cast(VolumeMapper)){ + vtkVolumeRayCastMapper* volumemapper = dynamic_cast(VolumeMapper); + if(function == 0){ + volumemapper->SetVolumeRayCastFunction(_compositeFunction); + }else{ + volumemapper->SetVolumeRayCastFunction(_MIPFunction); + } + }else if(dynamic_cast(VolumeMapper)){ + vtkGPUVolumeRayCastMapper* volumemapper = dynamic_cast(VolumeMapper); + if(function == 0){ + volumemapper->SetBlendModeToComposite(); + }else if(function == 1){ + volumemapper->SetBlendModeToMaximumIntensity(); + }else if(function == 2){ + volumemapper->SetBlendModeToMinimumIntensity(); + } + } + #endif +#else + vtkGPUVolumeRayCastMapper* volumemapper = dynamic_cast(VolumeMapper); if(function == 0){ - _volumeMapper->SetVolumeRayCastFunction(_compositeFunction); - }else{ - _volumeMapper->SetVolumeRayCastFunction(_MIPFunction); + volumemapper->SetBlendModeToComposite(); + }else if(function == 1){ + volumemapper->SetBlendModeToMaximumIntensity(); + }else if(function == 2){ + volumemapper->SetBlendModeToMinimumIntensity(); } +#endif } } void VolumeRendererManagerData::SetLookupTable(vtkLookupTable* lookuptable){ - _ctfun->RemoveAllPoints(); - vtkColorTransferFunction* colort = (vtkColorTransferFunction*)lookuptable; - for(int i = 0; i < colort->GetSize(); i++){ - double val[6]; - colort->GetNodeValue(i, val); - cout<< "JPRG::VolumeRendererManagerData::SetLookupTable::"<AddRGBPoint(val[0], val[1], val[2], val[3]); - } - _newvol->Update(); + if(lookuptable){ + _ctfun->RemoveAllPoints(); + vtkColorTransferFunction* colort = (vtkColorTransferFunction*)lookuptable; + for(int i = 0; i < colort->GetSize(); i++){ + double val[6]; + colort->GetNodeValue(i, val); + cout<< "JPRG::VolumeRendererManagerData::SetLookupTable::"<AddRGBPoint(val[0], val[1], val[2], val[3]); + } + _newvol->Update(); + } + +} + +void VolumeRendererManagerData::changeInterpolationType(int type){ + //checkInvariant(); + if(type == 0){ + _volumeProperty->SetInterpolationTypeToLinear(); + }else if(type == 1){ + _volumeProperty->SetInterpolationTypeToNearest(); + } +} + +void VolumeRendererManagerData::SetColorTransferFunction(int i, vtkColorTransferFunction* colorf){ + + _volumeProperty->SetColor(i, colorf); } diff --git a/lib/Kernel/VTKObjects/VolumeRenderer/volumerenderermanagerdata.h b/lib/Kernel/VTKObjects/VolumeRenderer/volumerenderermanagerdata.h index ea1cd4a..fd530b6 100644 --- a/lib/Kernel/VTKObjects/VolumeRenderer/volumerenderermanagerdata.h +++ b/lib/Kernel/VTKObjects/VolumeRenderer/volumerenderermanagerdata.h @@ -6,7 +6,7 @@ #include #include #include -#include + #include #include #include @@ -19,13 +19,10 @@ #include #include -#if (VTK_MAYOR_VERSION>=5 && VTK_MINOR_VERSION>=6) - #include -#endif - #include +using namespace std; // Callback for moving the planes from the box widget to the mapper class vtkBoxWidgetCallback : public vtkCommand @@ -36,23 +33,30 @@ public: virtual void Execute(vtkObject *caller, unsigned long, void*) { vtkBoxWidget *widget = reinterpret_cast(caller); - if (this->Mapper) - { - vtkPlanes *planes = vtkPlanes::New(); - widget->GetPlanes(planes); - this->Mapper->SetClippingPlanes(planes); - planes->Delete(); - } + vtkPlanes *planes = vtkPlanes::New(); + widget->GetPlanes(planes); + for(unsigned i = 0; i< VectorMapper.size(); i++){ + VectorMapper[i]->SetClippingPlanes(planes); + } + planes->Delete(); } void SetMapper(vtkAbstractMapper* m) - { this->Mapper = m; } + { if(VectorMapper.size() == 0){ + VectorMapper.push_back(m); + }else{ + VectorMapper[0] = m; + } + } + + void AddMapper(vtkAbstractMapper* m){ + VectorMapper.push_back(m); + } protected: vtkBoxWidgetCallback() - { this->Mapper = 0; } + { } - //vtkVolumeRayCastMapper *Mapper; - vtkAbstractMapper *Mapper; + vector< vtkAbstractMapper* > VectorMapper; }; @@ -61,7 +65,9 @@ class VolumeRendererManagerData : public vtkObject{ public: VolumeRendererManagerData(vtkImageData* vol, std::string dataname=""); VolumeRendererManagerData(vtkImageData* vol, vtkRenderer* render, std::string dataname=""); - VolumeRendererManagerData(vtkImageData* vol, bool usegpu, std::string dataname=""); + VolumeRendererManagerData(vtkImageData* vol, bool usegpu); + + ~VolumeRendererManagerData(); /** @@ -130,6 +136,24 @@ public: void EnableBoundingBox(vtkRenderWindowInteractor* interactor); void DisableBoundingBox(); + + /** + changes the interoplation type of the volume + type = 0 linear + type = 1 nearest + */ + void changeInterpolationType(int type); + + + vtkGetMacro(BoxWidget, vtkBoxWidget*); + vtkSetMacro(BoxWidget, vtkBoxWidget*); + + vtkGetMacro(VolumeMapper, vtkVolumeMapper*); + vtkSetMacro(VolumeMapper, vtkVolumeMapper*); + + void SetColorTransferFunction(int i, vtkColorTransferFunction* colorf); + + void SetIndependentComponents(bool independent); protected: /** * Prop 3D (data actor) @@ -149,16 +173,7 @@ private: int _id; vtkVolumeRayCastCompositeFunction *_compositeFunction; - vtkPlanes *_volumePlanes; - vtkVolumeRayCastMapper *_volumeMapper; - - -#if (VTK_MAYOR_VERSION>=5 && VTK_MINOR_VERSION>=6) - vtkGPUVolumeRayCastMapper *_volumeMappergpu; -#else - vtkVolumeRayCastMapper *_volumeMappergpu; -#endif - + vtkPlanes *_volumePlanes; vtkVolumeProperty *_volumeProperty; vtkVolume *_newvol; @@ -168,7 +183,8 @@ private: /** ** boxwidget to control the volume **/ - vtkBoxWidget* _boxWidgetS1; + vtkBoxWidget* BoxWidget; + vtkVolumeMapper *VolumeMapper; void Initialize(vtkImageData* vol, std::string dataname, bool usegpu = false); diff --git a/lib/maracasVisuLib/CMakeLists.txt b/lib/maracasVisuLib/CMakeLists.txt index 83d09b1..fc4152e 100644 --- a/lib/maracasVisuLib/CMakeLists.txt +++ b/lib/maracasVisuLib/CMakeLists.txt @@ -162,14 +162,24 @@ FILE(GLOB ${LIBRARY_NAME}_HEADERS_CUTMODULE src/CutModule/interface/*.h src/CutM # Sets the settings for macro CREA_ADVANCED_INSTALL_LIBRARY_FOR_CMAKE SET(${LIBRARY_NAME}_INSTALL_FOLDER ${LIBRARY_NAME}) + SET(${LIBRARY_NAME}_LIBRARIES ${LIBRARY_NAME} - BaseVolumeRenderer - BaseSurfaceRenderer - GUIWxSurfaceRenderer - GUIWxVolumeRenderer - KernelViewerWidgets - KernelVolumeRenderer - KernelSurfaceRenderer ) + KernelVolumeRenderer + KernelViewerWidgets + KernelSurfaceRenderer + BaseVolumeRenderer + BaseSurfaceRenderer + ) + +# SET(${LIBRARY_NAME}_LIBRARIES ${LIBRARY_NAME} +# BaseVolumeRenderer +# BaseSurfaceRenderer +# GUIWxSurfaceRenderer +# GUIWxVolumeRenderer +# KernelViewerWidgets +# KernelVolumeRenderer +# KernelSurfaceRenderer ) + # FILE(RELATIVE_PATH # ${LIBRARY_NAME}_BUILD_TREE_RELATIVE_INCLUDE_PATHS diff --git a/lib/maracasVisuLib/src/kernel/PlanesOperations.cxx b/lib/maracasVisuLib/src/kernel/PlanesOperations.cxx index b0c7ebd..a87830a 100644 --- a/lib/maracasVisuLib/src/kernel/PlanesOperations.cxx +++ b/lib/maracasVisuLib/src/kernel/PlanesOperations.cxx @@ -5,6 +5,8 @@ ** Start of data viewmanagerData *********************************************************************************************/ +using namespace std; + PlanesOperations::PlanesOperations() { } @@ -63,7 +65,7 @@ double* PlanesOperations::getNormal(double* vect) return vectnorm; } -double* PlanesOperations::makeVector(double podouble0[3], double podouble1[3]) +double* PlanesOperations::makeVector(double *podouble0, double *podouble1) { double *vect; vect = new double[3]; @@ -75,7 +77,134 @@ double* PlanesOperations::makeVector(double podouble0[3], double podouble1[3]) return vect; } +void PlanesOperations::getCrossProduct(double* vect0,double* vect1, double* vectres){ + vectres[0] = vect0[1]*vect1[2]-(vect0[2]*vect1[1]); + vectres[1] = -(vect0[0]*vect1[2]-(vect0[2]*vect1[0])); + vectres[2] = vect0[0]*vect1[1]-(vect0[1]*vect1[0]); +} + +void PlanesOperations::getNormal(double* vect, double* vectnorm){ + + double mag = getMagnitud(vect); + + if(mag!=0){ + vectnorm[0] = vect[0]/mag; + vectnorm[1] = vect[1]/mag; + vectnorm[2] = vect[2]/mag; + }else{ + vectnorm[0] = 0; + vectnorm[1] = 0; + vectnorm[2] = 0; + } +} + +void PlanesOperations::makeVector(double* podouble0, double* podouble1, double* vectres){ + vectres[0] = podouble1[0] - podouble0[0]; + vectres[1] = podouble1[1] - podouble0[1]; + vectres[2] = podouble1[2] - podouble0[2]; +} + double PlanesOperations::getDotProduct(double* vect0,double* vect1){ return vect0[0]*vect1[0] + vect0[1]*vect1[1] + vect0[2]*vect1[2]; } +void PlanesOperations::addVectors(double* vect0, double* vect1, double*vectres){ + + vectres[0]= vect0[0] + vect1[0]; + vectres[1]= vect0[1] + vect1[1]; + vectres[2]= vect0[2] + vect1[2]; +} + +void PlanesOperations::scalarVector(double* vect0, double scalar, double*vectres){ + + vectres[0]= vect0[0]*scalar; + vectres[1]= vect0[1]*scalar; + vectres[2]= vect0[2]*scalar; +} + +vector PlanesOperations::getCrossProduct(vector vect0,vector vect1){ + + vector vectCross; + + for(unsigned i = 0; i < vect0.size(); i++){ + + unsigned ii = (i + 1 == vect0.size())? 0: i + 1; + unsigned iii = (ii + 1 == vect0.size())? 0: ii + 1; + + vectCross.push_back( vect0[ii]*vect1[iii]- vect0[iii]*vect1[ii] ); + + } + return vectCross; + +} +double PlanesOperations::getDotProduct(vector vect0,vector vect1){ + + double sum = 0; + + for(unsigned i = 0; i < vect0.size(); i++) sum += vect0[i]*vect1[i]; + + return sum; +} +vector PlanesOperations::getNormal(vector vect){ + vector vectnorm; + double mag = getMagnitud(vect); + + for(unsigned i = 0; i < vect.size(); i++){ + + if(mag != 0){ + vectnorm.push_back(vect[i]/mag); + }else{ + vectnorm.push_back(0); + } + } + return vectnorm; +} +double PlanesOperations::getMagnitud(vector vect){ + double mag = 0; + + for(unsigned i = 0; i < vect.size(); i++) mag += pow(vect[i], 2); + + mag = sqrt(mag); + + //std::cout<<"mag "< PlanesOperations::makeVector(vector podouble0, vector podouble1){ + + vector vector; + + for(unsigned i = 0; i < podouble0.size(); i++){ + vector.push_back(podouble1[i] - podouble0[i]); + } + return vector; +} + +/** +* Adds to vectors, the result is in vectres; +*@param double* vect0, the first vector +*@param double* vect1, the second vector +*@param double* vectres, the resulting vector +*/ +vector PlanesOperations::addVectors(vector vect0, vector vect1){ + vector vectres; + for(unsigned i = 0; i < vect0.size(); i++){ + vectres.push_back(vect0[i] + vect1[i]); + } + return vectres; +} + +/** +* multiply a vector with a given scalar +*@param double* vect0, the vector +*@param double scalar, the scalar value +*@param double* vectres, the resulting vector +*/ +vector PlanesOperations::scalarVector(vector vect0, double scalar){ + vector vectres; + for(unsigned i = 0; i < vect0.size(); i++){ + vectres.push_back(vect0[i]*scalar); + } + return vectres; +} + diff --git a/lib/maracasVisuLib/src/kernel/PlanesOperations.h b/lib/maracasVisuLib/src/kernel/PlanesOperations.h index 451bd10..ea9c2ee 100644 --- a/lib/maracasVisuLib/src/kernel/PlanesOperations.h +++ b/lib/maracasVisuLib/src/kernel/PlanesOperations.h @@ -4,6 +4,9 @@ #include #include +#include + +using namespace std; class PlanesOperations { @@ -13,11 +16,49 @@ public: - double* getCrossProduct(double* vect0,double* vect1); - double getDotProduct(double* vect0,double* vect1); + double* getCrossProduct(double* vect0,double* vect1); + double getDotProduct(double* vect0,double* vect1); double* getNormal(double* vect); double getMagnitud(double* vect); - double* makeVector(double podouble0[3], double podouble1[3]); + double* makeVector(double *podouble0, double* podouble1); + + void getCrossProduct(double* vect0,double* vect1, double* vectres); + void getNormal(double* vect, double* vectnorm); + void makeVector(double* podouble0, double* podouble1, double* vectres); + /** + * Adds to vectors, the result is in vectres; + *@param double* vect0, the first vector + *@param double* vect1, the second vector + *@param double* vectres, the resulting vector + */ + void addVectors(double* vect0, double* vect1, double*vectres); + /** + * multiply a vector with a given scalar + *@param double* vect0, the vector + *@param double scalar, the scalar value + *@param double* vectres, the resulting vector + */ + void scalarVector(double* vect0, double scalar, double*vectres); + + vector getCrossProduct(vector vect0,vector vect1); + double getDotProduct(vector vect0,vector vect1); + vector getNormal(vector vect); + double getMagnitud(vector vect); + vector makeVector(vector podouble0, vector podouble1); + /** + * Adds to vectors, the result is in vectres; + *@param double* vect0, the first vector + *@param double* vect1, the second vector + *@param double* vectres, the resulting vector + */ + vector addVectors(vector vect0, vector vect1); + /** + * multiply a vector with a given scalar + *@param double* vect0, the vector + *@param double scalar, the scalar value + *@param double* vectres, the resulting vector + */ + vector scalarVector(vector vect0, double scalar); };