Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "vtkMitkGPUVolumeRayCastMapper.h"
00017
00018
00019 #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) ))
00020
00021
00022 #include "vtkVolumeRenderingFactory.h"
00023 #include "vtkImageData.h"
00024 #include "vtkPointData.h"
00025 #include "vtkCellData.h"
00026 #include "vtkDataArray.h"
00027 #include "vtkTimerLog.h"
00028 #include "vtkImageResample.h"
00029 #include "vtkVolume.h"
00030 #include "vtkVolumeProperty.h"
00031 #include "vtkRenderer.h"
00032 #include "vtkRenderWindow.h"
00033 #include <assert.h>
00034 #include "vtkCommand.h"
00035 #include "vtkCamera.h"
00036 #include "vtkRendererCollection.h"
00037 #include "vtkMultiThreader.h"
00038 #include "vtkGPUInfoList.h"
00039 #include "vtkGPUInfo.h"
00040
00041 vtkCxxRevisionMacro(vtkMitkGPUVolumeRayCastMapper, "$Revision: 1.7 $");
00042 vtkInstantiatorNewMacro(vtkMitkGPUVolumeRayCastMapper);
00043 vtkCxxSetObjectMacro(vtkMitkGPUVolumeRayCastMapper, MaskInput, vtkImageData);
00044 vtkCxxSetObjectMacro(vtkMitkGPUVolumeRayCastMapper, TransformedInput, vtkImageData);
00045
00046 vtkMitkGPUVolumeRayCastMapper::vtkMitkGPUVolumeRayCastMapper()
00047 {
00048 this->AutoAdjustSampleDistances = 1;
00049 this->ImageSampleDistance = 1.0;
00050 this->MinimumImageSampleDistance = 1.0;
00051 this->MaximumImageSampleDistance = 10.0;
00052 this->SampleDistance = 1.0;
00053 this->SmallVolumeRender = 0;
00054 this->BigTimeToDraw = 0.0;
00055 this->SmallTimeToDraw = 0.0;
00056 this->FinalColorWindow = 1.0;
00057 this->FinalColorLevel = 0.5;
00058 this->GeneratingCanonicalView = 0;
00059 this->CanonicalViewImageData = NULL;
00060
00061 this->MaskInput = NULL;
00062 this->MaskBlendFactor=1.0f;
00063
00064 this->AMRMode=0;
00065 this->ClippedCroppingRegionPlanes[0]=VTK_DOUBLE_MAX;
00066 this->ClippedCroppingRegionPlanes[1]=VTK_DOUBLE_MIN;
00067 this->ClippedCroppingRegionPlanes[2]=VTK_DOUBLE_MAX;
00068 this->ClippedCroppingRegionPlanes[3]=VTK_DOUBLE_MIN;
00069 this->ClippedCroppingRegionPlanes[4]=VTK_DOUBLE_MAX;
00070 this->ClippedCroppingRegionPlanes[5]=VTK_DOUBLE_MIN;
00071
00072 this->MaxMemoryInBytes=0;
00073 vtkGPUInfoList *l=vtkGPUInfoList::New();
00074 l->Probe();
00075 if(l->GetNumberOfGPUs()>0)
00076 {
00077 vtkGPUInfo *info=l->GetGPUInfo(0);
00078 this->MaxMemoryInBytes=info->GetDedicatedVideoMemory();
00079 if(this->MaxMemoryInBytes==0)
00080 {
00081 this->MaxMemoryInBytes=info->GetDedicatedSystemMemory();
00082 }
00083
00084 }
00085 l->Delete();
00086
00087 if(this->MaxMemoryInBytes==0)
00088 {
00089 this->MaxMemoryInBytes=128*1024*1024;
00090 }
00091
00092 this->MaxMemoryFraction = 0.75;
00093
00094 this->ReportProgress=true;
00095
00096 this->TransformedInput = NULL;
00097 this->LastInput = NULL;
00098 }
00099
00100
00101 vtkMitkGPUVolumeRayCastMapper::~vtkMitkGPUVolumeRayCastMapper()
00102 {
00103 this->SetMaskInput(NULL);
00104 this->SetTransformedInput(NULL);
00105 this->LastInput = NULL;
00106 }
00107
00108
00109 vtkMitkGPUVolumeRayCastMapper *vtkMitkGPUVolumeRayCastMapper::New()
00110 {
00111
00112 vtkObject* ret =
00113 vtkVolumeRenderingFactory::CreateInstance("vtkMitkGPUVolumeRayCastMapper");
00114 return static_cast<vtkMitkGPUVolumeRayCastMapper*>(ret);
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 void vtkMitkGPUVolumeRayCastMapper::Render( vtkRenderer *ren, vtkVolume *vol )
00129 {
00130
00131
00132 if (this->GeneratingCanonicalView )
00133 {
00134 this->CanonicalViewRender(ren, vol);
00135 return;
00136 }
00137
00138
00139 this->InvokeEvent(vtkCommand::VolumeMapperRenderStartEvent,0);
00140
00141
00142 vtkTimerLog *timer = vtkTimerLog::New();
00143 timer->StartTimer();
00144
00145
00146
00147 if ( this->ValidateRender(ren, vol ) )
00148 {
00149
00150 this->GPURender( ren, vol);
00151 }
00152
00153
00154 timer->StopTimer();
00155 double t = timer->GetElapsedTime();
00156
00157
00158
00159 this->TimeToDraw = t;
00160 timer->Delete();
00161
00162 if ( vol->GetAllocatedRenderTime() < 1.0 )
00163 {
00164 this->SmallTimeToDraw = t;
00165 }
00166 else
00167 {
00168 this->BigTimeToDraw = t;
00169 }
00170
00171
00172 this->InvokeEvent(vtkCommand::VolumeMapperRenderEndEvent,0);
00173 }
00174
00175
00176
00177
00178
00179 void vtkMitkGPUVolumeRayCastMapper::CanonicalViewRender(vtkRenderer *ren,
00180 vtkVolume *vol )
00181 {
00182
00183 if ( this->ValidateRender(ren, vol ) )
00184 {
00185
00186 this->GPURender( ren, vol);
00187 }
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 int vtkMitkGPUVolumeRayCastMapper::ValidateRender(vtkRenderer *ren,
00200 vtkVolume *vol)
00201 {
00202
00203 int goodSoFar = 1;
00204
00205
00206 if ( !ren )
00207 {
00208 goodSoFar = 0;
00209 vtkErrorMacro("Renderer cannot be null.");
00210 }
00211
00212
00213 if ( goodSoFar && !vol )
00214 {
00215 goodSoFar = 0;
00216 vtkErrorMacro("Volume cannot be null.");
00217 }
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 if ( goodSoFar && vol->GetProperty()->GetColorChannels() != 3 )
00232 {
00233
00234
00235 }
00236
00237
00238
00239
00240
00241
00242 if( goodSoFar && this->Cropping &&
00243 (this->CroppingRegionPlanes[0]>=this->CroppingRegionPlanes[1] ||
00244 this->CroppingRegionPlanes[2]>=this->CroppingRegionPlanes[3] ||
00245 this->CroppingRegionPlanes[4]>=this->CroppingRegionPlanes[5] ))
00246 {
00247
00248 goodSoFar = 0;
00249 }
00250
00251
00252 vtkImageData *input=this->GetInput();
00253
00254
00255 if(input != this->LastInput ||
00256 input->GetMTime() > this->TransformedInput->GetMTime())
00257 {
00258 this->LastInput = input;
00259
00260 vtkImageData* clone;
00261 if(!this->TransformedInput)
00262 {
00263 clone = vtkImageData::New();
00264 this->SetTransformedInput(clone);
00265 clone->Delete();
00266 }
00267 else
00268 {
00269 clone = this->TransformedInput;
00270 }
00271
00272 clone->ShallowCopy(input);
00273
00274
00275
00276
00277
00278
00279
00280 int extents[6], real_extents[6];
00281 clone->GetExtent(extents);
00282 clone->GetExtent(real_extents);
00283
00284
00285 double origin[3], spacing[3];
00286 clone->GetOrigin(origin);
00287 clone->GetSpacing(spacing);
00288
00289 for (int cc=0; cc < 3; cc++)
00290 {
00291
00292 origin[cc] = origin[cc] + extents[2*cc]*spacing[cc];
00293 extents[2*cc+1] -= extents[2*cc];
00294 extents[2*cc] -= extents[2*cc];
00295 }
00296
00297 clone->SetOrigin(origin);
00298 clone->SetExtent(extents);
00299 }
00300
00301
00302 if ( goodSoFar && !this->TransformedInput )
00303 {
00304 vtkErrorMacro("Input is NULL but is required");
00305 goodSoFar = 0;
00306 }
00307
00308
00309
00310
00311 vtkDataArray *scalars = NULL;
00312 if ( goodSoFar )
00313 {
00314
00315 this->TransformedInput->UpdateInformation();
00316 this->TransformedInput->SetUpdateExtentToWholeExtent();
00317 this->TransformedInput->Update();
00318
00319
00320 scalars=this->GetScalars(this->TransformedInput,this->ScalarMode,
00321 this->ArrayAccessMode,
00322 this->ArrayId,
00323 this->ArrayName,
00324 this->CellFlag);
00325
00326
00327 if ( !scalars )
00328 {
00329 vtkErrorMacro("No scalars found on input.");
00330 goodSoFar = 0;
00331 }
00332
00333 else if ( this->CellFlag == 2 )
00334 {
00335 vtkErrorMacro("Only point or cell scalar support - found field scalars instead.");
00336 goodSoFar = 0;
00337 }
00338 }
00339
00340
00341
00342 if ( goodSoFar )
00343 {
00344 switch(scalars->GetDataType())
00345 {
00346 case VTK_CHAR:
00347 vtkErrorMacro(<< "scalar of type VTK_CHAR is not supported "
00348 << "because this type is platform dependent. "
00349 << "Use VTK_SIGNED_CHAR or VTK_UNSIGNED_CHAR instead.");
00350 goodSoFar = 0;
00351 break;
00352 case VTK_BIT:
00353 vtkErrorMacro("scalar of type VTK_BIT is not supported by this mapper.");
00354 goodSoFar = 0;
00355 break;
00356 case VTK_ID_TYPE:
00357 vtkErrorMacro("scalar of type VTK_ID_TYPE is not supported by this mapper.");
00358 goodSoFar = 0;
00359 break;
00360 case VTK_STRING:
00361 vtkErrorMacro("scalar of type VTK_STRING is not supported by this mapper.");
00362 goodSoFar = 0;
00363 break;
00364 default:
00365
00366 break;
00367 }
00368 }
00369
00370
00371 if ( goodSoFar )
00372 {
00373 if(this->BlendMode!=vtkVolumeMapper::COMPOSITE_BLEND &&
00374 this->BlendMode!=vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND &&
00375 this->BlendMode!=vtkVolumeMapper::MINIMUM_INTENSITY_BLEND)
00376 {
00377 goodSoFar = 0;
00378 vtkErrorMacro(<< "Selected blend mode not supported. "
00379 << "Only Composite and MIP and MinIP modes "
00380 << "are supported by the current implementation.");
00381 }
00382 }
00383
00384
00385
00386 int numberOfComponents = 0;
00387 if ( goodSoFar )
00388 {
00389 numberOfComponents=scalars->GetNumberOfComponents();
00390 if( !( numberOfComponents==1 ||
00391 (numberOfComponents==4 &&
00392 vol->GetProperty()->GetIndependentComponents()==0)))
00393 {
00394 goodSoFar = 0;
00395 vtkErrorMacro(<< "Only one component scalars, or four "
00396 << "component with non-independent components, "
00397 << "are supported by this mapper.");
00398 }
00399 }
00400
00401
00402 if( goodSoFar &&
00403 numberOfComponents == 4 &&
00404 scalars->GetDataType() != VTK_UNSIGNED_CHAR)
00405 {
00406 goodSoFar = 0;
00407 vtkErrorMacro("Only unsigned char is supported for 4-component scalars!");
00408 }
00409
00410
00411 return goodSoFar;
00412 }
00413
00414
00415
00416
00417
00418
00419
00420 void vtkMitkGPUVolumeRayCastMapper::SetCellFlag(int cellFlag)
00421 {
00422 this->CellFlag=cellFlag;
00423 }
00424
00425
00426 void vtkMitkGPUVolumeRayCastMapper::CreateCanonicalView(
00427 vtkRenderer *ren,
00428 vtkVolume *volume,
00429 vtkImageData *image,
00430 int vtkNotUsed(blend_mode),
00431 double viewDirection[3],
00432 double viewUp[3])
00433 {
00434 this->GeneratingCanonicalView = 1;
00435 int oldSwap = ren->GetRenderWindow()->GetSwapBuffers();
00436 ren->GetRenderWindow()->SwapBuffersOff();
00437
00438
00439 int dim[3];
00440 image->GetDimensions(dim);
00441 int *size = ren->GetRenderWindow()->GetSize();
00442
00443 vtkImageData *bigImage = vtkImageData::New();
00444 bigImage->SetDimensions(size[0], size[1], 1);
00445 bigImage->SetScalarTypeToUnsignedChar();
00446 bigImage->SetNumberOfScalarComponents(3);
00447 bigImage->AllocateScalars();
00448
00449 this->CanonicalViewImageData = bigImage;
00450
00451
00452 double scale[2];
00453 scale[0] = dim[0] / static_cast<double>(size[0]);
00454 scale[1] = dim[1] / static_cast<double>(size[1]);
00455
00456
00457
00458
00459 vtkRendererCollection *renderers=ren->GetRenderWindow()->GetRenderers();
00460 int numberOfRenderers=renderers->GetNumberOfItems();
00461
00462 bool *rendererVisibilities=new bool[numberOfRenderers];
00463 renderers->InitTraversal();
00464 int i=0;
00465 while(i<numberOfRenderers)
00466 {
00467 vtkRenderer *r=renderers->GetNextItem();
00468 rendererVisibilities[i]=r->GetDraw()==1;
00469 if(r!=ren)
00470 {
00471 r->SetDraw(false);
00472 }
00473 ++i;
00474 }
00475
00476
00477
00478
00479 vtkPropCollection *props=ren->GetViewProps();
00480 int numberOfProps=props->GetNumberOfItems();
00481
00482 bool *propVisibilities=new bool[numberOfProps];
00483 props->InitTraversal();
00484 i=0;
00485 while(i<numberOfProps)
00486 {
00487 vtkProp *p=props->GetNextProp();
00488 propVisibilities[i]=p->GetVisibility()==1;
00489 if(p!=volume)
00490 {
00491 p->SetVisibility(false);
00492 }
00493 ++i;
00494 }
00495
00496 vtkCamera *savedCamera=ren->GetActiveCamera();
00497 savedCamera->Modified();
00498 vtkCamera *canonicalViewCamera=vtkCamera::New();
00499
00500
00501 double *center=volume->GetCenter();
00502 double bounds[6];
00503 volume->GetBounds(bounds);
00504 double d=sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
00505 (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
00506 (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
00507
00508
00509 d=bounds[1]-bounds[0];
00510
00511
00512 canonicalViewCamera->SetFocalPoint(center);
00513 canonicalViewCamera->ParallelProjectionOn();
00514 canonicalViewCamera->SetPosition(center[0] - d*viewDirection[0],
00515 center[1] - d*viewDirection[1],
00516 center[2] - d*viewDirection[2]);
00517 canonicalViewCamera->SetViewUp(viewUp);
00518 canonicalViewCamera->SetParallelScale(d/2);
00519
00520 ren->SetActiveCamera(canonicalViewCamera);
00521 ren->GetRenderWindow()->Render();
00522
00523
00524 ren->SetActiveCamera(savedCamera);
00525 canonicalViewCamera->Delete();
00526
00527
00528
00529 vtkImageResample *resample = vtkImageResample::New();
00530 resample->SetInput( bigImage );
00531 resample->SetAxisMagnificationFactor(0,scale[0]);
00532 resample->SetAxisMagnificationFactor(1,scale[1]);
00533 resample->SetAxisMagnificationFactor(2,1);
00534 resample->UpdateWholeExtent();
00535
00536
00537 image->DeepCopy(resample->GetOutput());
00538
00539 bigImage->Delete();
00540 resample->Delete();
00541
00542
00543 props->InitTraversal();
00544 i=0;
00545 while(i<numberOfProps)
00546 {
00547 vtkProp *p=props->GetNextProp();
00548 p->SetVisibility(propVisibilities[i]);
00549 ++i;
00550 }
00551
00552 delete[] propVisibilities;
00553
00554
00555 renderers->InitTraversal();
00556 i=0;
00557 while(i<numberOfRenderers)
00558 {
00559 vtkRenderer *r=renderers->GetNextItem();
00560 r->SetDraw(rendererVisibilities[i]);
00561 ++i;
00562 }
00563
00564 delete[] rendererVisibilities;
00565
00566 ren->GetRenderWindow()->SetSwapBuffers(oldSwap);
00567 this->CanonicalViewImageData = NULL;
00568 this->GeneratingCanonicalView = 0;
00569 }
00570
00571
00572
00573 void vtkMitkGPUVolumeRayCastMapper::PrintSelf(ostream& os, vtkIndent indent)
00574 {
00575 this->Superclass::PrintSelf(os,indent);
00576
00577 os << indent << "AutoAdjustSampleDistances: "
00578 << this->AutoAdjustSampleDistances << endl;
00579 os << indent << "MinimumImageSampleDistance: "
00580 << this->MinimumImageSampleDistance << endl;
00581 os << indent << "MaximumImageSampleDistance: "
00582 << this->MaximumImageSampleDistance << endl;
00583 os << indent << "ImageSampleDistance: " << this->ImageSampleDistance << endl;
00584 os << indent << "SampleDistance: " << this->SampleDistance << endl;
00585 os << indent << "FinalColorWindow: " << this->FinalColorWindow << endl;
00586 os << indent << "FinalColorLevel: " << this->FinalColorLevel << endl;
00587 os << indent << "MaskInput: " << this->MaskInput << endl;
00588 os << indent << "MaskBlendFactor: " << this->MaskBlendFactor << endl;
00589 os << indent << "MaxMemoryInBytes: " << this->MaxMemoryInBytes << endl;
00590 os << indent << "MaxMemoryFraction: " << this->MaxMemoryFraction << endl;
00591 os << indent << "ReportProgress: " << this->ReportProgress << endl;
00592 }
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606 void vtkMitkGPUVolumeRayCastMapper::ClipCroppingRegionPlanes()
00607 {
00608 assert("pre: volume_exists" && this->GetInput()!=0);
00609 assert("pre: valid_cropping" && this->Cropping &&
00610 this->CroppingRegionPlanes[0]<this->CroppingRegionPlanes[1] &&
00611 this->CroppingRegionPlanes[2]<this->CroppingRegionPlanes[3] &&
00612 this->CroppingRegionPlanes[4]<this->CroppingRegionPlanes[5]);
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623 double volBounds[6];
00624 this->GetInput()->GetBounds(volBounds);
00625
00626 int i=0;
00627 while(i<6)
00628 {
00629
00630 if(this->CroppingRegionPlanes[i]<volBounds[i])
00631 {
00632 this->ClippedCroppingRegionPlanes[i]=volBounds[i];
00633 }
00634 else
00635 {
00636 this->ClippedCroppingRegionPlanes[i]=this->CroppingRegionPlanes[i];
00637 }
00638 ++i;
00639
00640 if(this->CroppingRegionPlanes[i]>volBounds[i])
00641 {
00642 this->ClippedCroppingRegionPlanes[i]=volBounds[i];
00643 }
00644 else
00645 {
00646 this->ClippedCroppingRegionPlanes[i]=this->CroppingRegionPlanes[i];
00647 }
00648 ++i;
00649 }
00650 }
00651
00652 #endif