1 #include "volumerenderermanager.h"
3 /*=========================================================================
6 Module: $RCSfile: volumerenderermanager.cxx,v $
8 Date: $Date: 2011/10/19 16:08:29 $
9 Version: $Revision: 1.3 $
11 Copyright: (c) 2002, 2003
14 This software is distributed WITHOUT ANY WARRANTY; without even
15 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 PURPOSE. See the above copyright notice for more information.
18 =========================================================================*/
20 #include <vtkMetaImageReader.h>
21 #include <vtkImageCast.h>
23 #include "vtkImageLuminance.h"
24 #include "vtkImageAppendComponents.h"
25 #include "vtkSmartPointer.h"
32 ** Start of the manager class
34 VolumeRendererManager::VolumeRendererManager(){
38 VolumeRendererManager::~VolumeRendererManager(){
42 for(unsigned i = 0; i < prop3Dvect.size();i++){
43 prop3Dvect[i]->Delete();
49 ** Sets the renderer to manage the prop3D from the view
51 void VolumeRendererManager::setRenderer(vtkRenderer* renderer){
56 ** Gets the renderer which manage the prop3D from the view
58 vtkRenderer* VolumeRendererManager::getRenderer(){
65 void VolumeRendererManager::Update(int ppid){
66 VolumeRendererManagerData* data = this->getViewData(ppid);
72 * @pre The image can have one or multiple components per voxel, and volume rendering is performed seprately over the
73 three of them. If the image has multiple components and the separate components flag is set to false, then
74 the vtkImageAppendComponents is used to create a single image.
75 * @post The volume rendering is performed over the image vol
76 * @param vtkImageData* the image volume
77 * @param bool separatecomponents, if the image has multiple components, then a mapper is used for each of the channels
78 if this flag is set to false and the volume has multiple components, vtkImageAppendComponents is used to create
79 a single representation of the image.
81 int VolumeRendererManager::addVolume(vtkImageData* img, vtkRenderWindowInteractor* interactor, bool independentcomponents){
82 if(img->GetNumberOfScalarComponents() > 1 && !independentcomponents){
88 vtkSmartPointer< vtkImageLuminance > luminance = vtkSmartPointer< vtkImageLuminance >::New();
89 luminance->SetInput(img);
92 vtkSmartPointer< vtkImageAppendComponents > append = vtkSmartPointer< vtkImageAppendComponents >::New();
93 append->SetInput(0, img);
94 append->SetInput(1, luminance->GetOutput());
99 VolumeRendererManagerData* data = new VolumeRendererManagerData(append->GetOutput(), true);
100 data->SetIndependentComponents(independentcomponents);
103 prop3Dvect.push_back(data);
105 data->setId(_idCount);
113 vector< vtkImageData* > vectimg;
114 GetImages(img, vectimg);
115 vtkBoxWidget* boxw = 0;
116 for(unsigned i = 0; i < vectimg.size(); i++){
117 VolumeRendererManagerData* data = new VolumeRendererManagerData(vectimg[i], "");
119 vtkColorTransferFunction* colorf = data->GetColorFunction();
120 colorf->RemoveAllPoints();
121 double r = 0, g = 0, b = 0;
122 for(unsigned j = 0; j < 255; j++){
138 colorf->AddRGBPoint(j, r, g, b);
141 prop3Dvect.push_back(data);
143 data->setId(_idCount);
147 EnableBoundingBox(interactor, data->getId());
148 DisableBoundingBox(data->getId());
149 boxw = data->GetBoxWidget();
151 data->SetBoxWidget(boxw);
155 boxw->RemoveAllObservers();
157 vtkBoxWidgetCallback *callback = vtkBoxWidgetCallback::New();
159 for(unsigned i = 0; i < prop3Dvect.size(); i++){
160 VolumeRendererManagerData* data = prop3Dvect[i];
161 callback->AddMapper(data->GetVolumeMapper());
164 boxw->AddObserver(vtkCommand::InteractionEvent, callback);
169 /*vtkImageData* imgshort = 0;
170 imgshort = vtkImageData::New();
171 imgshort->SetNumberOfScalarComponents(1);
172 imgshort->SetExtent(img->GetExtent());
173 imgshort->SetSpacing(img->GetSpacing());
174 imgshort->SetOrigin(img->GetOrigin());
175 imgshort->SetScalarTypeToUnsignedShort();
176 imgshort->AllocateScalars();
177 GetImageDouble(img, imgshort);
179 VolumeRendererManagerData* data = new VolumeRendererManagerData(imgshort, "");
181 vtkColorTransferFunction* colorf = data->GetColorFunction();
182 colorf->RemoveAllPoints();
184 map< unsigned short, vector< double > > colormap;
186 int *extent = img->GetExtent();
188 for(unsigned i = extent[0]; i < extent[1]; i++){
189 for(unsigned j = extent[2]; j < extent[3]; j++){
190 for(unsigned k = extent[4]; k < extent[5]; k++){
192 unsigned char *imgpoint = ((unsigned char*)img->GetScalarPointer(i, j, k));
193 double temp = (double)(0.299*imgpoint[0] + 0.587*imgpoint[1] + 0.114*imgpoint[2]);
194 unsigned short val = temp*255.0;
196 vector< double > rgb;
197 rgb.push_back(0.299*imgpoint[0]);
198 rgb.push_back(0.587*imgpoint[1]);
199 rgb.push_back(0.114*imgpoint[2]);
208 map< unsigned short, vector< double > >::iterator it;
209 for(it = colormap.begin(); it != colormap.end(); ++it){
211 colorf->AddRGBPoint((*it).first, (*it).second[0] / 255.0, (*it).second[1] / 255.0, (*it).second[2] / 255.0);
214 prop3Dvect.push_back(data);
216 data->setId(_idCount);
217 EnableBoundingBox(interactor, data->getId());
218 DisableBoundingBox(data->getId());
225 VolumeRendererManagerData* data = new VolumeRendererManagerData(img, "");
226 prop3Dvect.push_back(data);
229 data->setId(_idCount);
232 EnableBoundingBox(interactor, data->getId());
233 DisableBoundingBox(data->getId());
237 return data->getId();
243 * @pre the image is not null and has more than one scalar component
244 * @post Each component in the image is put in a single image
245 * @param vtkImageData* img, multiple component image i.e. an image of vectors like an rgb
246 * @return vtkImageData* double type image
248 void VolumeRendererManager::GetImageDouble(vtkImageData* img, vtkImageData* imgushort){
251 int *extent = img->GetExtent();
253 for(unsigned i = extent[0]; i < extent[1]; i++){
254 for(unsigned j = extent[2]; j < extent[3]; j++){
255 for(unsigned k = extent[4]; k < extent[5]; k++){
256 if(img->GetScalarType() == VTK_UNSIGNED_CHAR){
257 unsigned char *imgpoint = ((unsigned char*)img->GetScalarPointer(i, j, k));
259 unsigned short *vectimgpoint = (unsigned short*)imgushort->GetScalarPointer(i, j, k);
260 double temp = (double)(0.299*imgpoint[0] + 0.587*imgpoint[1] + 0.114*imgpoint[2]);
261 *vectimgpoint = temp*255.0;
270 * @pre the image is not null and has more than one scalar component
271 * @post Each component in the image is separated to form a different image
272 * @param vtkImageData* img, multiple component image i.e. an image of vectors like an rgb
273 * @return vector<vtkImageData* > a vector of images, one for each component
275 void VolumeRendererManager::GetImages(vtkImageData* img, vector<vtkImageData* >& vectimg){
277 for(unsigned i = 0; i < img->GetNumberOfScalarComponents(); i++){
278 vectimg.push_back(vtkImageData::New());
279 vectimg[i]->SetNumberOfScalarComponents(1);
280 vectimg[i]->SetExtent(img->GetExtent());
281 vectimg[i]->SetSpacing(img->GetSpacing());
282 vectimg[i]->SetOrigin(img->GetOrigin());
283 vectimg[i]->SetScalarType(img->GetScalarType());
284 vectimg[i]->AllocateScalars();
287 int *extent = img->GetExtent();
289 for(unsigned i = extent[0]; i < extent[1]; i++){
290 for(unsigned j = extent[2]; j < extent[3]; j++){
291 for(unsigned k = extent[4]; k < extent[5]; k++){
292 if(img->GetScalarType() == VTK_UNSIGNED_CHAR){
293 unsigned char *imgpoint = ((unsigned char*)img->GetScalarPointer(i, j, k));
295 for(unsigned l = 0; l < vectimg.size(); l++){
296 unsigned char *vectimgpoint = (unsigned char*)vectimg[l]->GetScalarPointer(i, j, k);
297 *vectimgpoint = imgpoint[l];
299 }else if(img->GetScalarType() == VTK_CHAR){
300 char *imgpoint = ((char*)img->GetScalarPointer(i, j, k));
302 for(unsigned l = 0; l < vectimg.size(); l++){
303 char *vectimgpoint = ( char*)vectimg[l]->GetScalarPointer(i, j, k);
304 *vectimgpoint = imgpoint[l];
306 }else if(img->GetScalarType() == VTK_UNSIGNED_SHORT){
307 unsigned short *imgpoint = ((unsigned short*)img->GetScalarPointer(i, j, k));
309 for(unsigned l = 0; l < vectimg.size(); l++){
310 unsigned short *vectimgpoint = (unsigned short*)vectimg[l]->GetScalarPointer(i, j, k);
311 *vectimgpoint = imgpoint[l];
313 }else if(img->GetScalarType() == VTK_SHORT){
314 short *imgpoint = ((short*)img->GetScalarPointer(i, j, k));
316 for(unsigned l = 0; l < vectimg.size(); l++){
317 short *vectimgpoint = ( short*)vectimg[l]->GetScalarPointer(i, j, k);
318 *vectimgpoint = imgpoint[l];
327 ** Adds a prop3D to the manager and returns the identifier
329 int VolumeRendererManager::addVolume(int idTP, vtkImageData* vol, std::string dataname) throw(char*){
333 VolumeRendererManagerData* data = new VolumeRendererManagerData(vol, dataname);
334 prop3Dvect.push_back(data);
335 _renderer->AddActor(data->getProp3D());
338 data->setId(_idCount);
345 printf("VolumeRendererManager::addVolume->idVolumeRenderer: %i\n", data->getId());
346 return data->getId();
348 throw "Check mhd imagefile file or input";
353 ** adds or removes an actor depending of the bool value
356 void VolumeRendererManager::addRemoveActor(int propid, bool addremove) throw(char*){
359 VolumeRendererManagerData* data = this->getViewData(propid);
360 if(data->getProp3D()!=NULL){
362 _renderer->AddViewProp(data->getProp3D());
364 _renderer->RemoveViewProp(data->getProp3D());
371 ** Changes the opacity in a prop3D
373 void VolumeRendererManager::setVolumeOpacity(int propid, std::vector<double> greylevel,std::vector<double> value) throw(char*){
376 printf("EED VolumeRendererManager::setVolumeOpacity %d\n",propid);
378 VolumeRendererManagerData* volrenman = this->getViewData(propid);
381 volrenman->setVolumeOpacity(greylevel, value);
383 printf("EED VolumeRendererManager::setVolumeOpacity Warning volrenman NULL\n");
394 void VolumeRendererManager::setVolumeColor(int volid, std::vector<double> greylevel,
395 std::vector<double> red,
396 std::vector<double> green,
397 std::vector<double> blue)throw(char*){
398 printf("EED VolumeRendererManager::setVolumeColor start \n");
401 printf("EED VolumeRendererManager::setVolumeColor %d\n",volid);
403 VolumeRendererManagerData* volrenman = this->getViewData(volid);
406 this->getViewData(volid)->setVolumeColor(greylevel, red, green, blue);
408 printf("EED VolumeRendererManager::setVolumeColor Warning volrenman NULL\n");
412 printf("EED VolumeRendererManager::setVolumeColor end \n");
415 vtkImageData* VolumeRendererManager::getImageData(std::string filename){
416 if(filename.compare("")!= 0){
418 vtkMetaImageReader* reader = vtkMetaImageReader::New();
419 reader->SetFileName(filename.c_str());
421 vtkImageData* img = reader->GetOutput();
423 vtkImageCast* cast = vtkImageCast::New();
425 cast->SetOutputScalarTypeToUnsignedShort();
429 return cast->GetOutput();
435 vtkImageData* VolumeRendererManager::getImageData(){
439 void VolumeRendererManager::checkInvariant() throw(char*){
440 printf("EED VolumeRendererManager::checkInvariant start\n");
441 if(this->_renderer==NULL){
442 throw "Renderer not set";
444 printf("EED VolumeRendererManager::checkInvariant end \n");
447 VolumeRendererManagerData* VolumeRendererManager::getViewData(int id) throw(char*){
449 for(i = 0; i < (int)(prop3Dvect.size());i++){
450 if(prop3Dvect[i]->getId() == id){
451 return prop3Dvect[i];
454 throw "id not found in the data";
459 void VolumeRendererManager::deleteActor(int propid) throw (char *){
462 this->addRemoveActor(propid, false);
466 for(i = 0; i < (int)(prop3Dvect.size())&&!exit;i++){
467 if(prop3Dvect[i]->getId() == propid){
473 VolumeRendererManagerData* data = prop3Dvect[n];
475 for(j = i; j < (int)(prop3Dvect.size())-1;j++){
476 prop3Dvect[j] = prop3Dvect[j+1];
479 prop3Dvect.pop_back();
481 throw "id not found in the data";
486 vtkPiecewiseFunction* VolumeRendererManager::GetTransferFunction(int volumeid){
487 return getViewData(volumeid)->GetTransferFunction();
489 vtkColorTransferFunction* VolumeRendererManager::GetColorFunction(int volumeid){
491 return getViewData(volumeid)->GetColorFunction();
494 void VolumeRendererManager::changeCompositeMIPFunction(int id, int function) throw (char *){
496 for(unsigned i = 0; i < prop3Dvect.size(); i++)
497 prop3Dvect[i]->changeCompositeMIPFunction(function);
499 getViewData(id)->changeCompositeMIPFunction(function);
504 Changes the interpolation of the volume rendering.
505 type == 0 for linear interpolation
506 type == 1 for nearest interpolation
508 void VolumeRendererManager::changeInterpolationType(int type, int propid){
510 for(unsigned i = 0; i < prop3Dvect.size(); i++)
511 prop3Dvect[i]->changeInterpolationType(type);
513 getViewData(propid)->changeInterpolationType(type);
518 * Set the lookuptable to the volumes in memory
519 * if the id is set then it only changes the lookup table for a specific volume
521 void VolumeRendererManager::SetLookupTable(vtkLookupTable* lookup, int id){
523 for(unsigned i = 0; i < prop3Dvect.size(); i++)
524 prop3Dvect[i]->SetLookupTable(lookup);
526 getViewData(id)->SetLookupTable(lookup);
532 * @returns all the props3D in this manager
534 vector< vtkProp3D* > VolumeRendererManager::getProps3D(){
536 vector< vtkProp3D* > propvects;
537 for(unsigned i = 0; i < prop3Dvect.size(); i++){
538 propvects.push_back(prop3Dvect[i]->getProp3D());
544 * @param std::vector<double> greylevel, the corresponding greylevel in the image
545 * @param std::vector<double> value, the corresponding value for the opacity
546 * @param int propid, the correspoding id, by default it applies the changes to the first volume in the array
548 void VolumeRendererManager::setVolumeOpacity(std::vector<double> greylevel, std::vector<double> value, int propid){
550 for(unsigned i = 0; i < prop3Dvect.size(); i++)
551 prop3Dvect[i]->setVolumeOpacity(greylevel, value);
553 getViewData(propid)->setVolumeOpacity(greylevel, value);
557 void VolumeRendererManager::EnableBoundingBox(vtkRenderWindowInteractor* interactor, int propid){
559 for(unsigned i = 0; i < prop3Dvect.size(); i++)
560 prop3Dvect[i]->EnableBoundingBox(interactor);
562 getViewData(propid)->EnableBoundingBox(interactor);
566 void VolumeRendererManager::DisableBoundingBox(int propid){
569 for(unsigned i = 0; i < prop3Dvect.size(); i++)
570 prop3Dvect[i]->DisableBoundingBox();
572 getViewData(propid)->DisableBoundingBox();