Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

492 lines
16 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: ExerciseUnstructuredGridRayCastMapper.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 "ExerciseUnstructuredGridRayCastMapper.h"
#include "vtkActor.h"
#include "vtkArrayCalculator.h"
#include "vtkAssignAttribute.h"
#include "vtkCamera.h"
#include "vtkCellData.h"
#include "vtkColorTransferFunction.h"
#include "vtkCubeSource.h"
#include "vtkDataSet.h"
#include "vtkDataSetTriangleFilter.h"
#include "vtkDoubleArray.h"
#include "vtkImageMandelbrotSource.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPiecewiseFunction.h"
#include "vtkPointData.h"
#include "vtkPointDataToCellData.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkUnstructuredGridVolumeRayCastFunction.h"
#include "vtkUnstructuredGridVolumeRayCastMapper.h"
#include "vtkUnstructuredGridVolumeRayIntegrator.h"
#include "vtkVolume.h"
#include "vtkVolumeProperty.h"
#include "vtkRegressionTestImage.h"
//=============================================================================
// A simple filter that will convert an array from independent scalars
// to dependent scalars.
class vtkClassifyVolume : public vtkDataSetAlgorithm
{
public:
vtkTypeRevisionMacro(vtkClassifyVolume, vtkDataSetAlgorithm);
static vtkClassifyVolume *New();
vtkGetObjectMacro(TransferFunction, vtkVolumeProperty);
vtkSetObjectMacro(TransferFunction, vtkVolumeProperty);
protected:
vtkClassifyVolume();
~vtkClassifyVolume();
virtual int RequestData(vtkInformation *, vtkInformationVector **,
vtkInformationVector *);
virtual void Classify(vtkDataSetAttributes *in, vtkDataSetAttributes *out);
vtkVolumeProperty *TransferFunction;
private:
vtkClassifyVolume(const vtkClassifyVolume&); // Not implemented
void operator=(const vtkClassifyVolume&); // Not implemented
};
//-----------------------------------------------------------------------------
vtkCxxRevisionMacro(vtkClassifyVolume, "$Revision: 1.4 $");
vtkStandardNewMacro(vtkClassifyVolume);
vtkClassifyVolume::vtkClassifyVolume()
{
this->TransferFunction = NULL;
}
vtkClassifyVolume::~vtkClassifyVolume()
{
this->SetTransferFunction(NULL);
}
//-----------------------------------------------------------------------------
int vtkClassifyVolume::RequestData(vtkInformation *,
vtkInformationVector **inputVector,
vtkInformationVector *outputVector)
{
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
vtkDataSet *input = vtkDataSet::SafeDownCast(
inInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkInformation *outInfo = outputVector->GetInformationObject(0);
vtkDataSet *output = vtkDataSet::SafeDownCast(
outInfo->Get(vtkDataObject::DATA_OBJECT()));
output->CopyStructure(input);
this->Classify(input->GetPointData(), output->GetPointData());
this->Classify(input->GetCellData(), output->GetCellData());
return 1;
}
//-----------------------------------------------------------------------------
void vtkClassifyVolume::Classify(vtkDataSetAttributes *inAttrib,
vtkDataSetAttributes *outAttrib)
{
vtkDataArray *scalars = inAttrib->GetScalars();
if (!scalars) return;
if (scalars->GetNumberOfComponents() != 1)
{
vtkErrorMacro(<< "Only 1-tuple scalars are supported now.");
return;
}
vtkIdType numScalars = scalars->GetNumberOfTuples();
vtkDoubleArray *colors = vtkDoubleArray::New();
colors->SetName(scalars->GetName());
if (this->TransferFunction->GetColorChannels() == 3)
{
colors->SetNumberOfComponents(4);
colors->SetNumberOfTuples(numScalars);
vtkColorTransferFunction *rgb
= this->TransferFunction->GetRGBTransferFunction();
vtkPiecewiseFunction *alpha = this->TransferFunction->GetScalarOpacity();
for (vtkIdType i = 0; i < numScalars; i++)
{
double c[4];
double x = scalars->GetComponent(i, 0);
rgb->GetColor(x, c);
c[3] = alpha->GetValue(x);
colors->SetTuple(i, c);
}
}
else
{
vtkErrorMacro(<< "Gray values are not supported now.");
}
outAttrib->SetScalars(colors);
colors->Delete();
}
//=============================================================================
static vtkRenderer *NewTestViewport(RayCastFunctionCreator NewFunction,
RayIntegratorCreator NewIntegrator,
vtkVolumeProperty *volumeProperty,
int UseCellData, int UseDependentComponents,
int UseMultipleTransferFunctions)
{
// Create the render window.
vtkRenderer *ren = vtkRenderer::New();
// Create a small mesh. The coarser and more opaque the mesh, the easier it
// is to see rendering errors.
vtkImageMandelbrotSource *input = vtkImageMandelbrotSource::New();
input->SetWholeExtent(0, 2, 0, 2, 0, 2);
input->SetSizeCX(2, 2, 2, 2);
input->SetMaximumNumberOfIterations(10);
vtkAlgorithmOutput *outputPort = input->GetOutputPort(0);
// Make sure we have only tetrahedra.
vtkDataSetTriangleFilter *trifilter = vtkDataSetTriangleFilter::New();
trifilter->SetInputConnection(0, outputPort);
outputPort = trifilter->GetOutputPort(0);
// Make multiple scalars if necessary.
vtkArrayCalculator *calc = NULL;
vtkAssignAttribute *assign = NULL;
if (UseMultipleTransferFunctions)
{
calc = vtkArrayCalculator::New();
calc->AddScalarArrayName("Iterations");
calc->SetResultArrayName("Result");
calc->SetFunction("Iterations*iHat + (10-Iterations)*jHat");
calc->SetInputConnection(0, outputPort);
outputPort = calc->GetOutputPort(0);
assign = vtkAssignAttribute::New();
assign->Assign(vtkDataSetAttributes::VECTORS, vtkDataSetAttributes::SCALARS,
vtkAssignAttribute::POINT_DATA);
assign->SetInputConnection(0, outputPort);
outputPort = assign->GetOutputPort(0);
}
// Convert to cell centered data if requested.
vtkPointDataToCellData *celldata = NULL;
if (UseCellData)
{
celldata = vtkPointDataToCellData::New();
celldata->SetInputConnection(0, outputPort);
celldata->PassPointDataOff();
outputPort = celldata->GetOutputPort(0);
}
// Classify the data if testing dependent components.
vtkClassifyVolume *classify = NULL;
if (UseDependentComponents)
{
classify = vtkClassifyVolume::New();
classify->SetTransferFunction(volumeProperty);
classify->SetInputConnection(0, outputPort);
outputPort = classify->GetOutputPort(0);
}
// Set up the mapper.
vtkUnstructuredGridVolumeRayCastMapper *mapper
= vtkUnstructuredGridVolumeRayCastMapper::New();
mapper->SetInputConnection(0, outputPort);
if (NewFunction)
{
vtkUnstructuredGridVolumeRayCastFunction *function = NewFunction();
mapper->SetRayCastFunction(function);
function->Delete();
}
if (NewIntegrator)
{
vtkUnstructuredGridVolumeRayIntegrator *integrator = NewIntegrator();
mapper->SetRayIntegrator(integrator);
integrator->Delete();
}
// The volume holds the mapper and property and can be used to position/orient
// the volume.
vtkVolume *volume = vtkVolume::New();
volume->SetMapper(mapper);
if (!UseDependentComponents)
{
volume->SetProperty(volumeProperty);
}
else
{
// Set up a volume property that does not have the transfer function.
vtkVolumeProperty *vp = vtkVolumeProperty::New();
vp->SetShade(volumeProperty->GetShade());
vp->SetInterpolationType(volumeProperty->GetInterpolationType());
vp->SetScalarOpacityUnitDistance(
volumeProperty->GetScalarOpacityUnitDistance());
vp->IndependentComponentsOff();
volume->SetProperty(vp);
vp->Delete();
}
// Add the volume to the renderer.
ren->AddVolume(volume);
ren->ResetCamera();
ren->GetActiveCamera()->Azimuth(20.0);
ren->GetActiveCamera()->Elevation(15.0);
ren->GetActiveCamera()->Zoom(1.5);
// Delete objects. Will not actually be destroyed due to reference counting.
input->Delete();
trifilter->Delete();
if (celldata) celldata->Delete();
if (calc) calc->Delete();
if (assign) assign->Delete();
if (classify) classify->Delete();
mapper->Delete();
volume->Delete();
return ren;
}
//-----------------------------------------------------------------------------
static vtkRenderer *NewPlaceholderViewport()
{
vtkRenderer *ren = vtkRenderer::New();
vtkCubeSource *cube = vtkCubeSource::New();
vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
mapper->SetInputConnection(0, cube->GetOutputPort(0));
cube->Delete();
vtkActor *actor = vtkActor::New();
actor->SetMapper(mapper);
mapper->Delete();
ren->AddActor(actor);
ren->ResetCamera();
actor->Delete();
return ren;
}
//-----------------------------------------------------------------------------
static vtkVolumeProperty *NewRGBVolumeProperty()
{
// Create transfer mapping scalar value to opacity.
vtkPiecewiseFunction *opacityTransferFunction = vtkPiecewiseFunction::New();
opacityTransferFunction->AddPoint( 0.0, 0.0);
opacityTransferFunction->AddPoint(10.0, 1.0);
// Create transfer mapping scalar value to color.
vtkColorTransferFunction *colorTransferFunction
= vtkColorTransferFunction::New();
colorTransferFunction->SetColorSpaceToHSV();
colorTransferFunction->HSVWrapOn();
colorTransferFunction->AddHSVPoint( 0.0, 4.0/6.0, 1.0, 1.0);
colorTransferFunction->AddHSVPoint( 4.0, 2.0/6.0, 1.0, 1.0);
colorTransferFunction->AddHSVPoint( 6.0, 1.0/6.0, 1.0, 1.0);
colorTransferFunction->AddHSVPoint(10.0, 5.0/6.0, 1.0, 1.0);
vtkVolumeProperty *volumeProperty = vtkVolumeProperty::New();
volumeProperty->SetColor(colorTransferFunction);
volumeProperty->SetScalarOpacity(opacityTransferFunction);
volumeProperty->ShadeOff();
volumeProperty->SetInterpolationTypeToLinear();
volumeProperty->SetScalarOpacityUnitDistance(0.75);
// Delete objects. Will not actually be destroyed due to reference counting.
opacityTransferFunction->Delete();
colorTransferFunction->Delete();
return volumeProperty;
}
//-----------------------------------------------------------------------------
static vtkVolumeProperty *NewGrayVolumeProperty()
{
// Create transfer mapping scalar value to opacity.
vtkPiecewiseFunction *opacityTransferFunction = vtkPiecewiseFunction::New();
opacityTransferFunction->AddPoint( 0.0, 0.0);
opacityTransferFunction->AddPoint(10.0, 1.0);
// Create transfer mapping scalar value to color.
vtkPiecewiseFunction *grayTransferFunction = vtkPiecewiseFunction::New();
grayTransferFunction->AddPoint( 0.0, 0.0);
grayTransferFunction->AddPoint(10.0, 1.0);
vtkVolumeProperty *volumeProperty = vtkVolumeProperty::New();
volumeProperty->SetColor(grayTransferFunction);
volumeProperty->SetScalarOpacity(opacityTransferFunction);
volumeProperty->ShadeOff();
volumeProperty->SetInterpolationTypeToLinear();
volumeProperty->SetScalarOpacityUnitDistance(0.75);
// Delete objects. Will not actually be destroyed due to reference counting.
opacityTransferFunction->Delete();
grayTransferFunction->Delete();
return volumeProperty;
}
//-----------------------------------------------------------------------------
static vtkVolumeProperty *NewMultiTFVolumeProperty()
{
vtkVolumeProperty *volumeProperty = vtkVolumeProperty::New();
volumeProperty->ShadeOff();
volumeProperty->SetInterpolationTypeToLinear();
volumeProperty->SetScalarOpacityUnitDistance(0.75);
vtkColorTransferFunction *rgb;
vtkPiecewiseFunction *a;
// Create first tf.
rgb = vtkColorTransferFunction::New();
rgb->AddRGBPoint(0.0, 1.0, 0.0, 0.0);
volumeProperty->SetColor(0, rgb);
rgb->Delete();
a = vtkPiecewiseFunction::New();
a->AddPoint(2.9, 0.0);
a->AddPoint(3.0, 1.0);
volumeProperty->SetScalarOpacity(0, a);
a->Delete();
// Create second tf.
rgb = vtkColorTransferFunction::New();
rgb->AddRGBPoint(0.0, 0.0, 1.0, 1.0);
volumeProperty->SetColor(1, rgb);
rgb->Delete();
a = vtkPiecewiseFunction::New();
a->AddPoint(4.9, 0.0);
a->AddPoint(5.0, 0.5);
volumeProperty->SetScalarOpacity(1, a);
a->Delete();
// Create third tf.
rgb = vtkColorTransferFunction::New();
rgb->AddRGBPoint(0.0, 0.0, 0.0, 0.0);
volumeProperty->SetColor(2, rgb);
rgb->Delete();
a = vtkPiecewiseFunction::New();
a->AddPoint(0.0, 0.0);
volumeProperty->SetScalarOpacity(2, a);
a->Delete();
return volumeProperty;
}
//-----------------------------------------------------------------------------
int ExerciseUnstructuredGridRayCastMapper(int argc, char *argv[],
RayCastFunctionCreator NewFunction,
RayIntegratorCreator NewIntegrator,
int UseCellData,
int TestDependentComponents)
{
// Create the standard render window and interactor.
vtkRenderWindow *renWin = vtkRenderWindow::New();
renWin->SetSize(300, 300);
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
iren->SetDesiredUpdateRate(3.0);
// The property describes how the data will look. Establish various
// rendering modes with the property and its transfer functions.
vtkVolumeProperty *volumeProperty;
vtkRenderer *viewport;
// RGB transfer function.
volumeProperty = NewRGBVolumeProperty();
viewport = NewTestViewport(NewFunction, NewIntegrator, volumeProperty,
UseCellData, 0, 0);
if (!viewport) return -1;
viewport->SetViewport(0.0, 0.0, 0.5, 0.5);
renWin->AddRenderer(viewport);
volumeProperty->Delete();
viewport->Delete();
// Gray transfer function.
volumeProperty = NewGrayVolumeProperty();
viewport = NewTestViewport(NewFunction, NewIntegrator, volumeProperty,
UseCellData, 0, 0);
if (!viewport) return -1;
viewport->SetViewport(0.5, 0.0, 1.0, 0.5);
renWin->AddRenderer(viewport);
volumeProperty->Delete();
viewport->Delete();
if (TestDependentComponents)
{
// RGBA dependent components.
volumeProperty = NewRGBVolumeProperty();
viewport = NewTestViewport(NewFunction, NewIntegrator, volumeProperty,
UseCellData, 1, 0);
volumeProperty->Delete();
}
else
{
viewport = NewPlaceholderViewport();
}
if (!viewport) return -1;
viewport->SetViewport(0.0, 0.5, 0.5, 1.0);
renWin->AddRenderer(viewport);
viewport->Delete();
// Multiple transfer functions
volumeProperty = NewMultiTFVolumeProperty();
viewport = NewTestViewport(NewFunction, NewIntegrator, volumeProperty,
UseCellData, 0, 1);
if (!viewport) return -1;
viewport->SetViewport(0.5, 0.5, 1.0, 1.0);
renWin->AddRenderer(viewport);
volumeProperty->Delete();
viewport->Delete();
int retVal = vtkRegressionTestImageThreshold(renWin, 70);
if (retVal == vtkRegressionTester::DO_INTERACTOR)
{
iren->Start();
}
// Delete objects.
renWin->Delete();
iren->Delete();
return !retVal;
}