Pipeline for Generating Terrain Surfaces
//
// First we need some sources:
//
// An elevation data source:
elevReader = vtkImageReader::New();
elevReader->SetFileName( "canyon_elev.raw" );
elevReader->SetDataExtent( 0, 1023, 0, 511, 0, 0 );
elevReader->SetDataScalarTypeToUnsignedChar( );
elevReader->Update( ); // Needed to generate contour scale !
// A texture map source:
textureReader = vtkJPEGReader::New( );
textureReader->SetFileName( "canyon_rgb.jpg" );
//textureReader->SetFileName( "canyon_rgb_8.jpg" );
//
// Filters manipulate the data
//
/*vtkImageShrink3D *shrink = vtkImageShrink3D::New( );
shrink->SetShrinkFactors( 8, 8, 1 );
shrink->SetInput( elevReader->GetOutput( ) );
vtkImageShrink3D *textureShrinker = vtkImageShrink3D::New( );
textureShrinker->SetShrinkFactors( 8, 8, 1 );
textureShrinker->SetInput( textureReader->GetOutput( ) ); */
vtkImageDataGeometryFilter *geometry = vtkImageDataGeometryFilter::New( );
//geometry->SetInput( shrink->GetOutput( ) );
geometry->SetInput( elevReader->GetOutput( ) );
warper = vtkWarpScalar::New( );
warper->SetInput( ( vtkPointSet * ) ( geometry->GetOutput( ) ) );
warper->SetScaleFactor( scalingFactor );
vtkGeometryFilter *geomFilter = vtkGeometryFilter::New( );
geomFilter->SetInput( ( vtkDataSet * ) ( warper->GetOutput( ) ) );
vtkTexture *texture = vtkTexture::New( );
texture->SetInput( textureReader->GetOutput( ) );
//texture->SetInput( textureShrinker->GetOutput( ) );
texture->RepeatOff( );
vtkMergeFilter *merger = vtkMergeFilter::New( );
merger->SetGeometry( ( vtkDataSet * ) ( geomFilter->GetOutput( ) ) );
merger->SetScalars( ( vtkDataSet * ) ( textureReader->GetOutput( ) ) );
vtkGeometryFilter *geomFilter2 = vtkGeometryFilter::New( );
geomFilter2->SetInput( merger->GetOutput( ) );
float data[ 2 ], delta8;
elevReader->GetOutput( )->GetScalarRange( data );
dataMin = data[ 0 ];
dataMax = data[ 1 ];
delta8 = ( data[ 1 ] - data[ 0 ] ) / 8;
cout << "Data Min, Max, delta8 = " << dataMin << ", " << dataMax << ", "
<< delta8 << endl;
for( i = 0; i < 4; i++ ) {
contours[ i ] = vtkContourFilter::New( );
contours[ i ]->SetInput( ( vtkDataSet * ) ( elevReader->GetOutput( ) ) );
contourHeights[ i ] = data[ 0 ] + delta8 * ( 2 * i + 1 );
contours[ i ]->SetValue( 0, contourHeights[ i ] );
}
//
// The mapper ends the visualization pipeline
//
// vtkPolyDataMapper *surfaceMapper = vtkPolyDataMapper::New();
vtkDataSetMapper *surfaceMapper = vtkDataSetMapper::New();
//surfaceMapper->SetInput( geomFilter->GetOutput() );
surfaceMapper->SetInput( ( vtkDataSet * ) ( geomFilter2->GetOutput() ));
surfaceMapper->SetScalarRange( 0, 255 );
vtkPolyDataMapper *contourMappers[ 4 ];
for( i = 0; i < 4; i++ ) {
contourMappers[ i ] = vtkPolyDataMapper::New();
contourMappers[ i ]->SetInput( contours[ i ]->GetOutput() );
//contourMappers[ i ]->SetColorModeToMapScalars( );
//contourMappers[ i ]->SetScalarMaterialModeToAmbient( );
contourMappers[ i ]->SetScalarModeToUsePointFieldData( );
}
//
// Create an actor to represent the mapper output.
//
vtkLODActor *surfaceActor = vtkLODActor::New();
surfaceActor->SetMapper( surfaceMapper );
surfaceActor->SetTexture( texture );
float colors[ 4 ] [ 3 ] = { { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 },
{ 0.0, 0.0, 1.0 }, { 1.0, 1.0, 0.0 } };
for( i = 0; i < 4; i++ ) {
contourActors[ i ] = vtkActor::New( );
contourActors[ i ]->SetMapper( contourMappers[ i ] );
contourActors[ i ]->GetProperty( )->SetColor( colors[ i ] );
}
//
// Create the Renderer and assign actors to it. A renderer is like a
// viewport. It is part or all of a window on the screen and it is
// responsible for drawing the actors it has. We also set the background
// color here.
//
vtkRenderer *ren1= vtkRenderer::New();
ren1->AddActor( surfaceActor );
ren1->SetBackground( 0.1, 0.2, 0.4 );
ren1->SetViewport(0.0, 0.0, 1.0, 1.0);
for( i = 0; i < 4; i++ ) {
ren1->AddActor( contourActors[ i ] );
contourActors[ i ]->AddPosition( 0.0, 0.0, 2.0 - contourHeights[ i ] );
}
// Finally we create the render window which will show up on the screen.
// We put our renderer into the render window using AddRenderer. We also
// set the size.
vtkRenderWindow *renWin = vtkRenderWindow::New();
renWin->AddRenderer( ren1 );
renWin->SetSize( 600, 600 );
// The vtkRenderWindowInteractor class watches for events (e.g., keypress,
// mouse) in the vtkRenderWindow. These events are translated into
// event invocations that VTK understands (see VTK/Common/vtkCommand.h
// for all events that VTK processes). Then observers of these VTK
// events can process them as appropriate.
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
// By default the vtkRenderWindowInteractor instantiates an instance
// of vtkInteractorStyle. vtkInteractorStyle translates a set of events
// it observes into operations on the camera, actors, and/or properties
// in the vtkRenderWindow associated with the vtkRenderWinodwInteractor.
// Here we specify a particular interactor style.
vtkInteractorStyleTrackballCamera *style =
vtkInteractorStyleTrackballCamera::New();
iren->SetInteractorStyle(style);
// Unlike the previous scripts where we performed some operations and then
// exited, here we leave an event loop running. The user can use the mouse
// and keyboard to perform the operations on the scene according to the
// current interaction style. When the user presses the "e" key, by default
// an ExitEvent is invoked by the vtkRenderWindowInteractor which is caught
// and drops out of the event loop (triggered by the Start() method that
// follows.
iren->Initialize();
iren->Start();
// Final note: recall that an observers can watch for particular events and
// take appropriate action. Pressing "u" in the render window causes the
// vtkRenderWindowInteractor to invoke a UserEvent. This can be caught to
// popup a GUI, etc. So the Tcl Cone5.tcl example for an idea of how this
// works.
//
// Free up any objects we created. All instances in VTK are deleted by
// using the Delete() method.
//
elevReader->Delete();
//mapper->Delete();
//actor->Delete();
ren1->Delete();
renWin->Delete();
iren->Delete();
style->Delete();
} // End of constructor