Commit d309ca87 authored by Max Smolens's avatar Max Smolens

Consider whether volume transform preserves orientation

This commit changes the OpenGL2 GPU volume renderer to consider whether the
volume transform preserves orientation when orienting polygons. Before, nothing
was rendered when the transform didn't preserve orientation, presumably due to
backface culling.

The legacy OpenGL volume renderer handles this case.
parent 1cb5a963
Pipeline #24719 passed with stage
......@@ -22,6 +22,7 @@ set (GenericVolumeCxxTests
TestGPURayCastMIPToComposite.cxx
TestGPURayCastNearestDataTypesMIP.cxx
TestGPURayCastPerspectiveParallel.cxx
TestGPURayCastVolumeOrientation.cxx
TestGPURayCastVolumeUpdate.cxx
TestGPUVolumeRayCastMapper.cxx
TestMinIntensityRendering.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestGPURayCastVolumeOrientation.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 test volume renders a dataset that has a transform that
// doesn't preserve orientation.
#include <vtkColorTransferFunction.h>
#include <vtkGPUVolumeRayCastMapper.h>
#include <vtkImageData.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkNew.h>
#include <vtkOutlineFilter.h>
#include <vtkPiecewiseFunction.h>
#include <vtkPolyDataMapper.h>
#include <vtkRegressionTestImage.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <vtkTestUtilities.h>
#include <vtkVolumeProperty.h>
#include <vtkXMLImageDataReader.h>
int TestGPURayCastVolumeOrientation(int argc, char *argv[])
{
cout << "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)" << endl;
double scalarRange[2];
vtkNew<vtkActor> outlineActor;
vtkNew<vtkPolyDataMapper> outlineMapper;
vtkNew<vtkGPUVolumeRayCastMapper> volumeMapper;
vtkNew<vtkXMLImageDataReader> reader;
const char* volumeFile = vtkTestUtilities::ExpandDataFileName(
argc, argv, "Data/vase_1comp.vti");
reader->SetFileName(volumeFile);
volumeMapper->SetInputConnection(reader->GetOutputPort());
delete[] volumeFile;
// Add outline filter
vtkNew<vtkOutlineFilter> outlineFilter;
outlineFilter->SetInputConnection(reader->GetOutputPort());
outlineMapper->SetInputConnection(outlineFilter->GetOutputPort());
outlineActor->SetMapper(outlineMapper.GetPointer());
volumeMapper->GetInput()->GetScalarRange(scalarRange);
volumeMapper->SetSampleDistance(0.1);
volumeMapper->SetAutoAdjustSampleDistances(0);
volumeMapper->SetBlendModeToComposite();
vtkNew<vtkRenderWindow> renWin;
renWin->SetMultiSamples(0);
renWin->SetSize(400, 400);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin.GetPointer());
vtkNew<vtkInteractorStyleTrackballCamera> style;
iren->SetInteractorStyle(style.GetPointer());
renWin->Render(); // make sure we have an OpenGL context.
vtkNew<vtkRenderer> ren;
ren->SetBackground(0.2, 0.2, 0.5);
renWin->AddRenderer(ren.GetPointer());
vtkNew<vtkPiecewiseFunction> scalarOpacity;
scalarOpacity->AddPoint(50, 0.0);
scalarOpacity->AddPoint(75, 1.0);
vtkNew<vtkVolumeProperty> volumeProperty;
volumeProperty->ShadeOn();
volumeProperty->SetInterpolationType(VTK_LINEAR_INTERPOLATION);
volumeProperty->SetScalarOpacity(scalarOpacity.GetPointer());
vtkNew<vtkColorTransferFunction> colorTransferFunction;
colorTransferFunction->RemoveAllPoints();
colorTransferFunction->AddRGBPoint(scalarRange[0], 0.6, 0.4, 0.1);
volumeProperty->SetColor(colorTransferFunction.GetPointer());
vtkNew<vtkVolume> volume;
volume->SetMapper(volumeMapper.GetPointer());
volume->SetProperty(volumeProperty.GetPointer());
// Set a transform that doesn't preserve orientation
volume->SetScale(1.0, -1.0, 1.0);
outlineActor->SetScale(1.0, -1.0, 1.0);
ren->AddViewProp(volume.GetPointer());
ren->AddActor(outlineActor.GetPointer());
ren->ResetCamera();
int valid = volumeMapper->IsRenderSupported(renWin.GetPointer(),
volumeProperty.GetPointer());
int retVal;
if (valid)
{
renWin->Render();
iren->Initialize();
retVal = vtkRegressionTestImage(renWin.GetPointer());
if (retVal == vtkRegressionTester::DO_INTERACTOR)
{
iren->Start();
}
}
else
{
retVal = vtkTesting::PASSED;
cout << "Required extensions not supported" << endl;
}
return !retVal;
}
......@@ -1803,9 +1803,24 @@ void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::RenderVolumeGeometry(
vtkIdType npts;
vtkIdType *pts;
// See if the volume transform is orientation-preserving
// and orient polygons accordingly
vtkMatrix4x4* volMat = vol->GetMatrix();
double det = vtkMath::Determinant3x3(
volMat->GetElement(0, 0), volMat->GetElement(0, 1), volMat->GetElement(0, 2),
volMat->GetElement(1, 0), volMat->GetElement(1, 1), volMat->GetElement(1, 2),
volMat->GetElement(2, 0), volMat->GetElement(2, 1), volMat->GetElement(2, 2));
bool preservesOrientation = det > 0.0;
const vtkIdType indexMap[3] = {
preservesOrientation ? 0 : 2,
1,
preservesOrientation ? 2 : 0
};
while(cells->GetNextCell(npts, pts))
{
polys->InsertNextTuple3(pts[0], pts[1], pts[2]);
polys->InsertNextTuple3(pts[indexMap[0]], pts[indexMap[1]], pts[indexMap[2]]);
}
// Dispose any previously created buffers
......
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