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.
 
 
 
 
 
 

138 lines
4.9 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkMemoryLimitImageDataStreamer.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 "vtkMemoryLimitImageDataStreamer.h"
#include "vtkAlgorithmOutput.h"
#include "vtkCommand.h"
#include "vtkExtentTranslator.h"
#include "vtkImageData.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPipelineSize.h"
#include "vtkStreamingDemandDrivenPipeline.h"
vtkCxxRevisionMacro(vtkMemoryLimitImageDataStreamer, "$Revision: 1.12 $");
vtkStandardNewMacro(vtkMemoryLimitImageDataStreamer);
//----------------------------------------------------------------------------
vtkMemoryLimitImageDataStreamer::vtkMemoryLimitImageDataStreamer()
{
// Set a default memory limit of 50 Megabytes
this->MemoryLimit = 50000;
}
//----------------------------------------------------------------------------
void vtkMemoryLimitImageDataStreamer::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "MemoryLimit (in kb): " << this->MemoryLimit << endl;
}
//----------------------------------------------------------------------------
int
vtkMemoryLimitImageDataStreamer
::ProcessRequest(vtkInformation* request,
vtkInformationVector** inputVector,
vtkInformationVector* outputVector)
{
if(request->Has(vtkStreamingDemandDrivenPipeline::REQUEST_UPDATE_EXTENT()))
{
if (this->CurrentDivision == 0)
{
// we must set the extent on the input
vtkInformation* outInfo = outputVector->GetInformationObject(0);
// get the requested update extent
int outExt[6];
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), outExt);
vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
vtkImageData *input =
vtkImageData::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkExtentTranslator *translator = this->GetExtentTranslator();
translator->SetWholeExtent(outExt);
vtkPipelineSize *sizer = vtkPipelineSize::New();
this->NumberOfStreamDivisions = 1;
unsigned long oldSize, size = 0;
float ratio;
translator->SetPiece(0);
// watch for the limiting case where the size is the maximum size
// represented by an unsigned long. In that case we do not want to do
// the ratio test. We actual test for size < 0.5 of the max unsigned
// long which would indicate that oldSize is about at max unsigned
// long.
unsigned long maxSize;
maxSize = (((unsigned long)0x1) << (8*sizeof(unsigned long) - 1));
// we also have to watch how many pieces we are creating. Since
// NumberOfStreamDivisions is an int, it cannot be more that say 2^31
// (which is a bit much anyhow) so we also stop if the number of pieces
// is too large.
int count = 0;
// double the number of pieces until the size fits in memory
// or the reduction in size falls to 20%
do
{
oldSize = size;
translator->SetNumberOfPieces(this->NumberOfStreamDivisions);
translator->PieceToExtentByPoints();
int inExt[6];
translator->GetExtent(inExt);
// set the update extent
inInfo->Set(
vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), inExt, 6);
// then propagate it
vtkAlgorithm *alg = input->GetProducerPort()->GetProducer();
int index = input->GetProducerPort()->GetIndex();
vtkStreamingDemandDrivenPipeline *exec =
vtkStreamingDemandDrivenPipeline::SafeDownCast(alg->GetExecutive());
exec->PropagateUpdateExtent(index);
size = sizer->GetEstimatedSize(this,0,0);
// watch for the first time through
if (!oldSize)
{
ratio = 0.5;
}
// otherwise the normal ratio calculation
else
{
ratio = size/(float)oldSize;
}
this->NumberOfStreamDivisions = this->NumberOfStreamDivisions*2;
count++;
}
while (size > this->MemoryLimit &&
(size < maxSize && ratio < 0.8) && count < 29);
// undo the last *2
this->NumberOfStreamDivisions = this->NumberOfStreamDivisions/2;
sizer->Delete();
}
return
this->Superclass::ProcessRequest(request, inputVector, outputVector);
}
return this->Superclass::ProcessRequest(request, inputVector, outputVector);
}