Commit 56155d23 authored by Sankhesh Jhaveri's avatar Sankhesh Jhaveri Committed by Kitware Robot

Merge topic 'fix_interactive_volume_issues'

f95de304 Updated test to new ivar to turn off auto adjust sample distance
20b2a4a9 Added alternate baseline with jitter for GL2
5df033ab Fixed ReductionFactor not initialized that was causing tests to hangup
a5890e69 Fixed styles and added notes
5282543e Merge branch 'paraview_volume_issue' into fix_interactive_volume_issues
938c8790 Fixed issues with interactive volume rendering
9b2883aa Improve documentation of new variable in vtkSmartVolumeMapper
40ec94e5 Interactively adjust sample distance for vtkSmartVolumeMapper
...
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Reviewed-by: Sankhesh Jhaveri's avatarSankhesh Jhaveri <sankhesh.jhaveri@kitware.com>
Merge-request: !430
parents 2964c66a f95de304
......@@ -23,6 +23,7 @@ set (GenericVolumeCxxTests
TestGPURayCastNearestDataTypesMIP.cxx
TestGPURayCastPerspectiveParallel.cxx
TestGPURayCastVolumeUpdate.cxx
TestGPUVolumeRayCastMapper.cxx
TestMinIntensityRendering.cxx
TestProjectedTetrahedra.cxx
TestSmartVolumeMapper.cxx
......
......@@ -40,11 +40,11 @@ int TestGPURayCastAdditive(int argc,
cout << "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)" << endl;
// Create a spherical implicit function.
vtkSphere *shape=vtkSphere::New();
vtkSphere *shape = vtkSphere::New();
shape->SetRadius(0.1);
shape->SetCenter(0.0,0.0,0.0);
vtkSampleFunction *source=vtkSampleFunction::New();
vtkSampleFunction *source = vtkSampleFunction::New();
source->SetImplicitFunction(shape);
shape->Delete();
source->SetOutputScalarTypeToDouble();
......@@ -56,48 +56,53 @@ int TestGPURayCastAdditive(int argc,
source->Update();
vtkDataArray *a=source->GetOutput()->GetPointData()->GetScalars("values");
vtkDataArray *a = source->GetOutput()->GetPointData()->GetScalars("values");
double range[2];
a->GetRange(range);
vtkImageShiftScale *t=vtkImageShiftScale::New();
vtkImageShiftScale *t = vtkImageShiftScale::New();
t->SetInputConnection(source->GetOutputPort());
source->Delete();
t->SetShift(-range[0]);
double magnitude=range[1]-range[0];
if(magnitude==0.0)
double magnitude = range[1]-range[0];
if(magnitude == 0.0)
{
magnitude=1.0;
magnitude = 1.0;
}
t->SetScale(255.0/magnitude);
t->SetOutputScalarTypeToUnsignedChar();
t->Update();
vtkRenderWindow *renWin=vtkRenderWindow::New();
vtkRenderer *ren1=vtkRenderer::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
vtkRenderer *ren1 = vtkRenderer::New();
ren1->SetBackground(0.1,0.4,0.2);
renWin->AddRenderer(ren1);
ren1->Delete();
renWin->SetSize(301,300); // intentional odd and NPOT width/height
vtkRenderWindowInteractor *iren=vtkRenderWindowInteractor::New();
// intentional odd and NPOT width/height
renWin->SetSize(301,300);
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
renWin->Delete();
renWin->Render(); // make sure we have an OpenGL context.
// make sure we have an OpenGL context.
renWin->Render();
vtkGPUVolumeRayCastMapper *volumeMapper;
vtkVolumeProperty *volumeProperty;
vtkVolume *volume;
volumeMapper=vtkGPUVolumeRayCastMapper::New();
volumeMapper = vtkGPUVolumeRayCastMapper::New();
volumeMapper->SetAutoAdjustSampleDistances(0);
volumeMapper->SetSampleDistance(0.2);
volumeMapper->SetBlendModeToComposite(); // composite first
volumeMapper->SetInputConnection(
t->GetOutputPort());
volumeProperty=vtkVolumeProperty::New();
volumeProperty = vtkVolumeProperty::New();
volumeProperty->ShadeOff();
volumeProperty->SetInterpolationType(VTK_LINEAR_INTERPOLATION);
......@@ -114,19 +119,19 @@ int TestGPURayCastAdditive(int argc,
compositeOpacity->AddPoint(255.0,0.0);
volumeProperty->SetScalarOpacity(compositeOpacity); // composite first.
vtkColorTransferFunction *color=vtkColorTransferFunction::New();
vtkColorTransferFunction *color = vtkColorTransferFunction::New();
color->AddRGBPoint(0.0 ,0.0,0.0,1.0);
color->AddRGBPoint(40.0 ,1.0,0.0,0.0);
color->AddRGBPoint(255.0,1.0,1.0,1.0);
volumeProperty->SetColor(color);
color->Delete();
volume=vtkVolume::New();
volume = vtkVolume::New();
volume->SetMapper(volumeMapper);
volume->SetProperty(volumeProperty);
ren1->AddViewProp(volume);
int valid=volumeMapper->IsRenderSupported(renWin,volumeProperty);
int valid = volumeMapper->IsRenderSupported(renWin,volumeProperty);
int retVal;
if(valid)
......@@ -149,7 +154,7 @@ int TestGPURayCastAdditive(int argc,
}
else
{
retVal=vtkTesting::PASSED;
retVal = vtkTesting::PASSED;
cout << "Required extensions not supported." << endl;
}
......
......@@ -19,17 +19,14 @@
#include "vtkImageData.h"
#include "vtkNew.h"
#include "vtkPiecewiseFunction.h"
#include "vtkRTAnalyticSource.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkRTAnalyticSource.h"
#include "vtkTimerLog.h"
#include "vtkVolume.h"
#include "vtkVolumeProperty.h"
#include "vtkXMLImageDataReader.h"
#include "vtkRegressionTestImage.h"
#include "vtkTestUtilities.h"
//----------------------------------------------------------------------------
int TestGPURayCastMapperBenchmark(int argc, char* argv[])
......
This diff is collapsed.
......@@ -627,12 +627,23 @@ int TestSmartVolumeMapperWindowLevel(int argc,
vtkNew<vtkSmartVolumeMapper> mapper1;
mapper1->SetInputConnection(reader->GetOutputPort());
mapper1->SetRequestedRenderModeToDefault();
vtkNew<vtkSmartVolumeMapper> mapper2;
mapper2->SetInputConnection(reader->GetOutputPort());
vtkNew<vtkSmartVolumeMapper> mapper3;
mapper3->SetInputConnection(reader->GetOutputPort());
mapper3->SetRequestedRenderModeToRayCast();
#ifdef VTK_OPENGL2
mapper1->SetAutoAdjustSampleDistances(0);
mapper1->SetInteractiveAdjustSampleDistances(0);
mapper2->SetAutoAdjustSampleDistances(0);
mapper2->SetInteractiveAdjustSampleDistances(0);
mapper3->SetAutoAdjustSampleDistances(0);
mapper3->SetInteractiveAdjustSampleDistances(0);
#endif
vtkNew<vtkColorTransferFunction> ctf;
ctf->AddHSVPoint(1.0, 0.65, 1.0, 1.0);
ctf->AddHSVPoint(256, 0.95, 0.098, 1.0);
......
......@@ -1901,11 +1901,11 @@ void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateSamplingDistance(
// by 1/reduceFactor.
this->ActualSampleDistance = static_cast<float>(minWorldSpacing);
if (this->Parent->ReductionFactor < 1.0)
if (this->Parent->ReductionFactor < 1.0 &&
this->Parent->ReductionFactor != 0.0)
{
// 0.5 is done to increase the impact factor
this->ActualSampleDistance /=
static_cast<GLfloat>(this->Parent->ReductionFactor * 0.5);
static_cast<GLfloat>(this->Parent->ReductionFactor);
}
}
}
......@@ -2000,6 +2000,7 @@ vtkOpenGLGPUVolumeRayCastMapper::vtkOpenGLGPUVolumeRayCastMapper() :
vtkGPUVolumeRayCastMapper()
{
this->Impl = new vtkInternal(this);
this->ReductionFactor = 1.0;
}
///
......@@ -2464,6 +2465,9 @@ void vtkOpenGLGPUVolumeRayCastMapper::ComputeReductionFactor(
timeToDraw = this->BigTimeToDraw;
}
// This should be the case when rendering the volume very first time
// 10.0 is an arbitrary value chosen which happen to a large number
// in this context
if ( timeToDraw == 0.0 )
{
timeToDraw = 10.0;
......@@ -2472,32 +2476,29 @@ void vtkOpenGLGPUVolumeRayCastMapper::ComputeReductionFactor(
double fullTime = timeToDraw / this->ReductionFactor;
double newFactor = allocatedTime / fullTime;
if ( oldFactor == 1.0 ||
newFactor / oldFactor > 1.3 ||
newFactor / oldFactor < .95 )
{
this->ReductionFactor = (newFactor+oldFactor)/2.0;
// Compute average factor
this->ReductionFactor = (newFactor+oldFactor)/2.0;
this->ReductionFactor = (this->ReductionFactor > 5.0) ? (1.00) :
(this->ReductionFactor);
this->ReductionFactor = (this->ReductionFactor > 1.0) ? (0.99) :
(this->ReductionFactor);
this->ReductionFactor = (this->ReductionFactor < 0.1) ? (0.10) :
(this->ReductionFactor);
// Discretize reduction factor so that it doesn't cause
// visual artifacts when used to reduce the sample distance
this->ReductionFactor = (this->ReductionFactor > 1.0) ? 1.0 :
(this->ReductionFactor);
this->ReductionFactor = (this->ReductionFactor < 1.0) ? (0.5) :
(this->ReductionFactor);
this->ReductionFactor = (this->ReductionFactor < 0.5) ? (0.25) :
(this->ReductionFactor);
this->ReductionFactor = (this->ReductionFactor < 0.25) ? (0.1) :
(this->ReductionFactor);
if ( 1.0/this->ReductionFactor > this->MaximumImageSampleDistance )
{
this->ReductionFactor = 1.0 / this->MaximumImageSampleDistance;
}
if ( 1.0/this->ReductionFactor < this->MinimumImageSampleDistance )
{
this->ReductionFactor = 1.0 / this->MinimumImageSampleDistance;
}
// Clamp it
if ( 1.0/this->ReductionFactor > this->MaximumImageSampleDistance )
{
this->ReductionFactor = 1.0 / this->MaximumImageSampleDistance;
}
if ( 1.0/this->ReductionFactor < this->MinimumImageSampleDistance )
{
this->ReductionFactor = 1.0 / this->MinimumImageSampleDistance;
}
}
else
{
this->ReductionFactor = 1.0;
}
}
......
......@@ -52,9 +52,17 @@ vtkSmartVolumeMapper::vtkSmartVolumeMapper()
this->LowResGPUNecessary = 0;
this->InterpolationMode=VTK_RESLICE_CUBIC;
// If the render window has a desired update greater than or equal to the
// interactive update rate, we apply certain optimizations to ensure that the
// rendering is interactive.
this->InteractiveUpdateRate = 1.0;
// Enable checking whether the render is interactive and use the appropriate
// sample distance for rendering
this->InteractiveAdjustSampleDistances = 1;
// Initial sample distance
this->AutoAdjustSampleDistances = 1;
this->SampleDistance = 1.0;
this->SampleDistance = -1.0;
// Create all the mappers we might need
this->RayCastMapper = vtkFixedPointVolumeRayCastMapper::New();
......@@ -161,6 +169,17 @@ void vtkSmartVolumeMapper::Render( vtkRenderer *ren, vtkVolume *vol )
switch ( this->CurrentRenderMode )
{
case vtkSmartVolumeMapper::RayCastRenderMode:
if (this->InteractiveAdjustSampleDistances)
{
this->RayCastMapper->SetAutoAdjustSampleDistances(
ren->GetRenderWindow()->GetDesiredUpdateRate()>=
this->InteractiveUpdateRate);
}
else
{
this->RayCastMapper->SetAutoAdjustSampleDistances(
this->AutoAdjustSampleDistances);
}
this->RayCastMapper->Render(ren,vol);
break;
case vtkSmartVolumeMapper::GPURenderMode:
......@@ -172,6 +191,17 @@ void vtkSmartVolumeMapper::Render( vtkRenderer *ren, vtkVolume *vol )
{
usedMapper=this->GPUMapper;
}
if (this->InteractiveAdjustSampleDistances)
{
usedMapper->SetAutoAdjustSampleDistances(
ren->GetRenderWindow()->GetDesiredUpdateRate()>=
this->InteractiveUpdateRate);
}
else
{
usedMapper->SetAutoAdjustSampleDistances(
this->AutoAdjustSampleDistances);
}
usedMapper->Render(ren, vol);
break;
case vtkSmartVolumeMapper::InvalidRenderMode:
......@@ -285,6 +315,15 @@ void vtkSmartVolumeMapper::ComputeRenderMode(vtkRenderer *ren, vtkVolume *vol)
double spacing[3];
this->GetInput()->GetSpacing(spacing);
// Compute the sample distance based on dataset spacing.
// It is assumed that a negative SampleDistance means the user would like to
// compute volume mapper sample distance based on data spacing.
if (this->SampleDistance < 0)
{
this->SampleDistance =
static_cast<float>((spacing[0] + spacing[1] + spacing[2]) / 6.0);
}
vtkRenderWindow *win=ren->GetRenderWindow();
switch ( this->RequestedRenderMode )
......@@ -350,8 +389,6 @@ void vtkSmartVolumeMapper::ComputeRenderMode(vtkRenderer *ren, vtkVolume *vol)
this->RayCastMapper->SetBlendMode( this->GetBlendMode() );
this->RayCastMapper->SetFinalColorWindow(this->FinalColorWindow);
this->RayCastMapper->SetFinalColorLevel(this->FinalColorLevel);
this->RayCastMapper->SetAutoAdjustSampleDistances(
this->AutoAdjustSampleDistances);
this->RayCastMapper->SetSampleDistance(this->SampleDistance);
break;
......@@ -368,8 +405,6 @@ void vtkSmartVolumeMapper::ComputeRenderMode(vtkRenderer *ren, vtkVolume *vol)
this->GPUMapper->SetScalarMode(this->GetScalarMode());
this->GPUMapper->SetMaxMemoryInBytes(this->MaxMemoryInBytes);
this->GPUMapper->SetMaxMemoryFraction(this->MaxMemoryFraction);
this->GPUMapper->SetSampleDistance(
static_cast<float>((spacing[0] + spacing[1] + spacing[2] ) / 6.0) );
this->ConnectMapperInput(this->GPUMapper);
this->GPUMapper->SetClippingPlanes(this->GetClippingPlanes());
this->GPUMapper->SetCropping(this->GetCropping());
......@@ -380,8 +415,6 @@ void vtkSmartVolumeMapper::ComputeRenderMode(vtkRenderer *ren, vtkVolume *vol)
this->GPUMapper->SetBlendMode( this->GetBlendMode() );
this->GPUMapper->SetFinalColorWindow(this->FinalColorWindow);
this->GPUMapper->SetFinalColorLevel(this->FinalColorLevel);
this->GPUMapper->SetAutoAdjustSampleDistances(
this->AutoAdjustSampleDistances);
this->GPUMapper->SetSampleDistance(this->SampleDistance);
// Make the window current because we need the OpenGL context
......@@ -405,8 +438,6 @@ void vtkSmartVolumeMapper::ComputeRenderMode(vtkRenderer *ren, vtkVolume *vol)
this->GPULowResMapper->SetMaxMemoryInBytes(this->MaxMemoryInBytes);
this->GPULowResMapper->SetMaxMemoryFraction(this->MaxMemoryFraction);
this->GPULowResMapper->SetSampleDistance(
static_cast<float>((spacing[0] + spacing[1] + spacing[2] ) / 6.0) );
this->GPULowResMapper->SetInputConnection(
this->GPUResampleFilter->GetOutputPort());
......@@ -419,8 +450,6 @@ void vtkSmartVolumeMapper::ComputeRenderMode(vtkRenderer *ren, vtkVolume *vol)
this->GPULowResMapper->SetBlendMode( this->GetBlendMode() );
this->GPULowResMapper->SetFinalColorWindow(this->FinalColorWindow);
this->GPULowResMapper->SetFinalColorLevel(this->FinalColorLevel);
this->GPULowResMapper->SetAutoAdjustSampleDistances(
this->AutoAdjustSampleDistances);
this->GPULowResMapper->SetSampleDistance(this->SampleDistance);
}
else
......@@ -626,6 +655,9 @@ void vtkSmartVolumeMapper::PrintSelf(ostream& os, vtkIndent indent)
os << "FinalColorWindow: " << this->FinalColorWindow << endl;
os << "FinalColorLevel: " << this->FinalColorLevel << endl;
os << "RequestedRenderMode: " << this->RequestedRenderMode << endl;
os << "InteractiveUpdateRate: " << this->InteractiveUpdateRate << endl;
os << "InteractiveAdjustSampleDistances: " <<
this->InteractiveAdjustSampleDistances << endl;
os << "InterpolationMode: " << this->InterpolationMode << endl;
os << "MaxMemoryInBytes:" << this->MaxMemoryInBytes << endl;
os << "MaxMemoryFraction:" << this->MaxMemoryFraction << endl;
......
......@@ -200,10 +200,37 @@ public:
double viewUp[3] );
// Description:
// If AutoAdjustSampleDistances is on, the the ImageSampleDistance
// If the DesiredUpdateRate of the vtkRenderWindow that caused the Render
// falls at or above this rate, the render is considered interactive and
// the mapper may be adjusted (depending on the render mode).
// Initial value is 1.0.
vtkSetClampMacro( InteractiveUpdateRate, double, 1.0e-10, 1.0e10 );
// Description:
// Get the update rate at or above which this is considered an
// interactive render.
// Initial value is 1.0.
vtkGetMacro( InteractiveUpdateRate, double );
// Description:
// If the InteractiveAdjustSampleDistances flag is enabled,
// vtkSmartVolumeMapper interactively sets and resets the
// AutoAdjustSampleDistances flag on the internal volume mapper. This flag
// along with InteractiveUpdateRate is useful to adjust volume mapper sample
// distance based on whether the render is interactive or still.
// By default, InteractiveAdjustSampleDistances is enabled.
vtkSetClampMacro( InteractiveAdjustSampleDistances, int, 0, 1);
vtkGetMacro( InteractiveAdjustSampleDistances, int);
vtkBooleanMacro( InteractiveAdjustSampleDistances, int);
// Description:
// If AutoAdjustSampleDistances is on, the ImageSampleDistance
// will be varied to achieve the allocated render time of this
// prop (controlled by the desired update rate and any culling in
// use).
// Note that, this flag is ignored when InteractiveAdjustSampleDistances is
// enabled. To explicitly set and use this flag, one must disable
// InteractiveAdjustSampleDistances.
vtkSetClampMacro( AutoAdjustSampleDistances, int, 0, 1 );
vtkGetMacro( AutoAdjustSampleDistances, int );
vtkBooleanMacro( AutoAdjustSampleDistances, int );
......@@ -212,7 +239,8 @@ public:
// Set/Get the distance between samples used for rendering
// when AutoAdjustSampleDistances is off, or when this mapper
// has more than 1 second allocated to it for rendering.
// Initial value is 1.0.
// If SampleDistance is negative, it will be computed based on the dataset
// spacing. Initial value is -1.0.
vtkSetMacro( SampleDistance, float );
vtkGetMacro( SampleDistance, float );
......@@ -298,8 +326,23 @@ protected:
// The distance between sample points along the ray
float SampleDistance;
// Set whether or not the sample distance should be automatically calculated
// within the internal volume mapper
int AutoAdjustSampleDistances;
// If the DesiredUpdateRate of the vtkRenderWindow causing the Render is at
// or above this value, the render is considered interactive. Otherwise it is
// considered still.
double InteractiveUpdateRate;
// If the InteractiveAdjustSampleDistances flag is enabled,
// vtkSmartVolumeMapper interactively sets and resets the
// AutoAdjustSampleDistances flag on the internal volume mapper. This flag
// along with InteractiveUpdateRate is useful to adjust volume mapper sample
// distance based on whether the render is interactive or still.
int InteractiveAdjustSampleDistances;
private:
vtkSmartVolumeMapper(const vtkSmartVolumeMapper&); // Not implemented.
void operator=(const vtkSmartVolumeMapper&); // Not implemented.
......
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