Commit 0555e64a authored by Sankhesh Jhaveri's avatar Sankhesh Jhaveri Committed by Kitware Robot

Merge topic 'dependent_comps_grad_opacity'

e98dcbef Change test to use differing values for two components
07df9bce Change variable to a more context friendly name
14685528 Fix private method signatures
5de2fe82 Fix test to change the second component values
dfcbfe78 Use the right component for updating transfer function tables
276e272c Improve documentation for IndependentComponents
bcf077f1 Fix issues with volume rendering for dependent component data
36228cab Added test for four dependent comps with gradient opacity
...
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Merge-request: !1248
parents 1f6441f7 e98dcbef
......@@ -70,12 +70,17 @@ public:
// determine functionality). If IndependentComponents is Off, then you
// must have either 2 or 4 component data. For 2 component data, the
// first is passed through the first color transfer function and the
// second component is passed through the first opacity transfer function.
// Normals will be generated off of the second component. For 4 component
// second component is passed through the first scalar opacity (and
// gradient opacity) transfer function.
// Normals will be generated off of the second component. When using gradient
// based opacity modulation, the gradients are computed off of the
// second component. For 4 component
// data, the first three will directly represent RGB (no lookup table).
// The fourth component will be passed through the first scalar opacity
// transfer function for opacity. Normals will be generated from the fourth
// component.
// transfer function for opacity and first gradient opacity transfer function
// for gradient based opacity modulation. Normals will be generated from the
// fourth component. When using gradient based opacity modulation, the
// gradients are computed off of the fourth component.
vtkSetClampMacro(IndependentComponents, int, 0, 1);
vtkGetMacro(IndependentComponents, int);
vtkBooleanMacro(IndependentComponents, int);
......
......@@ -56,6 +56,7 @@ set (VolumeOpenGL2CxxTests
TestGPURayCastCameraInsideSmallSpacing.cxx
TestGPURayCastCellData.cxx
TestGPURayCastClipping.cxx
TestGPURayCastFourComponentsDependentGradient.cxx
TestGPURayCastGradientOpacity.cxx
TestGPURayCastPositionalLights.cxx
TestGPURayCastReleaseResources.cxx
......@@ -64,6 +65,7 @@ set (VolumeOpenGL2CxxTests
TestGPURayCastRenderToTexture.cxx
TestGPURayCastThreeComponentsIndependent.cxx
TestGPURayCastTwoComponentsDependent.cxx
TestGPURayCastTwoComponentsDependentGradient.cxx
TestGPURayCastTwoComponentsGradient.cxx
TestGPURayCastTwoComponentsIndependent.cxx
TestGPURayCastVolumeLightKit.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestGPURayCastFourComponentsDependentGradient.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.
=========================================================================*/
// Description
// This is a test for volume rendering using the GPU ray cast
// mapper of a dataset with four components treating them as
// dependent and applying a gradient opacity function
#include "vtkCamera.h"
#include "vtkColorTransferFunction.h"
#include "vtkGPUVolumeRayCastMapper.h"
#include "vtkNew.h"
#include "vtkPiecewiseFunction.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkTestUtilities.h"
#include "vtkTesting.h"
#include "vtkVolumeProperty.h"
#include "vtkXMLImageDataReader.h"
int TestGPURayCastFourComponentsDependentGradient(int argc, char *argv[])
{
cout << "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)" << endl;
char *cfname=
vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/vase_4comp.vti");
vtkNew<vtkXMLImageDataReader> reader;
reader->SetFileName(cfname);
delete [] cfname;
vtkNew<vtkRenderWindow> renWin;
renWin->SetSize(301, 300); // Intentional NPOT size
renWin->SetMultiSamples(0);
vtkNew<vtkRenderer> ren;
renWin->AddRenderer(ren.GetPointer());
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin.GetPointer());
renWin->Render();
// Volume render the dataset
vtkNew<vtkGPUVolumeRayCastMapper> mapper;
mapper->AutoAdjustSampleDistancesOff();
mapper->SetSampleDistance(0.5);
mapper->SetInputConnection(reader->GetOutputPort());
// Opacity transfer function
vtkNew<vtkPiecewiseFunction> pf;
pf->AddPoint(0, 0);
pf->AddPoint(255, 1);
// Gradient opacity transfer function
vtkNew<vtkPiecewiseFunction> pf1;
pf1->AddPoint(30, 0);
pf1->AddPoint(255, 1);
// Volume property with independent components OFF
vtkNew<vtkVolumeProperty> property;
property->IndependentComponentsOff();
property->SetScalarOpacity(pf.GetPointer());
property->SetGradientOpacity(pf1.GetPointer());
vtkNew<vtkVolume> volume;
volume->SetMapper(mapper.GetPointer());
volume->SetProperty(property.GetPointer());
ren->AddVolume(volume.GetPointer());
ren->ResetCamera();
renWin->Render();
iren->Initialize();
int retVal = vtkRegressionTestImage( renWin.GetPointer() );
if( retVal == vtkRegressionTester::DO_INTERACTOR)
{
iren->Start();
}
return !retVal;
}
/*=========================================================================
Program: Visualization Toolkit
Module: TestGPURayCastTwoComponentsDependentGradient.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.
=========================================================================*/
// Description
// This test creates a vtkImageData with two components.
// The data is volume rendered considering the two components as dependent
// and gradient based modulation of the opacity is applied
#include "vtkCamera.h"
#include "vtkColorTransferFunction.h"
#include "vtkGPUVolumeRayCastMapper.h"
#include "vtkImageData.h"
#include "vtkNew.h"
#include "vtkPiecewiseFunction.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkTesting.h"
#include "vtkTestUtilities.h"
#include "vtkVolume.h"
#include "vtkVolumeProperty.h"
#include "vtkUnsignedShortArray.h"
int TestGPURayCastTwoComponentsDependentGradient(int argc, char *argv[])
{
cout << "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)" << endl;
int dims[3] = { 30, 30, 30 };
// Create a vtkImageData with two components
vtkNew<vtkImageData> image;
image->SetDimensions(dims[0], dims[1], dims[2]);
image->AllocateScalars(VTK_DOUBLE, 2);
// Fill the first half rectangular parallelopiped along X with the
// first component values and the second half with second component values
double * ptr = static_cast<double *> (image->GetScalarPointer(0, 0, 0));
for (int z = 0; z < dims[2]; ++z)
{
for (int y = 0; y < dims[1]; ++y)
{
for (int x = 0; x < dims[0]; ++x)
{
if (x < dims[0] / 2)
{
if (y < dims[1] / 2)
{
*ptr++ = 0.0;
*ptr++ = 0.0;
}
else
{
*ptr++ = 0.25;
*ptr++ = 25.0;
}
}
else
{
if (y < dims[1] / 2)
{
*ptr++ = 0.5;
*ptr++ = 50.0;
}
else
{
*ptr++ = 1.0;
*ptr++ = 100.0;
}
}
}
}
}
vtkNew<vtkRenderWindow> renWin;
renWin->SetSize(301, 300); // Intentional NPOT size
renWin->SetMultiSamples(0);
vtkNew<vtkRenderer> ren;
renWin->AddRenderer(ren.GetPointer());
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin.GetPointer());
renWin->Render();
// Volume render the dataset
vtkNew<vtkGPUVolumeRayCastMapper> mapper;
mapper->AutoAdjustSampleDistancesOff();
mapper->SetSampleDistance(0.5);
mapper->SetInputData(image.GetPointer());
// Color transfer function
vtkNew<vtkColorTransferFunction> ctf1;
ctf1->AddRGBPoint(0.0, 0.0, 0.0, 1.0);
ctf1->AddRGBPoint(0.5, 0.0, 1.0, 0.0);
ctf1->AddRGBPoint(1.0, 1.0, 0.0, 0.0);
vtkNew<vtkColorTransferFunction> ctf2;
ctf2->AddRGBPoint(0.0, 0.0, 0.0, 0.0);
ctf2->AddRGBPoint(1.0, 0.0, 0.0, 1.0);
// Opacity functions
vtkNew<vtkPiecewiseFunction> pf1;
pf1->AddPoint(0.0, 0.1);
pf1->AddPoint(100.0, 0.1);
// Gradient Opacity function
// Whenever the gradient
vtkNew<vtkPiecewiseFunction> pf2;
pf2->AddPoint(0.0, 0.2);
pf2->AddPoint(30.0, 1.0);
// Volume property with independent components OFF
vtkNew<vtkVolumeProperty> property;
property->IndependentComponentsOff();
// Set color and opacity functions
property->SetColor(0, ctf1.GetPointer());
// Setting the transfer function for second component would be a no-op as only
// the first component functions are used.
property->SetColor(1, ctf2.GetPointer());
property->SetScalarOpacity(0, pf1.GetPointer());
property->SetGradientOpacity(0, pf2.GetPointer());
vtkNew<vtkVolume> volume;
volume->SetMapper(mapper.GetPointer());
volume->SetProperty(property.GetPointer());
ren->AddVolume(volume.GetPointer());
ren->ResetCamera();
renWin->Render();
iren->Initialize();
int retVal = vtkRegressionTestImage( renWin.GetPointer() );
if( retVal == vtkRegressionTester::DO_INTERACTOR)
{
iren->Start();
}
return !retVal;
}
#include <vtkSmartPointer.h>
#include <vtkPlanes.h>
#include <vtkCamera.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyData.h>
#include <vtkPointData.h>
/*=========================================================================
Program: Visualization Toolkit
Module: TestGPURayCastTwoComponentsIndependent.cxx
Module: TestGPURayCastTwoComponentsGradient.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
......
......@@ -233,19 +233,16 @@ public:
// and number of scalar components.
int UpdateColorTransferFunction(vtkRenderer* ren,
vtkVolume* vol,
int noOfComponents,
unsigned int component);
// Update opacity transfer function (not gradient opacity)
int UpdateOpacityTransferFunction(vtkRenderer* ren,
vtkVolume* vol,
int noOfComponents,
unsigned int component);
// Update gradient opacity function
int UpdateGradientOpacityTransferFunction(vtkRenderer* ren,
vtkVolume* vol,
int noOfComponents,
unsigned int component);
// Update noise texture (used to reduce rendering artifacts
......@@ -1088,10 +1085,10 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateInterpolationType(
return 0;
}
//----------------------------------------------------------------------------
int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateColorTransferFunction(
vtkRenderer* ren, vtkVolume* vol, int vtkNotUsed(noOfComponents),
unsigned int component)
//----------------------------------------------------------------------------
int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::
UpdateColorTransferFunction(vtkRenderer* ren, vtkVolume* vol,
unsigned int component)
{
// Volume property cannot be null.
vtkVolumeProperty* volumeProperty = vol->GetProperty();
......@@ -1152,9 +1149,9 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateInterpolationType(
}
//----------------------------------------------------------------------------
int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateOpacityTransferFunction(
vtkRenderer* ren, vtkVolume* vol, int vtkNotUsed(noOfComponents),
unsigned int component)
int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::
UpdateOpacityTransferFunction(vtkRenderer* ren, vtkVolume* vol,
unsigned int component)
{
if (!vol)
{
......@@ -1162,16 +1159,13 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateOpacityTransferFunction(
}
vtkVolumeProperty* volumeProperty = vol->GetProperty();
vtkPiecewiseFunction* scalarOpacity = 0;
if (!vol->GetProperty()->GetIndependentComponents())
{
scalarOpacity = volumeProperty->GetScalarOpacity(0);
}
else
{
scalarOpacity = volumeProperty->GetScalarOpacity(component);
}
// Transfer function table index based on whether independent / dependent
// components. If dependent, use the first scalar opacity transfer function
unsigned int lookupTableIndex = volumeProperty->GetIndependentComponents() ?
component : 0;
vtkPiecewiseFunction* scalarOpacity =
volumeProperty->GetScalarOpacity(lookupTableIndex);
if (scalarOpacity->GetSize() < 1)
{
......@@ -1189,9 +1183,7 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateOpacityTransferFunction(
scalarRange[i] = this->ScalarsRange[component][i];
}
int tableIndex = component < this->OpacityTables->GetNumberOfTables() ?
component : this->OpacityTables->GetNumberOfTables() - 1;
this->OpacityTables->GetTable(tableIndex)->Update(
this->OpacityTables->GetTable(lookupTableIndex)->Update(
scalarOpacity,this->Parent->BlendMode,
this->ActualSampleDistance,
scalarRange,
......@@ -1209,7 +1201,7 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateOpacityTransferFunction(
//----------------------------------------------------------------------------
int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::
UpdateGradientOpacityTransferFunction(vtkRenderer* ren, vtkVolume* vol,
int vtkNotUsed(noOfComponents), unsigned int component)
unsigned int component)
{
if (!vol)
{
......@@ -1218,25 +1210,21 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::
vtkVolumeProperty* volumeProperty = vol->GetProperty();
// Transfer function table index based on whether independent / dependent
// components. If dependent, use the first gradient opacity transfer function
unsigned int lookupTableIndex = volumeProperty->GetIndependentComponents() ?
component : 0;
// TODO Currently we expect the all of the tables will
// be initialized once and if at that time, the gradient
// opacity was not enabled then it is not used later.
if (!volumeProperty->HasGradientOpacity(component) ||
if (!volumeProperty->HasGradientOpacity(lookupTableIndex) ||
!this->GradientOpacityTables)
{
return 1;
}
vtkPiecewiseFunction* gradientOpacity = 0;
if (!vol->GetProperty()->GetIndependentComponents())
{
gradientOpacity = volumeProperty->GetGradientOpacity(0);
}
else
{
gradientOpacity = volumeProperty->GetGradientOpacity(component);
}
vtkPiecewiseFunction* gradientOpacity =
volumeProperty->GetGradientOpacity(lookupTableIndex);
if (gradientOpacity->GetSize() < 1)
{
......@@ -1254,14 +1242,11 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::
scalarRange[i] = this->ScalarsRange[component][i];
}
int tableIndex =
component < this->GradientOpacityTables->GetNumberOfTables() ?
component : this->GradientOpacityTables->GetNumberOfTables() - 1;
this->GradientOpacityTables->GetTable(tableIndex)->Update(
this->GradientOpacityTables->GetTable(lookupTableIndex)->Update(
gradientOpacity,
this->ActualSampleDistance,
scalarRange,
volumeProperty->GetScalarOpacityUnitDistance(),
volumeProperty->GetScalarOpacityUnitDistance(component),
#if GL_ES_VERSION_2_0 != 1
filterVal,
#else
......@@ -2908,26 +2893,19 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren,
{
for (int i = 0; i < noOfComponents; ++i)
{
this->Impl->UpdateOpacityTransferFunction(ren, vol, noOfComponents, i);
this->Impl->UpdateGradientOpacityTransferFunction(ren, vol,
noOfComponents, i);
this->Impl->UpdateColorTransferFunction(ren, vol, noOfComponents, i);
this->Impl->UpdateOpacityTransferFunction(ren, vol, i);
this->Impl->UpdateGradientOpacityTransferFunction(ren, vol, i);
this->Impl->UpdateColorTransferFunction(ren, vol, i);
}
}
else
{
if (noOfComponents == 2)
{
this->Impl->UpdateOpacityTransferFunction(ren, vol, noOfComponents, 1);
this->Impl->UpdateGradientOpacityTransferFunction(ren, vol,
noOfComponents, 1);
this->Impl->UpdateColorTransferFunction(ren, vol, noOfComponents, 0);
}
else if (noOfComponents == 4)
if (noOfComponents == 2 || noOfComponents == 4)
{
this->Impl->UpdateOpacityTransferFunction(ren, vol, noOfComponents, 3);
this->Impl->UpdateOpacityTransferFunction(ren, vol, noOfComponents - 1);
this->Impl->UpdateGradientOpacityTransferFunction(ren, vol,
noOfComponents, 3);
noOfComponents - 1);
this->Impl->UpdateColorTransferFunction(ren, vol, 0);
}
}
......
......@@ -370,7 +370,8 @@ namespace vtkvolume
gradientTableMap)
{
std::string shaderStr;
if (noOfComponents == 1 && vol->GetProperty()->HasGradientOpacity())
if (vol->GetProperty()->HasGradientOpacity() &&
(noOfComponents == 1 || !independentComponents))
{
shaderStr += std::string("\
\nuniform sampler2D in_gradientTransferFunc;\
......@@ -700,7 +701,8 @@ namespace vtkvolume
);
}
if (noOfComponents == 1 && volProperty->HasGradientOpacity())
if (volProperty->HasGradientOpacity() &&
(noOfComponents == 1 || !independentComponents))
{
shaderStr += std::string("\
\n if (gradient.w >= 0.0)\
......@@ -710,7 +712,7 @@ namespace vtkvolume
\n }"
);
}
else if (noOfComponents > 1 && independentComponents &&
else if (noOfComponents > 1 && independentComponents &&
volProperty->HasGradientOpacity())
{
shaderStr += std::string("\
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment