1 #include "volumerenderermanager.h"
3 /*=========================================================================
6 Module: $RCSfile: volumerenderermanager.cxx,v $
8 Date: $Date: 2011/10/05 16:27:04 $
9 Version: $Revision: 1.2 $
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 this->getViewData(propid)->setVolumeOpacity(greylevel, value);
385 void VolumeRendererManager::setVolumeColor(int volid, std::vector<double> greylevel,
386 std::vector<double> red,
387 std::vector<double> green,
388 std::vector<double> blue)throw(char*){
391 this->getViewData(volid)->setVolumeColor(greylevel, red, green, blue);
396 vtkImageData* VolumeRendererManager::getImageData(std::string filename){
397 if(filename.compare("")!= 0){
399 vtkMetaImageReader* reader = vtkMetaImageReader::New();
400 reader->SetFileName(filename.c_str());
402 vtkImageData* img = reader->GetOutput();
404 vtkImageCast* cast = vtkImageCast::New();
406 cast->SetOutputScalarTypeToUnsignedShort();
410 return cast->GetOutput();
416 vtkImageData* VolumeRendererManager::getImageData(){
420 void VolumeRendererManager::checkInvariant() throw(char*){
421 if(this->_renderer==NULL){
422 throw "Renderer not set";
426 VolumeRendererManagerData* VolumeRendererManager::getViewData(int id) throw(char*){
428 for(i = 0; i < (int)(prop3Dvect.size());i++){
429 if(prop3Dvect[i]->getId() == id){
430 return prop3Dvect[i];
433 throw "id not found in the data";
438 void VolumeRendererManager::deleteActor(int propid) throw (char *){
441 this->addRemoveActor(propid, false);
445 for(i = 0; i < (int)(prop3Dvect.size())&&!exit;i++){
446 if(prop3Dvect[i]->getId() == propid){
452 VolumeRendererManagerData* data = prop3Dvect[n];
454 for(j = i; j < (int)(prop3Dvect.size())-1;j++){
455 prop3Dvect[j] = prop3Dvect[j+1];
458 prop3Dvect.pop_back();
460 throw "id not found in the data";
465 vtkPiecewiseFunction* VolumeRendererManager::GetTransferFunction(int volumeid){
466 return getViewData(volumeid)->GetTransferFunction();
468 vtkColorTransferFunction* VolumeRendererManager::GetColorFunction(int volumeid){
470 return getViewData(volumeid)->GetColorFunction();
473 void VolumeRendererManager::changeCompositeMIPFunction(int id, int function) throw (char *){
475 for(unsigned i = 0; i < prop3Dvect.size(); i++)
476 prop3Dvect[i]->changeCompositeMIPFunction(function);
478 getViewData(id)->changeCompositeMIPFunction(function);
483 Changes the interpolation of the volume rendering.
484 type == 0 for linear interpolation
485 type == 1 for nearest interpolation
487 void VolumeRendererManager::changeInterpolationType(int type, int propid){
489 for(unsigned i = 0; i < prop3Dvect.size(); i++)
490 prop3Dvect[i]->changeInterpolationType(type);
492 getViewData(propid)->changeInterpolationType(type);
497 * Set the lookuptable to the volumes in memory
498 * if the id is set then it only changes the lookup table for a specific volume
500 void VolumeRendererManager::SetLookupTable(vtkLookupTable* lookup, int id){
502 for(unsigned i = 0; i < prop3Dvect.size(); i++)
503 prop3Dvect[i]->SetLookupTable(lookup);
505 getViewData(id)->SetLookupTable(lookup);
511 * @returns all the props3D in this manager
513 vector< vtkProp3D* > VolumeRendererManager::getProps3D(){
515 vector< vtkProp3D* > propvects;
516 for(unsigned i = 0; i < prop3Dvect.size(); i++){
517 propvects.push_back(prop3Dvect[i]->getProp3D());
523 * @param std::vector<double> greylevel, the corresponding greylevel in the image
524 * @param std::vector<double> value, the corresponding value for the opacity
525 * @param int propid, the correspoding id, by default it applies the changes to the first volume in the array
527 void VolumeRendererManager::setVolumeOpacity(std::vector<double> greylevel, std::vector<double> value, int propid){
529 for(unsigned i = 0; i < prop3Dvect.size(); i++)
530 prop3Dvect[i]->setVolumeOpacity(greylevel, value);
532 getViewData(propid)->setVolumeOpacity(greylevel, value);
536 void VolumeRendererManager::EnableBoundingBox(vtkRenderWindowInteractor* interactor, int propid){
538 for(unsigned i = 0; i < prop3Dvect.size(); i++)
539 prop3Dvect[i]->EnableBoundingBox(interactor);
541 getViewData(propid)->EnableBoundingBox(interactor);
545 void VolumeRendererManager::DisableBoundingBox(int propid){
548 for(unsigned i = 0; i < prop3Dvect.size(); i++)
549 prop3Dvect[i]->DisableBoundingBox();
551 getViewData(propid)->DisableBoundingBox();