1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    volProt.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "vtkCamera.h"
16 #include "vtkFiniteDifferenceGradientEstimator.h"
17 #include "vtkPiecewiseFunction.h"
18 #include "vtkRenderWindow.h"
19 #include "vtkRenderWindowInteractor.h"
20 #include "vtkRenderer.h"
21 #include "vtkStructuredPoints.h"
22 #include "vtkStructuredPointsReader.h"
23 #include "vtkVolume.h"
24 #include "vtkVolumeProperty.h"
25 #include "vtkVolumeRayCastCompositeFunction.h"
26 #include "vtkVolumeRayCastIsosurfaceFunction.h"
27 #include "vtkVolumeRayCastMIPFunction.h"
28 #include "vtkVolumeRayCastMapper.h"
29 #include "vtkVolumeTextureMapper2D.h"
30 #include "vtkColorTransferFunction.h"
31 
32 #include "vtkTestUtilities.h"
33 #include "vtkRegressionTestImage.h"
34 #include "vtkDebugLeaks.h"
35 
36 // Create an 8x7 grid of render windows in a renderer and render a volume
37 // using various techniques for testing purposes
volProt(int argc,char * argv[])38 int volProt( int argc, char *argv[] )
39 {
40   int i, j, k, l;
41 
42   // Create the renderers, render window, and interactor
43   vtkRenderWindow *renWin = vtkRenderWindow::New();
44   vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
45   iren->SetRenderWindow(renWin);
46   vtkRenderer *ren = vtkRenderer::New();
47   renWin->AddRenderer(ren);
48 
49   // Read the data from a vtk file
50   char* fname = vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/ironProt.vtk");
51   vtkStructuredPointsReader *reader = vtkStructuredPointsReader::New();
52   reader->SetFileName(fname);
53   reader->Update();
54   delete [] fname;
55 
56   // Create a transfer function mapping scalar value to opacity
57   vtkPiecewiseFunction *oTFun = vtkPiecewiseFunction::New();
58   oTFun->AddSegment(10, 0.0, 255, 0.3);
59 
60   vtkPiecewiseFunction *oTFun2 = vtkPiecewiseFunction::New();
61   oTFun2->AddSegment(  0, 0.0, 128, 1.0);
62   oTFun2->AddSegment(128, 1.0, 255, 0.0);
63 
64   // Create a transfer function mapping scalar value to color (grey)
65   vtkPiecewiseFunction *gTFun = vtkPiecewiseFunction::New();
66   gTFun->AddSegment(0, 1.0, 255, 1.0);
67 
68   // Create a transfer function mapping scalar value to color (color)
69   vtkColorTransferFunction *cTFun = vtkColorTransferFunction::New();
70   cTFun->AddRGBPoint(   0, 1.0, 0.0, 0.0 );
71   cTFun->AddRGBPoint(  64, 1.0, 1.0, 0.0 );
72   cTFun->AddRGBPoint( 128, 0.0, 1.0, 0.0 );
73   cTFun->AddRGBPoint( 192, 0.0, 1.0, 1.0 );
74   cTFun->AddRGBPoint( 255, 0.0, 0.0, 1.0 );
75 
76   // Create a transfer function mapping magnitude of gradient to opacity
77   vtkPiecewiseFunction *goTFun = vtkPiecewiseFunction::New();
78   goTFun->AddPoint(   0, 0.0 );
79   goTFun->AddPoint(  30, 0.0 );
80   goTFun->AddPoint(  40, 1.0 );
81   goTFun->AddPoint( 255, 1.0 );
82 
83   // Create a set of properties with varying options
84   vtkVolumeProperty *prop[16];
85   int index = 0;
86   for ( l = 0; l < 2; l++ )
87     {
88     for ( k = 0; k < 2; k++ )
89       {
90       for ( j = 0; j < 2; j++ )
91         {
92         for ( i = 0; i < 2; i++ )
93           {
94           prop[index] = vtkVolumeProperty::New();
95           prop[index]->SetShade(k);
96           prop[index]->SetAmbient(0.3);
97           prop[index]->SetDiffuse(1.0);
98           prop[index]->SetSpecular(0.2);
99           prop[index]->SetSpecularPower(50.0);
100           prop[index]->SetScalarOpacity(oTFun);
101 
102           if ( l )
103             {
104             prop[index]->SetGradientOpacity( goTFun );
105             }
106 
107           if ( j )
108             {
109             prop[index]->SetColor( cTFun );
110             }
111           else
112             {
113             prop[index]->SetColor( gTFun );
114             }
115 
116           if ( i )
117             {
118             prop[index]->SetInterpolationTypeToNearest();
119             }
120           else
121             {
122             prop[index]->SetInterpolationTypeToLinear();
123             }
124 
125           index++;
126           }
127         }
128       }
129     }
130 
131   // Create a set of properties for mip
132   vtkVolumeProperty *mipprop[4];
133   index = 0;
134   for ( j = 0; j < 2; j++ )
135     {
136     for ( i = 0; i < 2; i++ )
137       {
138       mipprop[index] = vtkVolumeProperty::New();
139       mipprop[index]->SetScalarOpacity(oTFun2);
140 
141       if ( j )
142         {
143         mipprop[index]->SetColor( cTFun );
144         }
145       else
146         {
147         mipprop[index]->SetColor( gTFun );
148         }
149 
150       if ( i )
151         {
152         mipprop[index]->SetInterpolationTypeToNearest();
153         }
154       else
155         {
156         mipprop[index]->SetInterpolationTypeToLinear();
157         }
158 
159       index++;
160       }
161     }
162 
163 
164 
165   // Create compositing ray functions
166   vtkVolumeRayCastCompositeFunction *compositeFunction1 =
167     vtkVolumeRayCastCompositeFunction::New();
168   compositeFunction1->SetCompositeMethodToInterpolateFirst();
169 
170   vtkVolumeRayCastCompositeFunction *compositeFunction2 =
171     vtkVolumeRayCastCompositeFunction::New();
172   compositeFunction2->SetCompositeMethodToClassifyFirst();
173 
174 
175   // Create mip ray functions
176   vtkVolumeRayCastMIPFunction *MIPFunction1 =
177     vtkVolumeRayCastMIPFunction::New();
178   MIPFunction1->SetMaximizeMethodToScalarValue();
179 
180   vtkVolumeRayCastMIPFunction *MIPFunction2 =
181     vtkVolumeRayCastMIPFunction::New();
182   MIPFunction2->SetMaximizeMethodToOpacity();
183 
184   // Create an isosurface ray function
185   vtkVolumeRayCastIsosurfaceFunction *isosurfaceFunction =
186     vtkVolumeRayCastIsosurfaceFunction::New();
187   isosurfaceFunction->SetIsoValue(80);
188 
189   vtkFiniteDifferenceGradientEstimator *gradest =
190     vtkFiniteDifferenceGradientEstimator::New();
191 
192   // Create 56 volumes
193   vtkVolume *volume[56];
194   index = 0;
195   for ( j = 0; j < 7; j++ )
196     {
197     for ( i = 0; i < 8; i++ )
198       {
199       volume[index] = vtkVolume::New();
200       volume[index]->AddPosition( i*70, j*70, 0 );
201       ren->AddViewProp(volume[index]);
202       index++;
203       }
204     }
205 
206 
207   // Create 48 ray cast mappers - 32 composite, 8 mip, 8 isosurface
208   vtkVolumeRayCastMapper *raycastMapper[48];
209   for ( i = 0; i < 48; i++ )
210     {
211     raycastMapper[i] = vtkVolumeRayCastMapper::New();
212     raycastMapper[i]->SetInputConnection(reader->GetOutputPort());
213     raycastMapper[i]->SetGradientEstimator(gradest);
214     volume[i]->SetMapper( raycastMapper[i] );
215 
216     if ( i < 16 )
217       {
218       volume[i]->SetProperty( prop[i] );
219       raycastMapper[i]->SetVolumeRayCastFunction( compositeFunction1 );
220       }
221     else if ( i < 32 )
222       {
223       volume[i]->SetProperty( prop[i-16] );
224       raycastMapper[i]->SetVolumeRayCastFunction( compositeFunction2 );
225       }
226     else
227       {
228       if ( i < 36 )
229         {
230         raycastMapper[i]->SetVolumeRayCastFunction( MIPFunction1 );
231         volume[i]->SetProperty( mipprop[i-32] );
232         }
233       else if ( i < 40 )
234         {
235         raycastMapper[i]->SetVolumeRayCastFunction( MIPFunction2 );
236         volume[i]->SetProperty( mipprop[i-36] );
237         }
238       else
239         {
240         raycastMapper[i]->SetVolumeRayCastFunction( isosurfaceFunction );
241         volume[i]->SetProperty( prop[i-40] );
242         }
243       }
244     }
245 
246   // Create 8 texture mappers
247   vtkVolumeTextureMapper2D *textureMapper[8];
248   for ( i = 0; i < 8; i++ )
249     {
250     textureMapper[i] = vtkVolumeTextureMapper2D::New();
251     textureMapper[i]->SetInputConnection( reader->GetOutputPort() );
252     volume[i+48]->SetMapper( textureMapper[i] );
253     volume[i+48]->SetProperty( prop[i*2] );
254     }
255 
256 
257   renWin->SetSize(400,350);
258 
259   ren->ResetCamera();
260   ren->GetActiveCamera()->Zoom(1.5);
261 
262   renWin->Render();
263 
264   int retVal = vtkRegressionTestImageThreshold( renWin, 70 );
265 
266   // Interact with the data at 3 frames per second
267   iren->SetDesiredUpdateRate(3.0);
268   iren->SetStillUpdateRate(0.001);
269 
270   if ( retVal == vtkRegressionTester::DO_INTERACTOR)
271     {
272     iren->Start();
273     }
274 
275   // Clean up
276   reader->Delete();
277   oTFun->Delete();
278   oTFun2->Delete();
279   gTFun->Delete();
280   cTFun->Delete();
281   goTFun->Delete();
282   for ( i = 0; i < 16; i++ )
283     {
284     prop[i]->Delete();
285     }
286   for ( i = 0; i < 4; i++ )
287     {
288     mipprop[i]->Delete();
289     }
290   compositeFunction1->Delete();
291   compositeFunction2->Delete();
292   isosurfaceFunction->Delete();
293   MIPFunction1->Delete();
294   MIPFunction2->Delete();
295   for ( i = 0; i < 56; i++ )
296     {
297     volume[i]->Delete();
298     }
299   gradest->Delete();
300   for ( i = 0; i < 48; i++ )
301     {
302     raycastMapper[i]->Delete();
303     }
304   for ( i = 0; i < 8; i++ )
305     {
306     textureMapper[i]->Delete();
307     }
308   ren->Delete();
309   iren->Delete();
310   renWin->Delete();
311 
312   return !retVal;
313 }
314 
315 
316 
317