1 /*=========================================================================
2
3 Copyright (c) Kitware Inc.
4 All rights reserved.
5
6 =========================================================================*/
7 // .SECTION Description
8 // This program illustrates the use of various filters acting upon hyper
9 // tree grid data sets. It generates output files in VTK format.
10 //
11 // .SECTION Usage
12 // --branch-factor opt Branching factor of hyper tree grid
13 // --dimension opt Dimension of hyper tree grid
14 // --grid-size-X opt Size of hyper tree grid in X direction
15 // --grid-size-Y opt Size of hyper tree grid in Y direction
16 // --grid-size-Z opt Size of hyper tree grid in Z direction
17 // --descriptor String of characters specifying tree structure
18 // --max-level opt Maximum depth of hyper tree grid
19 // --contours Number of iso-contours to be calculated
20 // --skip-Axis-Cut Skip axis cut filter
21 // --skip-Contour Skip contour filter
22 // --skip-Cut Skip cut filter
23 // --skip-Geometry Skip geometry filter
24 // --skip-Shrink Skip shrink filter
25 //
26 // .SECTION Thanks
27 // This example was written by Philippe Pebay and Charles Law, Kitware 2012
28 // This work was supported in part by Commissariat a l'Energie Atomique (CEA/DIF)
29
30 #include "vtkHyperTreeGrid.h"
31 #include "vtkHyperTreeGridAxisCut.h"
32 #include "vtkHyperTreeGridSource.h"
33 #include "vtkHyperTreeGridGeometry.h"
34
35 #include "vtkContourFilter.h"
36 #include "vtkCutter.h"
37 #include "vtkDataSetWriter.h"
38 #include "vtkMath.h"
39 #include "vtkNew.h"
40 #include "vtkPlane.h"
41 #include "vtkPointData.h"
42 #include "vtkPolyDataWriter.h"
43 #include "vtkShrinkFilter.h"
44 #include "vtkStdString.h"
45 #include "vtkTimerLog.h"
46 #include "vtkUnstructuredGrid.h"
47 #include "vtkUnstructuredGridWriter.h"
48
49 #include "vtksys/CommandLineArguments.hxx"
50
51 #include <vtksys/ios/sstream>
52
SetInputParameters(int & dim,int & branch,int & nX,int & nY,int & nZ,int max,vtkStdString & str)53 void SetInputParameters( int& dim,
54 int& branch,
55 int& nX,
56 int& nY,
57 int& nZ,
58 int max,
59 vtkStdString& str )
60 {
61 // Ensure that parsed dimensionality makes sense
62 if ( dim > 3 )
63 {
64 dim = 3;
65 }
66 else if ( dim < 1 )
67 {
68 dim = 1;
69 }
70
71 // Ensure that parsed branch factor makes sense
72 if ( branch > 3 )
73 {
74 branch = 3;
75 }
76 else if ( branch < 2 )
77 {
78 branch = 2;
79 }
80
81 // Ensure that parsed grid sizes make sense
82 if ( nX < 1 )
83 {
84 nX = 1;
85 }
86 if ( nY < 1 )
87 {
88 nY = 1;
89 }
90 if ( nZ < 1 )
91 {
92 nZ = 1;
93 }
94
95 // Ensure that parsed grid sizes are consistent with dimensionality
96 if ( dim < 3 )
97 {
98 nZ = 1;
99 if ( dim < 2 )
100 {
101 nY = 1;
102 }
103 }
104
105 // Ensure that maximum level makes sense
106 if ( max < 1 )
107 {
108 max = 1;
109 }
110
111 // Generate a descriptor if none was provided
112 if ( str = "" )
113 {
114 // Calculate refined block size
115 int blockSize = branch;
116 for ( int i = 1; i < dim; ++ i )
117 {
118 blockSize *= branch;
119 }
120
121 // Initialize character stream
122 vtksys_ios::ostringstream stream;
123
124 // Seed random number generator
125 vtkMath::RandomSeed( static_cast<int>( vtkTimerLog::GetUniversalTime() ) );
126
127 // Initialize per-level cardinality
128 int cardLevel = nX * nY * nZ;
129
130 // Iterate over refinement levels
131 for ( int l = 0; l < max - 1; ++ l )
132 {
133 // Initialize counters for this level
134 int nRefined = 0;
135 int nLeaves = 0;
136
137 // Insert separator if not first level
138 if ( l )
139 {
140 stream << '|';
141 }
142
143 // Iterate over entries in this level
144 for ( int i = 0; i < cardLevel; ++ i )
145 {
146 // Generate next character based on pseudo-random clause
147 double u = vtkMath::Random();
148 if ( u < .3 )
149 {
150 // Refined cell
151 stream << 'R';
152 ++ nRefined;
153 } // if ( u < .1 )
154 else
155 {
156 // Leaf cell
157 stream << '.';
158 ++ nLeaves;
159 } // else
160 } // i
161
162 // Update cardinality for next level
163 cardLevel = nRefined * blockSize;
164 } // l
165
166 // Last level contains only leaf cells
167 if ( max > 1 )
168 {
169 // Insert separator if not first level
170 stream << '|';
171 }
172 // Iterate over entries in this level
173 for ( int i = 0; i < cardLevel; ++ i )
174 {
175 stream << '.';
176 }
177
178 // Finally dump stream into descriptor
179 str = stream.str();
180
181 } // if ( str = "" )
182 }
183
main(int argc,char * argv[])184 int main( int argc, char* argv[] )
185 {
186 // Set default argument values and options
187 vtkStdString descriptor = "";
188 int dim = 3;
189 int branch = 3;
190 int max = 3;
191 int nX = 2;
192 int nY = 3;
193 int nZ = 2;
194 double sX = 1.5;
195 double sY = 1.;
196 double sZ = .7;
197 int nContours = 1;
198 bool skipAxisCut = false;
199 bool skipContour = false;
200 bool skipCut = false;
201 bool skipGeometry = false;
202 bool skipShrink = false;
203 bool printDescriptor = false;
204
205 // Initialize command line argument parser
206 vtksys::CommandLineArguments clArgs;
207 clArgs.Initialize( argc, argv );
208 clArgs.StoreUnusedArguments( false );
209
210 // Parse command line parameters and options
211 clArgs.AddArgument( "--dimension",
212 vtksys::CommandLineArguments::SPACE_ARGUMENT,
213 &dim, "Dimension of hyper tree grid" );
214
215 clArgs.AddArgument( "--branch-factor",
216 vtksys::CommandLineArguments::SPACE_ARGUMENT,
217 &branch, "Branching factor of hyper tree grid" );
218
219 clArgs.AddArgument( "--max-level",
220 vtksys::CommandLineArguments::SPACE_ARGUMENT,
221 &max, "Maximum depth of hyper tree grid" );
222
223 clArgs.AddArgument("--descriptor",
224 vtksys::CommandLineArguments::SPACE_ARGUMENT,
225 &descriptor, "String describing the hyper tree grid");
226
227 clArgs.AddArgument( "--grid-size-X",
228 vtksys::CommandLineArguments::SPACE_ARGUMENT,
229 &nX, "Size of hyper tree grid in X direction" );
230
231 clArgs.AddArgument( "--grid-size-Y",
232 vtksys::CommandLineArguments::SPACE_ARGUMENT,
233 &nY, "Size of hyper tree grid in Y direction" );
234
235 clArgs.AddArgument( "--grid-size-Z",
236 vtksys::CommandLineArguments::SPACE_ARGUMENT,
237 &nZ, "Size of hyper tree grid in Z direction" );
238
239 clArgs.AddArgument( "--grid-scale-X",
240 vtksys::CommandLineArguments::SPACE_ARGUMENT,
241 &sX, "Scale of hyper tree grid in X direction" );
242
243 clArgs.AddArgument( "--grid-scale-Y",
244 vtksys::CommandLineArguments::SPACE_ARGUMENT,
245 &sY, "Scale of hyper tree grid in Y direction" );
246
247 clArgs.AddArgument( "--grid-scale-Z",
248 vtksys::CommandLineArguments::SPACE_ARGUMENT,
249 &sZ, "Scale of hyper tree grid in Z direction" );
250
251 clArgs.AddArgument( "--contours",
252 vtksys::CommandLineArguments::SPACE_ARGUMENT,
253 &nContours, "Number of iso-contours to be calculated" );
254
255 clArgs.AddArgument( "--skip-Axis-Cut",
256 vtksys::CommandLineArguments::NO_ARGUMENT,
257 &skipAxisCut, "Skip axis cut filter" );
258
259 clArgs.AddArgument( "--skip-Contour",
260 vtksys::CommandLineArguments::NO_ARGUMENT,
261 &skipContour, "Skip contour filter" );
262
263 clArgs.AddArgument( "--skip-Cut",
264 vtksys::CommandLineArguments::NO_ARGUMENT,
265 &skipCut, "Skip cut filter" );
266
267 clArgs.AddArgument( "--skip-Geometry",
268 vtksys::CommandLineArguments::NO_ARGUMENT,
269 &skipGeometry, "Skip geometry filter" );
270
271 clArgs.AddArgument( "--skip-Shrink",
272 vtksys::CommandLineArguments::NO_ARGUMENT,
273 &skipShrink, "Skip shrink filter" );
274
275 clArgs.AddArgument( "--print-Descriptor",
276 vtksys::CommandLineArguments::NO_ARGUMENT,
277 &printDescriptor, "Print descriptor string" );
278
279 // If incorrect arguments were provided, provide some help and terminate in error.
280 if ( ! clArgs.Parse() )
281 {
282 cerr << "Usage: "
283 << clArgs.GetHelp()
284 << "\n";
285 return 1;
286 }
287
288 // Verify and set input parameters
289 SetInputParameters( dim, branch, nX, nY, nZ, max, descriptor );
290 if ( printDescriptor )
291 {
292 cerr << "# Hyper tree grid descriptor: "
293 << endl
294 << descriptor
295 << endl;
296 }
297
298 // Create hyper tree grid source
299 vtkNew<vtkHyperTreeGridSource> source;
300 source->DualOn();
301 source->SetGridSize( nX, nY, nZ );
302 source->SetGridScale( sX, sY, sZ );
303 source->SetDimension( dim );
304 source->SetAxisBranchFactor( branch );
305 source->SetMaximumLevel( max );
306 source->SetDescriptor( descriptor.c_str() );
307 source->Update();
308 vtkHyperTreeGrid* htGrid = source->GetOutput();
309 cerr << " Number of hyper tree dual grid cells: "
310 << htGrid->GetNumberOfCells()
311 << endl;
312
313 if ( ! skipGeometry )
314 {
315 cerr << "# Geometry" << endl;
316 vtkNew<vtkHyperTreeGridGeometry> geometry;
317 geometry->SetInputConnection( source->GetOutputPort() );
318 vtkNew<vtkPolyDataWriter> writer4;
319 writer4->SetFileName( "./hyperTreeGridGeometry.vtk" );
320 writer4->SetInputConnection( geometry->GetOutputPort() );
321 writer4->Write();
322 cerr << " Number of surface cells: "
323 << geometry->GetOutput()->GetNumberOfCells()
324 << endl;
325 }
326
327 if ( ! skipContour )
328 {
329 cerr << "# Contour" << endl;
330 vtkNew<vtkContourFilter> contour;
331 contour->SetInputData( htGrid );
332 double* range = htGrid->GetPointData()->GetScalars()->GetRange();
333 cerr << " Calculating "
334 << nContours
335 << " iso-contours across ["
336 << range[0]
337 << ", "
338 << range[1]
339 << "] range:"
340 << endl;
341 contour->SetNumberOfContours( nContours );
342 double resolution = ( range[1] - range[0] ) / ( nContours + 1. );
343 double isovalue = resolution;
344 for ( int i = 0; i < nContours; ++ i, isovalue += resolution )
345 {
346 cerr << " Contour "
347 << i
348 << " at iso-value: "
349 << isovalue
350 << endl;
351 contour->SetValue( i, isovalue );
352 }
353 vtkNew<vtkPolyDataWriter> writer0;
354 writer0->SetFileName( "./hyperTreeGridContour.vtk" );
355 writer0->SetInputConnection( contour->GetOutputPort() );
356 writer0->Write();
357 cerr << " Number of cells in iso-contours: "
358 << contour->GetOutput()->GetNumberOfCells()
359 << endl;
360 }
361
362 if ( ! skipShrink )
363 {
364 cerr << "# Shrink" << endl;
365 vtkNew<vtkShrinkFilter> shrink;
366 shrink->SetInputData( htGrid );
367 shrink->SetShrinkFactor( .5 );
368 vtkNew<vtkUnstructuredGridWriter> writer1;
369 writer1->SetFileName( "./hyperTreeGridShrink.vtk" );
370 writer1->SetInputConnection( shrink->GetOutputPort() );
371 writer1->Write();
372 cerr << " Number of shrunk cells: "
373 << shrink->GetOutput()->GetNumberOfCells()
374 << endl;
375 }
376
377 if ( ! skipAxisCut )
378 {
379 // Axis-aligned cut works only in 3D for now
380 if ( dim == 3 )
381 {
382 cerr << "# HyperTreeGridAxisCut" << endl;
383 vtkNew<vtkHyperTreeGridAxisCut> axisCut;
384 axisCut->SetInputConnection( source->GetOutputPort() );
385 axisCut->SetPlaneNormalAxis( 2 );
386 axisCut->SetPlanePosition( .499 * nZ * sZ );
387 vtkNew<vtkPolyDataWriter> writer2;
388 writer2->SetFileName( "./hyperTreeGridAxisCut.vtk" );
389 writer2->SetInputConnection( axisCut->GetOutputPort() );
390 writer2->Write();
391 cerr << " Number of cells in axis cut: "
392 << axisCut->GetOutput()->GetNumberOfCells()
393 << endl;
394 }
395 }
396
397 if ( ! skipCut )
398 {
399 cerr << "# Cut" << endl;
400 vtkNew<vtkCutter> cut;
401 vtkNew<vtkPlane> plane;
402 plane->SetOrigin( .5, .5, .15 );
403 plane->SetNormal( 0, 0, 1 );
404 cut->SetInputData( htGrid );
405 cut->SetCutFunction( plane.GetPointer() );
406 vtkNew<vtkPolyDataWriter> writer3;
407 writer3->SetFileName( "./hyperTreeGridCut.vtk" );
408 writer3->SetInputConnection( cut->GetOutputPort() );
409 writer3->Write();
410 cerr << " Number of cells in generic cut: "
411 << cut->GetOutput()->GetNumberOfCells()
412 << endl;
413 }
414
415 return 0;
416 }
417