Commit 5e2432fb authored by David Gobbi's avatar David Gobbi

Make streaming optional for the 3D image mappers.

Previously, the default behavior of the 3D image mappers was to stream
the data through the pipeline, meaning that only the part of the input
image that was required to display one (possibly oblique) slice on the
screen was updated.  However, this resulted in the UPDATE_EXTENT changing
whenever a new slice was displayed, triggerring a pipeline update.

The new default behaviour is to set the UPDATE_EXTENT to the WHOLE_EXTENT,
so that the whole extent is updated on the first render, but no pipeline
execution occurs on subsequent renders (e.g. while slicing through the data)
unless the pipeline is modified.

The StreamingOn() method can be used to revert to the old behavior.

Change-Id: I76b31a2ae4b329885d755c2947b62f9a9474b88a
parent 280a78bf
......@@ -49,6 +49,8 @@ vtkImageActor::vtkImageActor()
mapper->SliceAtFocalPointOff();
mapper->SliceFacesCameraOff();
mapper->SetOrientationToZ();
// For backwards compabilitity, make Streaming the default behavior
mapper->StreamingOn();
}
//----------------------------------------------------------------------------
......
......@@ -42,6 +42,7 @@ vtkImageMapper3D::vtkImageMapper3D()
this->Threader = vtkMultiThreader::New();
this->NumberOfThreads = this->Threader->GetNumberOfThreads();
this->Streaming = 0;
this->Border = 0;
this->Background = 0;
......@@ -156,6 +157,7 @@ void vtkImageMapper3D::PrintSelf(ostream& os, vtkIndent indent)
os << indent << "Border: " << (this->Border ? "On\n" : "Off\n");
os << indent << "Background: " << (this->Background ? "On\n" : "Off\n");
os << indent << "NumberOfThreads: " << this->NumberOfThreads << "\n";
os << indent << "Streaming: " << (this->Streaming ? "On\n" : "Off\n");
}
//----------------------------------------------------------------------------
......
......@@ -119,6 +119,18 @@ public:
vtkSetClampMacro(NumberOfThreads, int, 1, VTK_MAX_THREADS);
vtkGetMacro(NumberOfThreads, int);
// Description:
// Turn on streaming, to pull the minimum amount of data from the input.
// Streaming decreases the memory required to display large images, since
// only one slice will be pulled through the input pipeline if only
// one slice is mapped to the screen. The default behavior is to pull
// the full 3D input extent through the input pipeline, but to do this
// only when the input data changes. The default behavior results in
// much faster follow-up renders when the input data is static.
vtkSetMacro(Streaming, int);
vtkGetMacro(Streaming, int);
vtkBooleanMacro(Streaming, int);
protected:
vtkImageMapper3D();
~vtkImageMapper3D();
......@@ -190,6 +202,7 @@ protected:
vtkScalarsToColors *DefaultLookupTable;
vtkMultiThreader *Threader;
int NumberOfThreads;
int Streaming;
// The slice.
vtkPlane *SlicePlane;
......
......@@ -221,12 +221,23 @@ int vtkImageSliceMapper::ProcessRequest(
return 1;
}
// set update extent to display extent
// set update extent
if(request->Has(vtkStreamingDemandDrivenPipeline::REQUEST_UPDATE_EXTENT()))
{
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),
this->DisplayExtent, 6);
if (this->Streaming)
{
// only update the display extent if streaming is on
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),
this->DisplayExtent, 6);
}
else
{
int ext[6];
inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), ext);
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), ext, 6);
}
return 1;
}
......
......@@ -69,6 +69,8 @@ int TestImageResliceMapperOrient3D(int argc, char* argv[])
imageMapper->SetInputConnection(reader->GetOutputPort());
imageMapper->SliceAtFocalPointOn();
imageMapper->SliceFacesCameraOn();
// exercise the Streaming options, for better coverage
imageMapper->StreamingOn();
double *bounds = imageMapper->GetBounds();
double point[3];
......
......@@ -398,10 +398,21 @@ int vtkImageResliceMapper::ProcessRequest(
if(request->Has(vtkStreamingDemandDrivenPipeline::REQUEST_UPDATE_EXTENT()))
{
// delegate request to vtkImageReslice (generally not a good thing to
// do, but I'm familiar with the vtkImageReslice code that gets called).
return this->ImageReslice->ProcessRequest(
request, inputVector, outputVector);
if (this->Streaming)
{
// delegate request to vtkImageReslice (generally not a good thing to
// do, but I'm familiar with the vtkImageReslice code that gets called).
return this->ImageReslice->ProcessRequest(
request, inputVector, outputVector);
}
else
{
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
int ext[6];
inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), ext);
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), ext, 6);
}
return 1;
}
if(request->Has(vtkStreamingDemandDrivenPipeline::REQUEST_DATA()))
......
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