Commit ddde757a authored by Berk Geveci's avatar Berk Geveci
Browse files

ENH: Finally updated examples to work with new pipeline

parent 82e7cb1b
......@@ -6,8 +6,5 @@ IF(NOT VTK_USE_RENDERING)
ENDIF(NOT VTK_USE_RENDERING)
INCLUDE(${VTK_USE_FILE})
ADD_EXECUTABLE(HierarchicalBox HierarchicalBox.cxx)
TARGET_LINK_LIBRARIES(HierarchicalBox vtkRendering vtkIO)
ADD_EXECUTABLE(HierarchicalBoxPipeline HierarchicalBoxPipeline.cxx)
TARGET_LINK_LIBRARIES(HierarchicalBoxPipeline vtkRendering vtkIO)
/*=========================================================================
Program: Visualization Toolkit
Module: HierarchicalBox.cxx
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.
=========================================================================*/
// This example demonstrates how hierarchical box (uniform rectilinear)
// AMR datasets can be processed using the new vtkHierarchicalBoxDataSet class.
// Since the native pipeline support is not yet available, helper classes are
// used outside the pipeline to process the dataset.
// See the comments below for details.
//
// The command line arguments are:
// -D <path> => path to the data (VTKData); the data should be in <path>/Data/
#include "vtkActor.h"
#include "vtkAMRBox.h"
#include "vtkCellDataToPointData.h"
#include "vtkCompositeDataIterator.h"
#include "vtkCompositeDataVisitor.h"
#include "vtkContourFilter.h"
#include "vtkDebugLeaks.h"
#include "vtkHierarchicalBoxDataSet.h"
#include "vtkImageData.h"
#include "vtkMultiBlockApplyFilterCommand.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkTestUtilities.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkUniformGrid.h"
#include "vtkXMLImageDataReader.h"
int main(int argc, char* argv[])
{
// Standard rendering classes
vtkRenderer *ren = vtkRenderer::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
renWin->AddRenderer(ren);
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
// Since there is no AMR reader avaible yet, we will load a
// collection of VTK files and create our own vtkHierarchicalBoxDataSet.
// To create the files, I loaded a Chombo file with an experimental
// Chombo reader and wrote the datasets separately.
int i;
vtkXMLImageDataReader* reader = vtkXMLImageDataReader::New();
// vtkHierarchicalBoxDataSet represents hierarchical box
// (uniform rectilinear) AMR datasets, See the class documentation
// for more information.
vtkHierarchicalBoxDataSet* hb = vtkHierarchicalBoxDataSet::New();
for (i=0; i<16; i++)
{
// Here we load the 16 separate files (each containing
// an image dataset -uniform rectilinear grid-)
ostrstream fname;
fname << "Data/chombo3d/chombo3d_" << i << ".vti" << ends;
char* fstr = fname.str();
char* cfname =
vtkTestUtilities::ExpandDataFileName(argc, argv, fstr);
reader->SetFileName(cfname);
// We have to update since we are working without a VTK pipeline.
// This will read the file and the output of the reader will be
// a valid image data.
reader->Update();
delete[] fstr;
delete[] cfname;
// We now create a vtkUniformGrid. This is essentially a simple
// vtkImageData (not a sub-class though) with blanking. Since
// VTK readers do not know vtkUniformGrid, we simply create our
// own by copying from the image data.
vtkUniformGrid* ug = vtkUniformGrid::New();
ug->ShallowCopy(reader->GetOutput());
// Each sub-dataset in a vtkHierarchicalBoxDataSet has an associated
// vtkAMRBox. This is similar to extent but is stored externally
// since it is possible to have sub-dataset nodes with NULL
// vtkUniformGrid pointers.
vtkAMRBox box;
// This is a hack (do not do this at home). Normally, the
// region (box) information should be available in the file.
// In this case, since there is no such information available,
// we obtain it by looking at each image data's extent.
// -- begin hack
int extent[6];
double spacing[3];
double origin[3];
ug->GetExtent(extent);
ug->GetSpacing(spacing);
ug->GetOrigin(origin);
for (int j=0; j<3; j++)
{
box.LoCorner[j] =
static_cast<int>(origin[j]/spacing[j] + extent[2*j]);
box.HiCorner[j] =
static_cast<int>(origin[j]/spacing[j] + extent[2*j+1] - 1);
}
// Similarly, the level of each sub-dataset is normally
// available in the file. Since this is not the case, I
// hard coded this into the example program.
// Level 0 = { 0 }, Level 1 = { 1 },
// Level 2 = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }
int level;
int dsindex;
if (i == 0)
{
level = 0;
dsindex = 0;
}
else if (i == 1)
{
level = 1;
dsindex = 0;
}
else
{
level = 2;
dsindex = i-2;
}
// -- end hack
// Given the level, index and box, add the sub-dataset to
// hierarchical dataset.
hb->SetDataSet(level, dsindex, box, ug);
ug->Delete();
}
reader->Delete();
// I hard coded the refinement ratios. These should normally
// be available in the file.
hb->SetRefinementRatio(0, 2);
hb->SetRefinementRatio(1, 2);
// This call generates visibility (blanking) arrays that mask
// regions of lower level datasets that overlap with regions
// of higher level datasets (it is assumed that, when available,
// higher level information should always be used instead of
// lower level information)
hb->GenerateVisibilityArrays();
// Here is how a multi-block dataset is processed currently:
// 1. Create a command to applied to each sub-dataset in the AMR
// dataset. Usually this is vtkMultiBlockApplyFilterCommand. This
// command applies a filter to each sub-dataset and collects the
// outputs in a multi-block dataset.
// 2. Create a visitor that will iterate over the sub-datasets and
// apply the command to each.
// 3. Get the output from the command.
// First, we pass the AMR dataset through a celldatatopointdata filter
// since the dataset has cell data only (contour needs point data).
// Create the command
vtkMultiBlockApplyFilterCommand* comm1 =
vtkMultiBlockApplyFilterCommand::New();
// Create and assign the filter.
vtkCellDataToPointData* c2p = vtkCellDataToPointData::New();
comm1->SetFilter(c2p);
c2p->Delete();
// Ask the dataset to create an appropriate visitor for us.
vtkCompositeDataVisitor* visitor1 = hb->NewVisitor();
// Tell the visitor to use the command we create
visitor1->SetCommand(comm1);
// Apply the command to each sub-dataset.
visitor1->Execute();
// Next we apply an iso-surface filter to the resulting multi-block
// dataset.
// Create the command
vtkMultiBlockApplyFilterCommand* comm2 =
vtkMultiBlockApplyFilterCommand::New();
// Create and assign the filter.
vtkContourFilter* contour = vtkContourFilter::New();
// Note that we are setting the contour values directly
// on the filter. There is no way of doing this through
// the command or visitor.
contour->SetValue(0, -0.013);
contour->SelectInputScalars("phi");
comm2->SetFilter(contour);
contour->Delete();
// Ask the multi-block datasets to create an appropriate visitor
// for us.
vtkCompositeDataVisitor* visitor2 = comm1->GetOutput()->NewVisitor();
// Tell the visitor to use the command we create
visitor2->SetCommand(comm2);
// Apply the command to each sub-dataset. If any of the sub-datasets
// are composite datasets, the visitor will recursively process those
// and their sub-datasets.
visitor2->Execute();
// After the execution, the output should contain all the
// iso-surfaces (one polydata for each sub-dataset)
vtkMultiBlockDataSet* output = comm2->GetOutput();
// We now create a mapper/actor pair for each iso-surface.
// Ask the output multi-block dataset to create an appropriate
// iterator. This is a forward iterator.
vtkCompositeDataIterator* iter = output->NewIterator();
iter->GoToFirstItem();
while (!iter->IsDoneWithTraversal())
{
// For each polydata, create a mapper/actor pair
vtkPolyData* pd = vtkPolyData::SafeDownCast(iter->GetCurrentDataObject());
if (pd)
{
vtkPolyDataMapper* mapper = vtkPolyDataMapper::New();
mapper->SetInput(pd);
vtkActor* actor = vtkActor::New();
actor->SetMapper(mapper);
mapper->Delete();
ren->AddActor(actor);
actor->Delete();
}
iter->GoToNextItem();
}
iter->Delete();
// In the future (once the pipeline changes are finished), it
// will be possible to do the following:
//
// vtkHBoxAMRSomethingReader* reader = vtkHBoxAMRSomethingReader::New()
//
// vtkHierarchicalBoxCellDataToPointData* c2p =
// vtkHierarchicalBoxCellDataToPointData::New();
// c2p->SetInput(reader->GetOutput());
//
// vtkContourFilter* contour = vtkContourFilter::New();
// contour->SetInput(c2p->GetOutput());
//
// /* This might or might not be necessary */
// vtkMultiBlockPolyDataGeometryFilter* geom =
// vtkMultiBlockPolyDataGeometryFilter::New();
// geom->SetInput(contour->GetOutput());
//
// vtkPolyDataMapper* mapper = vtkPolyDataMapper::New();
// mapper->SetInput(geom->GetOutput());
// Standard testing code.
ren->SetBackground(1,1,1);
renWin->SetSize(300,300);
iren->Start();
// Cleanup
ren->Delete();
renWin->Delete();
iren->Delete();
comm1->Delete();
comm2->Delete();
visitor1->Delete();
visitor2->Delete();
hb->Delete();
return 0;
}
......@@ -14,23 +14,19 @@
=========================================================================*/
// This example demonstrates how hierarchical box (uniform rectilinear)
// AMR datasets can be processed using the new vtkHierarchicalBoxDataSet class.
// Since the native pipeline support is not yet available, special AMR
// filters are used to process the dataset. These filters are simple
// wrappers around the corresponding dataset filters.
// See the comments below for details.
//
// The command line arguments are:
// -D <path> => path to the data (VTKData); the data should be in <path>/Data/
#include "vtkActor.h"
#include "vtkAMRBox.h"
#include "vtkCellDataToPointData.h"
#include "vtkContourFilter.h"
#include "vtkDebugLeaks.h"
#include "vtkHierarchicalBoxCellDataToPointData.h"
#include "vtkHierarchicalBoxContour.h"
#include "vtkHierarchicalBoxDataSet.h"
#include "vtkHierarchicalBoxOutlineFilter.h"
#include "vtkHierarchicalDataSetGeometryFilter.h"
#include "vtkImageData.h"
#include "vtkPolyData.h"
#include "vtkOutlineCornerFilter.h"
#include "vtkPolyDataMapper.h"
#include "vtkProperty.h"
#include "vtkTestUtilities.h"
......@@ -155,72 +151,64 @@ int main(int argc, char* argv[])
// lower level information)
hb->GenerateVisibilityArrays();
// We now create a simple pipeline using AMR filters. The AMR
// filters can be simple wrappers around existing dataset filters.
// However, some of these filters are special. For example,
// cell data to point data conversion requires knowledge about
// neighbors (same level or higher) to minimize artifacts at
// the boundaries.
vtkHierarchicalBoxCellDataToPointData* c2p =
vtkHierarchicalBoxCellDataToPointData::New();
// We now create a simple pipeline.
// AMR datasets can be processed with regular VTK filters in two ways:
// 1. Pass through a AMR aware consumer. Since a AMR
// aware mapper is not yet available, vtkHierarchicalDataSetGeometryFilter
// can be used
// 2. Assign the composite executive (vtkCompositeDataPipeline) to
// all "simple" (that work only on simple, non-composite datasets) filters
vtkCellDataToPointData* c2p = vtkCellDataToPointData::New();
c2p->SetInput(hb);
// The contour filter is a simple wrapper around the dataset
// filter. When the pipeline changes are completed, there will
// be no need for this.
vtkHierarchicalBoxContour* contour = vtkHierarchicalBoxContour::New();
contour->SetInput(c2p->GetOutput());
// contour
vtkContourFilter* contour = vtkContourFilter::New();
contour->SetInputConnection(0, c2p->GetOutputPort(0));
contour->SelectInputScalars("phi");
contour->SetValue(0, -0.013);
// geometry filter
// This filter is AMR aware and will request blocks from the
// input. These blocks will be processed by simple processes as if they
// are the whole dataset
vtkHierarchicalDataSetGeometryFilter* geom1 =
vtkHierarchicalDataSetGeometryFilter::New();
geom1->SetInputConnection(0, contour->GetOutputPort(0));
// Rendering objects
vtkPolyDataMapper* ctMapper = vtkPolyDataMapper::New();
ctMapper->SetInput(contour->GetOutput());
ctMapper->SetInputConnection(0, geom1->GetOutputPort(0));
vtkActor* ctActor = vtkActor::New();
ctActor->SetMapper(ctMapper);
ren->AddActor(ctActor);
// The outline filter is a simple wrapper around the dataset
// filter. When the pipeline changes are completed, there will
// be no need for this.
vtkHierarchicalBoxOutlineFilter* outline =
vtkHierarchicalBoxOutlineFilter::New();
// outline
vtkOutlineCornerFilter* outline = vtkOutlineCornerFilter::New();
outline->SetInput(hb);
vtkHierarchicalDataSetGeometryFilter* geom2 =
vtkHierarchicalDataSetGeometryFilter::New();
geom2->SetInputConnection(0, outline->GetOutputPort(0));
// Rendering objects
vtkPolyDataMapper* outMapper = vtkPolyDataMapper::New();
outMapper->SetInput(outline->GetOutput());
outMapper->SetInputConnection(0, geom2->GetOutputPort(0));
vtkActor* outActor = vtkActor::New();
outActor->SetMapper(outMapper);
outActor->GetProperty()->SetColor(0, 0, 0);
ren->AddActor(outActor);
// In the future (once the pipeline changes are finished), it
// will be possible to do the following:
//
// vtkHBoxAMRSomethingReader* reader = vtkHBoxAMRSomethingReader::New()
//
// vtkHierarchicalBoxCellDataToPointData* c2p =
// vtkHierarchicalBoxCellDataToPointData::New();
// c2p->SetInput(reader->GetOutput());
//
// vtkContourFilter* contour = vtkContourFilter::New();
// contour->SetInput(c2p->GetOutput());
//
// /* This might or might not be necessary */
// vtkMultiBlockPolyDataGeometryFilter* geom =
// vtkMultiBlockPolyDataGeometryFilter::New();
// geom->SetInput(contour->GetOutput());
//
// vtkPolyDataMapper* mapper = vtkPolyDataMapper::New();
// mapper->SetInput(geom->GetOutput());
// Standard testing code.
ren->SetBackground(1,1,1);
renWin->SetSize(300,300);
iren->Start();
// Cleanup
geom1->Delete();
geom2->Delete();
ren->Delete();
renWin->Delete();
iren->Delete();
......
......@@ -109,8 +109,8 @@ ELSE(VTK_BINARY_DIR)
# Most examples require rendering support.
IF(VTK_USE_RENDERING)
SUBDIRS(
#AMR/Cxx
#MultiBlock/Cxx
AMR/Cxx
MultiBlock/Cxx
DataManipulation/Cxx
Medical/Cxx
Modelling/Cxx
......
......@@ -13,28 +13,28 @@
=========================================================================*/
// This example demonstrates how multi-block datasets can be processed
// using the new vtkMultiBlockDataSet class. Since the native pipeline
// support is not yet available, helper classes are used outside the
// pipeline to process the dataset. See the comments below for details.
// using the new vtkHierarchicalDataSet class.
//
// The command line arguments are:
// -D <path> => path to the data (VTKData); the data should be in <path>/Data/
#include "vtkActor.h"
#include "vtkCompositeDataIterator.h"
#include "vtkCompositeDataVisitor.h"
#include "vtkCellDataToPointData.h"
#include "vtkContourFilter.h"
#include "vtkDebugLeaks.h"
#include "vtkMultiBlockApplyFilterCommand.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkHierarchicalDataSet.h"
#include "vtkHierarchicalDataSetGeometryFilter.h"
#include "vtkOutlineCornerFilter.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkTestUtilities.h"
#include "vtkRegressionTestImage.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkShrinkPolyData.h"
#include "vtkStructuredGrid.h"
#include "vtkStructuredGridOutlineFilter.h"
#include "vtkTestUtilities.h"
#include "vtkXMLStructuredGridReader.h"
int main(int argc, char* argv[])
......@@ -51,9 +51,10 @@ int main(int argc, char* argv[])
// three pieces and wrote them out separately.
int i;
vtkXMLStructuredGridReader* reader = vtkXMLStructuredGridReader::New();
// vtkMultiBlockDataSet respresents multi-block datasets. See
// the class documentation for more information.
vtkMultiBlockDataSet* mb = vtkMultiBlockDataSet::New();
vtkHierarchicalDataSet* mb = vtkHierarchicalDataSet::New();
for (i=0; i<3; i++)
{
......@@ -79,99 +80,78 @@ int main(int argc, char* argv[])
sg->ShallowCopy(reader->GetOutput());
// Add the structured grid to the multi-block dataset
mb->AddDataSet(sg);
mb->SetDataSet(0, i, sg);
sg->Delete();
}
reader->Delete();
// Here is how a multi-block dataset is processed currently:
// 1. Create a command to be applied to each sub-dataset in the multi-block
// dataset. Usually this is vtkMultiBlockApplyFilterCommand. This
// command applies a filter to each sub-dataset and collects the
// outputs in an another multi-block dataset.
// 2. Create a visitor that will iterate over the sub-datasets and
// apply the command to each.
// 3. Get the output from the command.
// Create the command
vtkMultiBlockApplyFilterCommand* comm =
vtkMultiBlockApplyFilterCommand::New();
// Create and assign the filter.
vtkContourFilter* filter = vtkContourFilter::New();
// Note that we are setting the contour values directly
// on the filter. There is no way of doing this through
// the command or visitor.
filter->SetValue(0, 0.45);
comm->SetFilter(filter);
filter->Delete();
// Ask the multi-block dataset to create an appropriate visitor
// for us.
vtkCompositeDataVisitor* visitor = mb->NewVisitor();
// Tell the visitor to use the command we create
visitor->SetCommand(comm);
// Apply the command to each sub-dataset. If any of the sub-datasets
// are composite datasets, the visitor will recursively process those
// and their sub-datasets.
visitor->Execute();
// After the execution, the output should contain all the
// iso-surfaces (one polydata for each sub-dataset)
vtkMultiBlockDataSet* output = comm->GetOutput();
// We now create a mapper/actor pair for each iso-surface.
// Ask the output multi-block dataset to create an appropriate
// iterator. This is a forward iterator.
vtkCompositeDataIterator* iter = output->NewIterator();
iter->GoToFirstItem();
while (!iter->IsDoneWithTraversal())
{
// For each polydata, create a mapper/actor pair
vtkPolyData* pd = vtkPolyData::SafeDownCast(iter->GetCurrentDataObject());
if (pd)
{
vtkPolyDataMapper* mapper = vtkPolyDataMapper::New();
mapper->SetInput(pd);
vtkActor* actor = vtkActor::New();
actor->SetMapper(mapper);
mapper->Delete();
ren->AddActor(actor);
actor->Delete();
}
iter->GoToNextItem();
}
iter->Delete();
// In the future (once the pipeline changes are finished), it
// will be possible to do the following:
//
// vtkMultiBlockSomethingReader* reader = vtkMultiBlockSomethingReader::New()
//
// vtkContourFilter* contour = vtkContourFilter::New();
// contour->SetInput(reader->GetOutput());
//
// /* This might or might not be necessary */
// vtkMultiBlockPolyDataGeometryFilter* geom =
// vtkMultiBlockPolyDataGeometryFilter::New();
// geom->SetInput(contour->GetOutput());
//
// vtkPolyDataMapper* mapper = vtkPolyDataMapper::New();
// mapper->SetInput(geom->GetOutput());
// Standard testing code.
// Multi-block can be processed with regular VTK filters in two ways:
// 1. Pass through a multi-block aware consumer. Since a multi-block
// aware mapper is not yet available, vtkHierarchicalDataSetGeometryFilter
// can be used
// 2. Assign the composite executive (vtkCompositeDataPipeline) to
// all "simple" (that work only on simple, non-composite datasets) filters
// outline
vtkStructuredGridOutlineFilter* of = vtkStructuredGridOutlineFilter::New();
of->SetInput(mb);
// geometry filter
// This filter is multi-block aware and will request blocks from the
// input. These blocks will be processed by simple processes as if they
// are the whole dataset
vtkHierarchicalDataSetGeometryFilter* geom1 =
vtkHierarchicalDataSetGeometryFilter::New();
geom1->SetInputConnection(0, of->GetOutputPort(0));
// Rendering objects
vtkPolyDataMapper* geoMapper = vtkPolyDataMapper::New();
geoMapper->SetInputConnection(0, geom1->GetOutputPort(0));
vtkActor* geoActor = vtkActor::New();
geoActor->SetMapper(geoMapper);
geoActor->GetProperty()->SetColor(0, 0, 0);
ren->AddActor(geoActor);
// cell 2 point and contour
vtkCellDataToPointData* c2p = vtkCellDataToPointData::New();
c2p->SetInput(mb);
vtkContourFilter* contour = vtkContourFilter::New();
contour->SetInputConnection(0, c2p->GetOutputPort(0));
contour->SetValue(0, 0.45);
// geometry filter
vtkHierarchicalDataSetGeometryFilter* geom2 =
vtkHierarchicalDataSetGeometryFilter::New();
geom2->SetInputConnection(0, contour->GetOutputPort(0));
// Rendering objects
vtkPolyDataMapper* contMapper = vtkPolyDataMapper::New();
contMapper->SetInputConnection(0, geom2->GetOutputPort(0));
vtkActor* contActor = vtkActor::New();