]> Creatis software - creaMaracasVisu.git/blob - lib/Kernel/VTKObjects/VolumeRenderer/volumerenderermanager.cxx
no message
[creaMaracasVisu.git] / lib / Kernel / VTKObjects / VolumeRenderer / volumerenderermanager.cxx
1 #include "volumerenderermanager.h"
2
3 /*=========================================================================
4
5   Program:   wxMaracas
6   Module:    $RCSfile: volumerenderermanager.cxx,v $
7   Language:  C++
8   Date:      $Date: 2011/10/19 16:08:29 $
9   Version:   $Revision: 1.3 $
10
11   Copyright: (c) 2002, 2003
12   License:
13
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.
17
18 =========================================================================*/
19
20 #include <vtkMetaImageReader.h>
21 #include <vtkImageCast.h>
22
23 #include "vtkImageLuminance.h"
24 #include "vtkImageAppendComponents.h"
25 #include "vtkSmartPointer.h"
26
27 #include <map>
28
29 using namespace std;
30
31 /**
32 **      Start of the manager class
33 **/
34 VolumeRendererManager::VolumeRendererManager(){
35         _renderer = NULL;
36         _idCount=0;
37 }
38 VolumeRendererManager::~VolumeRendererManager(){
39     _renderer = 0;
40     _idCount=0;
41     image = 0;
42     for(unsigned i = 0; i < prop3Dvect.size();i++){
43         prop3Dvect[i]->Delete();
44     }
45     prop3Dvect.clear();
46 }
47
48 /**
49 **      Sets the renderer to manage the prop3D from the view
50 **/
51 void VolumeRendererManager::setRenderer(vtkRenderer*  renderer){
52         _renderer = renderer;
53 }
54
55 /**
56 ** Gets the renderer which manage the prop3D from the view
57 **/
58 vtkRenderer* VolumeRendererManager::getRenderer(){
59         return _renderer;
60 }
61
62 /**
63 ** Updates Volume
64 **/
65 void VolumeRendererManager::Update(int ppid){
66         VolumeRendererManagerData* data = this->getViewData(ppid);
67         data->Update();
68         _renderer->Render();
69 }
70
71 /**
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.
80 */
81 int VolumeRendererManager::addVolume(vtkImageData* img, vtkRenderWindowInteractor* interactor, bool independentcomponents){
82     if(img->GetNumberOfScalarComponents() > 1 && !independentcomponents){
83
84
85         image = img;
86
87
88         vtkSmartPointer< vtkImageLuminance > luminance = vtkSmartPointer< vtkImageLuminance >::New();
89         luminance->SetInput(img);
90         luminance->Update();
91
92         vtkSmartPointer< vtkImageAppendComponents > append = vtkSmartPointer< vtkImageAppendComponents >::New();
93         append->SetInput(0, img);
94         append->SetInput(1, luminance->GetOutput());
95         append->Update();
96
97
98
99         VolumeRendererManagerData* data = new VolumeRendererManagerData(append->GetOutput(), true);
100         data->SetIndependentComponents(independentcomponents);
101
102
103         prop3Dvect.push_back(data);
104
105         data->setId(_idCount);
106         _idCount++;
107
108         return _idCount-1;
109
110
111         /*image = img;
112
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], "");
118
119             vtkColorTransferFunction* colorf = data->GetColorFunction();
120             colorf->RemoveAllPoints();
121             double r = 0, g = 0, b = 0;
122             for(unsigned j = 0; j < 255; j++){
123
124                 if(i == 0){
125                     r = j/255.0;
126                     g = 0;
127                     b = 0;
128                 }else if(i == 1){
129                     r = 0;
130                     g = j/255.0;
131                     b = 0;
132                 }else if(i == 2){
133                     r = 0;
134                     g = 0;
135                     b = j/255.0;
136                 }
137
138                 colorf->AddRGBPoint(j, r, g, b);
139             }
140
141             prop3Dvect.push_back(data);
142
143             data->setId(_idCount);
144             _idCount++;
145
146             if(!boxw){
147                 EnableBoundingBox(interactor, data->getId());
148                 DisableBoundingBox(data->getId());
149                 boxw = data->GetBoxWidget();
150             }else{
151                 data->SetBoxWidget(boxw);
152             }
153         }
154
155         boxw->RemoveAllObservers();
156
157         vtkBoxWidgetCallback *callback = vtkBoxWidgetCallback::New();
158
159         for(unsigned i = 0; i < prop3Dvect.size(); i++){
160             VolumeRendererManagerData* data = prop3Dvect[i];
161             callback->AddMapper(data->GetVolumeMapper());
162         }
163
164         boxw->AddObserver(vtkCommand::InteractionEvent, callback);
165         callback->Delete();
166
167         return _idCount-1;*/
168
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);
178
179         VolumeRendererManagerData* data = new VolumeRendererManagerData(imgshort, "");
180
181         vtkColorTransferFunction* colorf = data->GetColorFunction();
182         colorf->RemoveAllPoints();
183
184         map< unsigned short, vector< double > > colormap;
185
186         int *extent = img->GetExtent();
187
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++){
191
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;
195
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]);
200
201                     colormap[val] = rgb;
202                 }
203             }
204         }
205
206
207
208         map< unsigned short, vector< double > >::iterator it;
209         for(it = colormap.begin(); it != colormap.end(); ++it){
210
211             colorf->AddRGBPoint((*it).first, (*it).second[0] / 255.0, (*it).second[1] / 255.0, (*it).second[2] / 255.0);
212         }
213
214         prop3Dvect.push_back(data);
215
216         data->setId(_idCount);
217         EnableBoundingBox(interactor, data->getId());
218         DisableBoundingBox(data->getId());
219         _idCount++;*/
220
221
222     }else{
223         image = img;
224
225         VolumeRendererManagerData* data = new VolumeRendererManagerData(img, "");
226         prop3Dvect.push_back(data);
227
228
229         data->setId(_idCount);
230         _idCount++;
231
232         EnableBoundingBox(interactor, data->getId());
233         DisableBoundingBox(data->getId());
234
235
236
237         return data->getId();
238
239     }
240 }
241
242 /**
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
247   */
248 void VolumeRendererManager::GetImageDouble(vtkImageData* img, vtkImageData* imgushort){
249
250
251     int *extent = img->GetExtent();
252
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));
258
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;
262
263                 }
264             }
265         }
266     }
267 }
268
269 /**
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
274   */
275 void VolumeRendererManager::GetImages(vtkImageData* img, vector<vtkImageData* >& vectimg){
276
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();
285     }
286
287     int *extent = img->GetExtent();
288
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));
294
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];
298                     }
299                 }else if(img->GetScalarType() == VTK_CHAR){
300                     char *imgpoint = ((char*)img->GetScalarPointer(i, j, k));
301
302                    for(unsigned l = 0; l < vectimg.size(); l++){
303                         char *vectimgpoint = ( char*)vectimg[l]->GetScalarPointer(i, j, k);
304                        *vectimgpoint = imgpoint[l];
305                    }
306                }else if(img->GetScalarType() == VTK_UNSIGNED_SHORT){
307                     unsigned short *imgpoint = ((unsigned short*)img->GetScalarPointer(i, j, k));
308
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];
312                     }
313                 }else if(img->GetScalarType() == VTK_SHORT){
314                      short *imgpoint = ((short*)img->GetScalarPointer(i, j, k));
315
316                     for(unsigned l = 0; l < vectimg.size(); l++){
317                          short *vectimgpoint = ( short*)vectimg[l]->GetScalarPointer(i, j, k);
318                         *vectimgpoint = imgpoint[l];
319                     }
320                 }
321             }
322         }
323     }
324 }
325
326 /**
327 **      Adds a prop3D to the manager and returns the identifier
328 **/
329 int VolumeRendererManager::addVolume(int idTP, vtkImageData* vol, std::string dataname) throw(char*){
330         checkInvariant();
331         image = vol;
332         if(vol != NULL){
333                 VolumeRendererManagerData* data = new VolumeRendererManagerData(vol, dataname);
334                 prop3Dvect.push_back(data);
335                 _renderer->AddActor(data->getProp3D());
336                 if(idTP == -1)
337                 {
338                         data->setId(_idCount);
339                         _idCount++;
340                 }
341                 else
342                 {
343                         data->setId(idTP);
344                 }
345                 printf("VolumeRendererManager::addVolume->idVolumeRenderer: %i\n", data->getId());
346                 return data->getId();
347         }else{
348                 throw "Check mhd imagefile file or input";
349         }
350         return -1;
351 }
352 /**
353 **      adds or removes an actor depending of the bool value
354 **/
355
356 void VolumeRendererManager::addRemoveActor(int propid, bool addremove)  throw(char*){
357         checkInvariant();
358
359         VolumeRendererManagerData* data = this->getViewData(propid);
360         if(data->getProp3D()!=NULL){
361                 if(addremove){
362                         _renderer->AddViewProp(data->getProp3D());
363                 }else{
364                         _renderer->RemoveViewProp(data->getProp3D());
365                 }
366                 _renderer->Render();
367         }
368
369 }
370 /**
371 **      Changes the opacity in a prop3D
372 **/
373 void VolumeRendererManager::setVolumeOpacity(int propid, std::vector<double> greylevel,std::vector<double> value)  throw(char*){
374         checkInvariant();
375
376         printf("EED VolumeRendererManager::setVolumeOpacity %d\n",propid);
377         
378         VolumeRendererManagerData* volrenman = this->getViewData(propid);
379         if (volrenman!=NULL) 
380         {
381         volrenman->setVolumeOpacity(greylevel, value);
382         } else {
383                 printf("EED  VolumeRendererManager::setVolumeOpacity  Warning volrenman NULL\n");
384         }
385         
386         _renderer->Render();
387
388 }
389
390 /**
391 **      Set Volume Color
392 **/
393
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");
399         checkInvariant();
400
401         printf("EED VolumeRendererManager::setVolumeColor %d\n",volid);
402         
403         VolumeRendererManagerData* volrenman = this->getViewData(volid);
404         if (volrenman!=NULL) 
405         {
406                 this->getViewData(volid)->setVolumeColor(greylevel, red, green, blue);
407         } else {
408                 printf("EED  VolumeRendererManager::setVolumeColor  Warning volrenman NULL\n");
409         }
410
411         _renderer->Render();
412         printf("EED VolumeRendererManager::setVolumeColor  end \n");
413 }
414
415 vtkImageData* VolumeRendererManager::getImageData(std::string filename){
416         if(filename.compare("")!= 0){
417
418                 vtkMetaImageReader* reader =  vtkMetaImageReader::New();
419                 reader->SetFileName(filename.c_str());
420                 reader->Update();
421                 vtkImageData* img = reader->GetOutput();
422
423                 vtkImageCast* cast = vtkImageCast::New();
424                 cast->SetInput(img);
425                 cast->SetOutputScalarTypeToUnsignedShort();
426                 cast->Update();
427                 //reader->Delete();
428                 //img->Delete();
429                 return cast->GetOutput();
430                 //return img;
431         }
432         return NULL;
433 }
434
435 vtkImageData* VolumeRendererManager::getImageData(){
436         return image;
437 }
438
439 void VolumeRendererManager::checkInvariant()  throw(char*){
440         printf("EED VolumeRendererManager::checkInvariant start\n");
441         if(this->_renderer==NULL){
442                 throw "Renderer not set";
443         }
444         printf("EED VolumeRendererManager::checkInvariant end \n");
445 }
446
447 VolumeRendererManagerData* VolumeRendererManager::getViewData(int id) throw(char*){
448     int i;
449         for(i = 0; i < (int)(prop3Dvect.size());i++){
450                 if(prop3Dvect[i]->getId() == id){
451                         return prop3Dvect[i];
452                 }
453         }
454         throw "id not found in the data";
455
456         return NULL;
457 }
458
459 void VolumeRendererManager::deleteActor(int propid) throw (char *){
460         checkInvariant();
461
462         this->addRemoveActor(propid, false);
463
464         int i,n;
465         bool exit = false;
466         for(i = 0; i < (int)(prop3Dvect.size())&&!exit;i++){
467                 if(prop3Dvect[i]->getId() == propid){
468                         n=i;
469                         exit = true;
470                 }
471         }
472         if(exit){
473                 VolumeRendererManagerData* data = prop3Dvect[n];
474                 int j;
475                 for(j = i; j < (int)(prop3Dvect.size())-1;j++){
476                         prop3Dvect[j] = prop3Dvect[j+1];
477                 }
478                 delete data;
479                 prop3Dvect.pop_back();
480         }else{
481                 throw "id not found in the data";
482         }
483
484 }
485
486 vtkPiecewiseFunction* VolumeRendererManager::GetTransferFunction(int volumeid){
487         return getViewData(volumeid)->GetTransferFunction();
488 }
489 vtkColorTransferFunction* VolumeRendererManager::GetColorFunction(int volumeid){
490
491         return getViewData(volumeid)->GetColorFunction();
492 }
493
494 void VolumeRendererManager::changeCompositeMIPFunction(int id, int function) throw (char *){
495     if(id == -1){
496         for(unsigned i = 0; i < prop3Dvect.size(); i++)
497             prop3Dvect[i]->changeCompositeMIPFunction(function);
498     }else{
499         getViewData(id)->changeCompositeMIPFunction(function);
500     }
501 }
502
503 /**
504   Changes the interpolation of the volume rendering.
505   type == 0 for linear interpolation
506   type == 1 for nearest interpolation
507   */
508 void VolumeRendererManager::changeInterpolationType(int type, int propid){
509     if(propid == -1){
510         for(unsigned i = 0; i < prop3Dvect.size(); i++)
511             prop3Dvect[i]->changeInterpolationType(type);
512     }else{
513         getViewData(propid)->changeInterpolationType(type);
514     }
515 }
516
517 /**
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
520  */
521 void VolumeRendererManager::SetLookupTable(vtkLookupTable* lookup, int id){
522     if(id == -1){
523         for(unsigned i = 0; i < prop3Dvect.size(); i++)
524             prop3Dvect[i]->SetLookupTable(lookup);
525     }else{
526         getViewData(id)->SetLookupTable(lookup);
527     }
528
529 }
530
531 /**
532   * @returns all the props3D in this manager
533 */
534 vector< vtkProp3D* > VolumeRendererManager::getProps3D(){
535
536     vector< vtkProp3D* >  propvects;
537     for(unsigned i = 0; i < prop3Dvect.size(); i++){
538         propvects.push_back(prop3Dvect[i]->getProp3D());
539     }
540     return propvects;
541 }
542
543 /**
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
547   */
548 void VolumeRendererManager::setVolumeOpacity(std::vector<double> greylevel, std::vector<double> value, int propid){
549     if(propid == -1){
550         for(unsigned i = 0; i < prop3Dvect.size(); i++)
551             prop3Dvect[i]->setVolumeOpacity(greylevel, value);
552     }else{
553         getViewData(propid)->setVolumeOpacity(greylevel, value);
554     }
555 }
556
557 void VolumeRendererManager::EnableBoundingBox(vtkRenderWindowInteractor* interactor, int propid){
558     if(propid == -1){
559         for(unsigned i = 0; i < prop3Dvect.size(); i++)
560             prop3Dvect[i]->EnableBoundingBox(interactor);
561     }else{
562         getViewData(propid)->EnableBoundingBox(interactor);
563     }
564 }
565
566 void VolumeRendererManager::DisableBoundingBox(int propid){
567
568     if(propid == -1){
569         for(unsigned i = 0; i < prop3Dvect.size(); i++)
570             prop3Dvect[i]->DisableBoundingBox();
571     }else{
572         getViewData(propid)->DisableBoundingBox();
573     }
574 }