/*========================================================================= Program: Visualization Toolkit Module: $RCSfile: volProt.cxx,v $ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkCamera.h" #include "vtkFiniteDifferenceGradientEstimator.h" #include "vtkPiecewiseFunction.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkRenderer.h" #include "vtkStructuredPoints.h" #include "vtkStructuredPointsReader.h" #include "vtkVolume.h" #include "vtkVolumeProperty.h" #include "vtkVolumeRayCastCompositeFunction.h" #include "vtkVolumeRayCastIsosurfaceFunction.h" #include "vtkVolumeRayCastMIPFunction.h" #include "vtkVolumeRayCastMapper.h" #include "vtkVolumeTextureMapper2D.h" #include "vtkColorTransferFunction.h" #include "vtkTestUtilities.h" #include "vtkRegressionTestImage.h" #include "vtkDebugLeaks.h" // Create an 8x7 grid of render windows in a renderer and render a volume // using various techniques for testing purposes int volProt( int argc, char *argv[] ) { int i, j, k, l; // Create the renderers, render window, and interactor vtkRenderWindow *renWin = vtkRenderWindow::New(); vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); iren->SetRenderWindow(renWin); vtkRenderer *ren = vtkRenderer::New(); renWin->AddRenderer(ren); // Read the data from a vtk file char* fname = vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/ironProt.vtk"); vtkStructuredPointsReader *reader = vtkStructuredPointsReader::New(); reader->SetFileName(fname); reader->Update(); delete [] fname; // Create a transfer function mapping scalar value to opacity vtkPiecewiseFunction *oTFun = vtkPiecewiseFunction::New(); oTFun->AddSegment(10, 0.0, 255, 0.3); vtkPiecewiseFunction *oTFun2 = vtkPiecewiseFunction::New(); oTFun2->AddSegment( 0, 0.0, 128, 1.0); oTFun2->AddSegment(128, 1.0, 255, 0.0); // Create a transfer function mapping scalar value to color (grey) vtkPiecewiseFunction *gTFun = vtkPiecewiseFunction::New(); gTFun->AddSegment(0, 1.0, 255, 1.0); // Create a transfer function mapping scalar value to color (color) vtkColorTransferFunction *cTFun = vtkColorTransferFunction::New(); cTFun->AddRGBPoint( 0, 1.0, 0.0, 0.0 ); cTFun->AddRGBPoint( 64, 1.0, 1.0, 0.0 ); cTFun->AddRGBPoint( 128, 0.0, 1.0, 0.0 ); cTFun->AddRGBPoint( 192, 0.0, 1.0, 1.0 ); cTFun->AddRGBPoint( 255, 0.0, 0.0, 1.0 ); // Create a transfer function mapping magnitude of gradient to opacity vtkPiecewiseFunction *goTFun = vtkPiecewiseFunction::New(); goTFun->AddPoint( 0, 0.0 ); goTFun->AddPoint( 30, 0.0 ); goTFun->AddPoint( 40, 1.0 ); goTFun->AddPoint( 255, 1.0 ); // Create a set of properties with varying options vtkVolumeProperty *prop[16]; int index = 0; for ( l = 0; l < 2; l++ ) { for ( k = 0; k < 2; k++ ) { for ( j = 0; j < 2; j++ ) { for ( i = 0; i < 2; i++ ) { prop[index] = vtkVolumeProperty::New(); prop[index]->SetShade(k); prop[index]->SetAmbient(0.3); prop[index]->SetDiffuse(1.0); prop[index]->SetSpecular(0.2); prop[index]->SetSpecularPower(50.0); prop[index]->SetScalarOpacity(oTFun); if ( l ) { prop[index]->SetGradientOpacity( goTFun ); } if ( j ) { prop[index]->SetColor( cTFun ); } else { prop[index]->SetColor( gTFun ); } if ( i ) { prop[index]->SetInterpolationTypeToNearest(); } else { prop[index]->SetInterpolationTypeToLinear(); } index++; } } } } // Create a set of properties for mip vtkVolumeProperty *mipprop[4]; index = 0; for ( j = 0; j < 2; j++ ) { for ( i = 0; i < 2; i++ ) { mipprop[index] = vtkVolumeProperty::New(); mipprop[index]->SetScalarOpacity(oTFun2); if ( j ) { mipprop[index]->SetColor( cTFun ); } else { mipprop[index]->SetColor( gTFun ); } if ( i ) { mipprop[index]->SetInterpolationTypeToNearest(); } else { mipprop[index]->SetInterpolationTypeToLinear(); } index++; } } // Create compositing ray functions vtkVolumeRayCastCompositeFunction *compositeFunction1 = vtkVolumeRayCastCompositeFunction::New(); compositeFunction1->SetCompositeMethodToInterpolateFirst(); vtkVolumeRayCastCompositeFunction *compositeFunction2 = vtkVolumeRayCastCompositeFunction::New(); compositeFunction2->SetCompositeMethodToClassifyFirst(); // Create mip ray functions vtkVolumeRayCastMIPFunction *MIPFunction1 = vtkVolumeRayCastMIPFunction::New(); MIPFunction1->SetMaximizeMethodToScalarValue(); vtkVolumeRayCastMIPFunction *MIPFunction2 = vtkVolumeRayCastMIPFunction::New(); MIPFunction2->SetMaximizeMethodToOpacity(); // Create an isosurface ray function vtkVolumeRayCastIsosurfaceFunction *isosurfaceFunction = vtkVolumeRayCastIsosurfaceFunction::New(); isosurfaceFunction->SetIsoValue(80); vtkFiniteDifferenceGradientEstimator *gradest = vtkFiniteDifferenceGradientEstimator::New(); // Create 56 volumes vtkVolume *volume[56]; index = 0; for ( j = 0; j < 7; j++ ) { for ( i = 0; i < 8; i++ ) { volume[index] = vtkVolume::New(); volume[index]->AddPosition( i*70, j*70, 0 ); ren->AddViewProp(volume[index]); index++; } } // Create 48 ray cast mappers - 32 composite, 8 mip, 8 isosurface vtkVolumeRayCastMapper *raycastMapper[48]; for ( i = 0; i < 48; i++ ) { raycastMapper[i] = vtkVolumeRayCastMapper::New(); raycastMapper[i]->SetInputConnection(reader->GetOutputPort()); raycastMapper[i]->SetGradientEstimator(gradest); volume[i]->SetMapper( raycastMapper[i] ); if ( i < 16 ) { volume[i]->SetProperty( prop[i] ); raycastMapper[i]->SetVolumeRayCastFunction( compositeFunction1 ); } else if ( i < 32 ) { volume[i]->SetProperty( prop[i-16] ); raycastMapper[i]->SetVolumeRayCastFunction( compositeFunction2 ); } else { if ( i < 36 ) { raycastMapper[i]->SetVolumeRayCastFunction( MIPFunction1 ); volume[i]->SetProperty( mipprop[i-32] ); } else if ( i < 40 ) { raycastMapper[i]->SetVolumeRayCastFunction( MIPFunction2 ); volume[i]->SetProperty( mipprop[i-36] ); } else { raycastMapper[i]->SetVolumeRayCastFunction( isosurfaceFunction ); volume[i]->SetProperty( prop[i-40] ); } } } // Create 8 texture mappers vtkVolumeTextureMapper2D *textureMapper[8]; for ( i = 0; i < 8; i++ ) { textureMapper[i] = vtkVolumeTextureMapper2D::New(); textureMapper[i]->SetInputConnection( reader->GetOutputPort() ); volume[i+48]->SetMapper( textureMapper[i] ); volume[i+48]->SetProperty( prop[i*2] ); } renWin->SetSize(400,350); ren->ResetCamera(); ren->GetActiveCamera()->Zoom(1.5); renWin->Render(); int retVal = vtkRegressionTestImageThreshold( renWin, 70 ); // Interact with the data at 3 frames per second iren->SetDesiredUpdateRate(3.0); iren->SetStillUpdateRate(0.001); if ( retVal == vtkRegressionTester::DO_INTERACTOR) { iren->Start(); } // Clean up reader->Delete(); oTFun->Delete(); oTFun2->Delete(); gTFun->Delete(); cTFun->Delete(); goTFun->Delete(); for ( i = 0; i < 16; i++ ) { prop[i]->Delete(); } for ( i = 0; i < 4; i++ ) { mipprop[i]->Delete(); } compositeFunction1->Delete(); compositeFunction2->Delete(); isosurfaceFunction->Delete(); MIPFunction1->Delete(); MIPFunction2->Delete(); for ( i = 0; i < 56; i++ ) { volume[i]->Delete(); } gradest->Delete(); for ( i = 0; i < 48; i++ ) { raycastMapper[i]->Delete(); } for ( i = 0; i < 8; i++ ) { textureMapper[i]->Delete(); } ren->Delete(); iren->Delete(); renWin->Delete(); return !retVal; }