Commit 395a161e authored by Utkarsh Ayachit's avatar Utkarsh Ayachit

Added infrastructure for AMR streaming.

vtkAMRVolumeRepresentation can now stream data. Client requests block at a time
and updates it. Still a work in progress.
parent 9c827d39
......@@ -15,19 +15,24 @@
#include "vtkAMRVolumeRepresentation.h"
#include "vtkAlgorithmOutput.h"
#include "vtkAMRResampleFilter.h"
#include "vtkCommand.h"
#include "vtkAMRVolumeMapper.h"
#include "vtkOverlappingAMR.h"
#include "vtkCompositeDataPipeline.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMath.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkOverlappingAMR.h"
#include "vtkPVCacheKeeper.h"
#include "vtkPVLODVolume.h"
#include "vtkPVRenderView.h"
#include "vtkRenderer.h"
#include "vtkSmartPointer.h"
#include "vtkSmartVolumeMapper.h"
#include "vtkVolumeProperty.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkImageData.h"
#include <map>
#include <string>
......@@ -36,10 +41,10 @@ vtkStandardNewMacro(vtkAMRVolumeRepresentation);
//----------------------------------------------------------------------------
vtkAMRVolumeRepresentation::vtkAMRVolumeRepresentation()
{
this->RequestedRenderMode = 0; // Use Smart Mode
this->RequestedRenderMode = 0; //vtkAMRVolumeMapper::DefaultRenderMode; // Use Smart Mode
this->RequestedResamplingMode = 0; // Frustrum Mode
this->VolumeMapper = vtkAMRVolumeMapper::New();
this->VolumeMapper->SetUseDefaultThreading(true);
this->VolumeMapper = vtkSmartVolumeMapper::New();
//this->VolumeMapper->SetUseDefaultThreading(true);
this->Property = vtkVolumeProperty::New();
this->Actor = vtkPVLODVolume::New();
......@@ -53,6 +58,10 @@ vtkAMRVolumeRepresentation::vtkAMRVolumeRepresentation()
this->CacheKeeper->SetInputData(this->Cache);
this->FreezeFocalPoint = false;
vtkMath::UninitializeBounds(this->DataBounds);
this->StreamingBlockId = 0;
this->StreamingCapableSource = false;
}
//----------------------------------------------------------------------------
......@@ -84,15 +93,53 @@ vtkAMRVolumeRepresentation::RequestUpdateExtent(vtkInformation* request,
vtkInformationVector* outputVector)
{
this->Superclass::RequestUpdateExtent(request, inputVector, outputVector);
// If this->StreamingCapableSource is true, i.e. input is streaming capable
// and streaming is enabled, the update request is always "qualified". i.e. we
// only request a particular block from the input. The block is passed on by
// the view during streaming updates. Default behavior is to just request the
// 0th block.
if (this->StreamingCapableSource)
{
for (int cc=0; cc < this->GetNumberOfInputPorts(); cc++)
{
for (int kk=0; kk < inputVector[cc]->GetNumberOfInformationObjects(); kk++)
{
vtkInformation* info = inputVector[cc]->GetInformationObject(kk);
info->Set(vtkCompositeDataPipeline::LOAD_REQUESTED_BLOCKS(), 1);
int block = static_cast<int>(this->StreamingBlockId);
info->Set(vtkCompositeDataPipeline::UPDATE_COMPOSITE_INDICES(),
&block, 1);
cout << "vtkAMRVolumeRepresentation::RequestUpdateExtent "
<< block << endl;
}
}
}
return 1;
}
//----------------------------------------------------------------------------
int
vtkAMRVolumeRepresentation::RequestInformation(vtkInformation* request,
vtkInformationVector** inputVector,
vtkInformationVector* outputVector)
{
this->Superclass::RequestInformation(request, inputVector, outputVector);
if (!this->Superclass::RequestInformation(request, inputVector, outputVector))
{
return 0;
}
// Determine if the input is streaming capable.
this->StreamingCapableSource = false;
if (inputVector[0]->GetNumberOfInformationObjects() == 1)
{
vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
if (inInfo->Has(vtkCompositeDataPipeline::COMPOSITE_DATA_META_DATA()) &&
vtkPVView::GetEnableStreaming())
{
this->StreamingCapableSource = true;
}
}
return 1;
}
......@@ -112,18 +159,53 @@ int vtkAMRVolumeRepresentation::ProcessViewRequest(
// At the same time, the image data is not the data being delivered
// anywhere, so we don't really report it to the view's storage.
// vtkPVRenderView::SetPiece(inInfo, this, this->Cache);
vtkPVRenderView::SetPiece(inInfo, this,
this->CacheKeeper->GetOutputDataObject(0));
outInfo->Set(vtkPVRenderView::NEED_ORDERED_COMPOSITING(), 1);
vtkPVRenderView::SetGeometryBounds(inInfo, this->DataBounds);
vtkPVRenderView::SetStreamable(inInfo, this, this->StreamingCapableSource);
}
else if (request_type == vtkPVView::REQUEST_RENDER())
{
this->UpdateMapperParameters();
vtkAlgorithmOutput* producerPort = vtkPVRenderView::GetPieceProducer(inInfo, this);
if (producerPort)
{
this->VolumeMapper->SetInputConnection(producerPort);
vtkOverlappingAMR* amr = vtkOverlappingAMR::SafeDownCast(
producerPort->GetProducer()->GetOutputDataObject(0));
if (amr)
{
cout << "AMR Being Rendering -----" << endl;
for (unsigned int cc=0; cc < amr->GetNumberOfLevels(); cc++)
{
for (unsigned int kk=0; kk < amr->GetNumberOfDataSets(cc); kk++)
{
cout << cc <<", " << kk << " = " << amr->GetDataSet(cc, kk) << endl;
}
}
double bounds[6];
amr->GetBounds(bounds);
vtkNew<vtkAMRResampleFilter> resampler;
resampler->SetNumberOfSamples(40, 40, 40);
resampler->SetDemandDrivenMode(0);
resampler->SetMin(bounds[0], bounds[2], bounds[4]);
resampler->SetMax(bounds[1], bounds[3], bounds[5]);
resampler->SetInputData(amr);
resampler->Update();
vtkMultiBlockDataSet* mbs = vtkMultiBlockDataSet::SafeDownCast(
resampler->GetOutputDataObject(0));
if (mbs && mbs->GetNumberOfBlocks() == 1)
{
this->VolumeMapper->SetInputData(
vtkImageData::SafeDownCast(mbs->GetBlock(0)));
}
}
else
{
this->VolumeMapper->SetInputConnection(producerPort);
}
}
}
return 1;
......@@ -133,11 +215,11 @@ int vtkAMRVolumeRepresentation::ProcessViewRequest(
int vtkAMRVolumeRepresentation::RequestData(vtkInformation* request,
vtkInformationVector** inputVector, vtkInformationVector* outputVector)
{
cerr << "vtkAMRVolumeRepresentation::RequestData" << endl;
// Pass caching information to the cache keeper.
this->CacheKeeper->SetCachingEnabled(this->GetUseCache());
this->CacheKeeper->SetCacheTime(this->GetCacheKey());
vtkMath::UninitializeBounds(this->DataBounds);
if (inputVector[0]->GetNumberOfInformationObjects()==1)
{
vtkOverlappingAMR* input =
......@@ -147,6 +229,12 @@ int vtkAMRVolumeRepresentation::RequestData(vtkInformation* request,
this->Cache->ShallowCopy(input);
}
this->CacheKeeper->Update();
vtkOverlappingAMR* amr = vtkOverlappingAMR::SafeDownCast(
this->CacheKeeper->GetOutputDataObject(0));
if (amr)
{
amr->GetBounds(this->DataBounds);
}
}
return this->Superclass::RequestData(request, inputVector, outputVector);
......@@ -199,20 +287,12 @@ void vtkAMRVolumeRepresentation::UpdateMapperParameters()
{
this->VolumeMapper->SelectScalarArray(this->ColorArrayName);
this->VolumeMapper->SetRequestedRenderMode(this->RequestedRenderMode);
this->VolumeMapper->SetNumberOfSamples(this->NumberOfSamples);
this->VolumeMapper->SetRequestedResamplingMode(this->RequestedResamplingMode);
this->VolumeMapper->SetFreezeFocalPoint(this->FreezeFocalPoint);
switch (this->ColorAttributeType)
{
case CELL_DATA:
this->VolumeMapper->SetScalarMode(VTK_SCALAR_MODE_USE_CELL_FIELD_DATA);
break;
case POINT_DATA:
default:
this->VolumeMapper->SetScalarMode(VTK_SCALAR_MODE_USE_POINT_FIELD_DATA);
break;
}
// we always say point-data, since the resampler samples to points.
this->VolumeMapper->SetScalarMode(VTK_SCALAR_MODE_USE_POINT_FIELD_DATA);
//this->VolumeMapper->SetNumberOfSamples(this->NumberOfSamples);
//this->VolumeMapper->SetRequestedResamplingMode(this->RequestedResamplingMode);
//this->VolumeMapper->SetFreezeFocalPoint(this->FreezeFocalPoint);
this->Actor->SetMapper(this->VolumeMapper);
}
......
......@@ -24,7 +24,7 @@
#include "vtkPVDataRepresentation.h"
#include "vtkWeakPointer.h" // needed for iVars.
class vtkAMRVolumeMapper;
class vtkSmartVolumeMapper;
class vtkColorTransferFunction;
class vtkFixedPointVolumeRayCastMapper;
class vtkOverlappingAMR;
......@@ -117,25 +117,39 @@ public:
void SetSpecularPower(double);
void SetShade(bool);
vtkSetMacro(FreezeFocalPoint,bool);
vtkGetMacro(FreezeFocalPoint,bool);
// Description:
// When steaming, this is the block that's requested from the upstream.
void SetStreamingBlockId(unsigned int val)
{
if (this->StreamingCapableSource)
{
this->StreamingBlockId = val;
this->MarkModified();
}
}
void ResetStreamingBlockId()
{ this->StreamingBlockId = 0; }
//BTX
protected:
vtkAMRVolumeRepresentation();
~vtkAMRVolumeRepresentation();
// Description:
// Gets the metadata from upstream module and determines which blocks
// should be loaded by this instance.
virtual int RequestInformation(
vtkInformation *rqst,
vtkInformationVector **inputVector,
vtkInformationVector *outputVector );
virtual int RequestInformation(vtkInformation *rqst,
vtkInformationVector **inputVector,
vtkInformationVector *outputVector );
// Description:
// Performs upstream requests to the reader
virtual int RequestUpdateExtent(
vtkInformation*, vtkInformationVector**,
vtkInformationVector* );
vtkSetMacro(FreezeFocalPoint,bool);
vtkGetMacro(FreezeFocalPoint,bool);
//BTX
protected:
vtkAMRVolumeRepresentation();
~vtkAMRVolumeRepresentation();
vtkInformation*, vtkInformationVector**,
vtkInformationVector* );
// Description:
// Fill input port information.
......@@ -171,7 +185,7 @@ protected:
vtkOverlappingAMR* Cache;
vtkPVCacheKeeper* CacheKeeper;
vtkAMRVolumeMapper* VolumeMapper;
vtkSmartVolumeMapper* VolumeMapper;
vtkVolumeProperty* Property;
vtkPVLODVolume* Actor;
vtkWeakPointer<vtkPVRenderView> RenderView;
......@@ -182,6 +196,11 @@ protected:
int RequestedResamplingMode;
int NumberOfSamples[3];
bool FreezeFocalPoint;
bool StreamingCapableSource;
unsigned int StreamingBlockId;
double DataBounds[6];
private:
vtkAMRVolumeRepresentation(const vtkAMRVolumeRepresentation&); // Not implemented
......
......@@ -78,6 +78,9 @@ class vtkPVRenderView::vtkInternals
public:
unsigned int UniqueId;
vtkNew<vtkRepresentedDataStorage> GeometryStore;
vtkInternals() : UniqueId(1)
{
}
};
......@@ -839,37 +842,40 @@ void vtkPVRenderView::InteractiveRender()
}
//----------------------------------------------------------------------------
const char* vtkPVRenderView::DeliverNextPiece()
unsigned int vtkPVRenderView::GetNextPieceToDeliver()
{
if (!vtkPVView::GetEnableStreaming())
{
return NULL;
return 0;
}
if (this->UpdateTimeStamp > this->PriorityQueueBuildTimeStamp ||
this->GetActiveCamera()->GetMTime() > this->PriorityQueueBuildTimeStamp)
{
// if data or camera changed, we need to rebuild the priority queues.
// TODO:
// either the data or the camera has changed. Regenerate the priority queue.
// Priority queue contains a list of (representation-id, block-id) tuples
// indicating the blocks to request.
vtkTimerLog::MarkStartEvent("Build View Priority Queue");
this->GetGeometryStore()->BuildPriorityQueue();
vtkTimerLog::MarkEndEvent("Build View Priority Queue");
this->PriorityQueueBuildTimeStamp.Modified();
}
cout << "StreamingUpdate: " << endl;
return this->GetGeometryStore()->GetRepresentationIdFromQueue();
}
//----------------------------------------------------------------------------
void vtkPVRenderView::StreamingUpdate()
{
vtkTimerLog::MarkStartEvent("Streaming Update");
// Update the representations.
this->RequestInformation->Set(REPRESENTED_DATA_STORE(),
this->Internals->GeometryStore.GetPointer());
this->CallProcessViewRequest(vtkPVView::REQUEST_UPDATE(),
this->RequestInformation, this->ReplyInformationVector);
vtkTimerLog::MarkEndEvent("Streaming Update");
return "hehe";
}
//----------------------------------------------------------------------------
void vtkPVRenderView::Render(bool interactive, bool skip_rendering)
{
......@@ -1067,6 +1073,22 @@ void vtkPVRenderView::MarkAsRedistributable(
storage->MarkAsRedistributable(repr);
}
//----------------------------------------------------------------------------
void vtkPVRenderView::SetStreamable(
vtkInformation* info, vtkPVDataRepresentation* repr, bool val)
{
vtkRepresentedDataStorage* storage =
vtkRepresentedDataStorage::SafeDownCast(
info->Get(REPRESENTED_DATA_STORE()));
if (!storage)
{
vtkGenericWarningMacro("Missing REPRESENTED_DATA_STORE().");
return;
}
storage->SetStreamable(repr, val);
}
//----------------------------------------------------------------------------
void vtkPVRenderView::SetDeliverToAllProcesses(vtkInformation* info,
vtkPVDataRepresentation* repr, bool clone)
......
......@@ -171,7 +171,11 @@ public:
virtual void InteractiveRender();
// Description:
const char* DeliverNextPiece();
// Returns the representation id which is going to deliver the next piece for
// streaming.
unsigned int GetNextPieceToDeliver();
void StreamingUpdate();
// Description:
// Get/Set the reduction-factor to use when for StillRender(). This is
......@@ -347,6 +351,8 @@ public:
vtkInformation* info, vtkPVDataRepresentation* repr);
static void SetGeometryBounds(vtkInformation* info,
double bounds[6], vtkMatrix4x4* transform = NULL);
static void SetStreamable(
vtkInformation* info, vtkPVDataRepresentation* repr, bool streamable);
public:
//*****************************************************************
......
......@@ -62,7 +62,7 @@ vtkInformationKeyMacro(vtkPVView, REQUEST_UPDATE, Request);
vtkInformationKeyMacro(vtkPVView, REQUEST_UPDATE_LOD, Request);
vtkInformationKeyMacro(vtkPVView, REQUEST_RENDER, Request);
bool vtkPVView::EnableStreaming = true;
bool vtkPVView::EnableStreaming = true;
//----------------------------------------------------------------------------
void vtkPVView::SetEnableStreaming(bool val)
{
......
......@@ -16,18 +16,27 @@
#include "vtkRepresentedDataStorageInternals.h"
#include "vtkAlgorithmOutput.h"
#include "vtkAMRVolumeRepresentation.h"
#include "vtkBSPCutsGenerator.h"
#include "vtkFieldData.h"
#include "vtkMPIMoveData.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkMultiProcessController.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkOrderedCompositeDistributor.h"
#include "vtkOverlappingAMR.h"
#include "vtkPKdTree.h"
#include "vtkProcessModule.h"
#include "vtkPVRenderView.h"
#include "vtkPVSession.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkTimerLog.h"
#include "vtkUniformGridAMRDataIterator.h"
#include "vtkUniformGrid.h"
#include "vtkUnsignedIntArray.h"
#include <assert.h>
vtkStandardNewMacro(vtkRepresentedDataStorage);
//----------------------------------------------------------------------------
......@@ -123,6 +132,30 @@ void vtkRepresentedDataStorage::MarkAsRedistributable(
}
}
//----------------------------------------------------------------------------
void vtkRepresentedDataStorage::SetStreamable(
vtkPVDataRepresentation* repr, bool val)
{
if (!repr->IsA("vtkAMRVolumeRepresentation") && val == true)
{
vtkWarningMacro(
"Only vtkAMRVolumeRepresentation streaming is currently supported.");
return;
}
vtkInternals::vtkItem* item = this->Internals->GetItem(repr, false);
vtkInternals::vtkItem* low_item = this->Internals->GetItem(repr, true);
if (item)
{
item->Streamable = val;
low_item->Streamable = val;
}
else
{
vtkErrorMacro("Invalid argument.");
}
}
//----------------------------------------------------------------------------
void vtkRepresentedDataStorage::SetPiece(
vtkPVDataRepresentation* repr, vtkDataObject* data, bool low_res)
......@@ -247,26 +280,22 @@ void vtkRepresentedDataStorage::Deliver(int use_lod, unsigned int size, unsigned
// we are dealing with AMR datasets.
// We assume for now we're not running in render-server mode. We can
// ensure that at some point in future.
// So we are either in pass-through or collect mode.
if ( (mode & vtkMPIMoveData::COLLECT) != 0)
{
// handle delivery of AMR datasets.
}
// So we are either in pass-through or collect mode.
// FIXME: check that the mode flags are "suitable" for AMR.
}
else
vtkNew<vtkMPIMoveData> dataMover;
dataMover->InitializeForCommunicationForParaView();
dataMover->SetOutputDataType(data->GetDataObjectType());
dataMover->SetMoveMode(mode);
if (item->AlwaysClone)
{
vtkNew<vtkMPIMoveData> dataMover;
dataMover->InitializeForCommunicationForParaView();
dataMover->SetOutputDataType(data->GetDataObjectType());
dataMover->SetMoveMode(mode);
if (item->AlwaysClone)
{
dataMover->SetMoveModeToClone();
}
dataMover->SetInputConnection(item->GetProducer()->GetOutputPort());
dataMover->Update();
item->SetDataObject(dataMover->GetOutputDataObject(0));
dataMover->SetMoveModeToClone();
}
dataMover->SetInputConnection(item->GetProducer()->GetOutputPort());
dataMover->Update();
item->SetDataObject(dataMover->GetOutputDataObject(0));
}
// There's a possibility that we'd need to do ordered compositing.
......@@ -344,6 +373,130 @@ vtkPKdTree* vtkRepresentedDataStorage::GetKdTree()
{
return this->KdTree;
}
//----------------------------------------------------------------------------
bool vtkRepresentedDataStorage::BuildPriorityQueue()
{
// just find the first visible AMR dataset and build priority queue for that
// dataset alone. In future, we can fix it to use information provided by
// representation indicating if streaming is possible (since not every AMR
// source is streambale).
this->Internals->PriorityQueue = vtkInternals::PriorityQueueType();
vtkOverlappingAMR* oamr = NULL;
vtkInternals::ItemsMapType::iterator iter;
for (iter = this->Internals->ItemsMap.begin();
iter != this->Internals->ItemsMap.end(); ++iter)
{
vtkInternals::vtkItem& item = iter->second.first;
if (item.Representation &&
item.Representation->GetVisibility() &&
item.Streamable &&
item.GetDataObject() &&
item.GetDataObject()->IsA("vtkOverlappingAMR"))
{
oamr = vtkOverlappingAMR::SafeDownCast(item.GetDataObject());
break;
}
}
if (oamr == NULL)
{
return true;
}
// note: amr block ids currently don't match up with composite dataset ids :/.
unsigned int block_id = 0;
// now build a priority queue for absent blocks using the current camera.
for (unsigned int level=0; level < oamr->GetNumberOfLevels(); level++)
{
for (unsigned int index=0;
index < oamr->GetNumberOfDataSets(level); index++)
{
if (oamr->GetDataSet(level, index) == NULL)
{
vtkInternals::vtkPriorityQueueItem item;
item.RepresentationId = iter->first;
item.BlockId = block_id;
item.Priority = 1.0 / (1.0 + block_id);
this->Internals->PriorityQueue.push(item);
}
block_id++;
}
}
return true;
}
//----------------------------------------------------------------------------
void vtkRepresentedDataStorage::StreamingDeliver(unsigned int key)
{
vtkInternals::vtkItem* item = this->Internals->GetItem(key, false);
vtkOverlappingAMR* oamr = vtkOverlappingAMR::SafeDownCast(item->GetDataObject());
if (!oamr)
{
cout << "ERROR: StreamingDeliver can only deliver AMR datasets for now" << endl;
abort();
}
if (this->Internals->PriorityQueue.empty())
{
// client side.
vtkNew<vtkMPIMoveData> dataMover;
dataMover->InitializeForCommunicationForParaView();
dataMover->SetOutputDataType(VTK_OVERLAPPING_AMR);
dataMover->SetMoveModeToCollect();
dataMover->SetInputConnection(NULL);
dataMover->Update();
// now put the piece in right place.
vtkOverlappingAMR* ds = vtkOverlappingAMR::SafeDownCast(
dataMover->GetOutputDataObject(0));
vtkCompositeDataIterator* iter = ds->NewIterator();
for (iter->InitTraversal(); !iter->IsDoneWithTraversal();
iter->GoToNextItem())
{
oamr->SetDataSet(iter, iter->GetCurrentDataObject());
}
iter->Delete();
oamr->Modified();
}
else
{
vtkInternals::vtkPriorityQueueItem qitem =
this->Internals->PriorityQueue.top();
this->Internals->PriorityQueue.pop();
assert(qitem.RepresentationId == key);
vtkAMRVolumeRepresentation* repr = vtkAMRVolumeRepresentation::SafeDownCast(
item->Representation);
repr->SetStreamingBlockId(qitem.BlockId);
this->View->StreamingUpdate();
repr->ResetStreamingBlockId();
oamr = vtkOverlappingAMR::SafeDownCast(item->GetDataObject());
// the one bad thing about this is that we are sending the full amr
// meta-data again. We can do better here and not send it again.
vtkNew<vtkMPIMoveData> dataMover;
dataMover->InitializeForCommunicationForParaView();
dataMover->SetOutputDataType(VTK_OVERLAPPING_AMR);
dataMover->SetMoveModeToCollect();
dataMover->SetInputData(oamr);
dataMover->Update();
}
}
//----------------------------------------------------------------------------
unsigned int vtkRepresentedDataStorage::GetRepresentationIdFromQueue()
{
if (!this->Internals->PriorityQueue.empty())
{
return this->Internals->PriorityQueue.top().RepresentationId;
}
return 0;
}
//----------------------------------------------------------------------------
void vtkRepresentedDataStorage::PrintSelf(ostream& os, vtkIndent indent)
{
......
......@@ -74,8 +74,20 @@ public:
// needs to be "moved around" when ordered compositing is needed.
void MarkAsRedistributable(vtkPVDataRepresentation*);
// Description:
// Mark a representation as streamable. Currently only
// vtkAMRVolumeRepresentation is supported.
void SetStreamable(vtkPVDataRepresentation*, bool);
vtkPKdTree* GetKdTree();
// Description:
// Based on the current camera and currently available datasets, build a
// priority queue.
bool BuildPriorityQueue();
unsigned int GetRepresentationIdFromQueue();
void StreamingDeliver(unsigned int key);
//BTX
bool NeedsDelivery(unsigned long timestamp,
std::vector<unsigned int>& keys_to_deliver, bool use_low_res);
......
......@@ -25,11 +25,34 @@
#include "vtkWeakPointer.h"
#include <map>
#include <queue>
#include <utility>
class vtkRepresentedDataStorage::vtkInternals
{
public:
class vtkPriorityQueueItem
{
public:
unsigned int RepresentationId;
unsigned int BlockId;
double Priority;
vtkPriorityQueueItem() :
RepresentationId(0), BlockId(0), Priority(0)
{
}
bool operator < (const vtkPriorityQueueItem& other) const
{
return this->Priority < other.Priority;
}
};
typedef std::priority_queue<vtkPriorityQueueItem> PriorityQueueType;
PriorityQueueType PriorityQueue;
class vtkItem
{
vtkSmartPointer<vtkPVTrivialProducer> Producer;
......@@ -40,13 +63,15 @@ public:
vtkWeakPointer<vtkPVDataRepresentation> Representation;
bool AlwaysClone;
bool Redistributable;
bool Streamable;
vtkItem() :
Producer(vtkSmartPointer<vtkPVTrivialProducer>::New()),
TimeStamp(0),