Commit af6c6a1f authored by Utkarsh Ayachit's avatar Utkarsh Ayachit

Improved support for rendering composite datasets.

* Cleaned up code between vtkPolyDataMapper and subclasses to avoid redundancy.
* Remove API from vtkCompositePainter to color leaves. That was added in
  anticipation for support for selection, but we have a different implementation
  for that now.
* Extended vtkHardwareSelector to add a pass to identify composite-ids for the
  points/cells.
parent 84167675
......@@ -17,23 +17,17 @@
#include "vtkCompositeDataIterator.h"
#include "vtkCompositeDataSet.h"
#include "vtkGarbageCollector.h"
#include "vtkInformation.h"
#include "vtkInformationIntegerKey.h"
#include "vtkHardwareSelector.h"
#include "vtkObjectFactory.h"
#include "vtkPainterDeviceAdapter.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkCellData.h"
#ifndef VTK_IMPLEMENT_MESA_CXX
# include "vtkOpenGL.h"
#endif
vtkStandardNewMacro(vtkCompositePainter);
vtkInformationKeyMacro(vtkCompositePainter, COLOR_LEAVES, Integer);
//----------------------------------------------------------------------------
vtkCompositePainter::vtkCompositePainter()
{
this->ColorLeaves = 0;
this->OutputData = 0;
}
......@@ -42,20 +36,6 @@ vtkCompositePainter::~vtkCompositePainter()
{
}
//----------------------------------------------------------------------------
void vtkCompositePainter::ProcessInformation(vtkInformation* info)
{
this->Superclass::ProcessInformation(info);
if (info->Has(COLOR_LEAVES()))
{
this->SetColorLeaves(info->Get(COLOR_LEAVES()));
}
else
{
this->SetColorLeaves(0);
}
}
//----------------------------------------------------------------------------
vtkDataObject* vtkCompositePainter::GetOutput()
{
......@@ -68,53 +48,26 @@ void vtkCompositePainter::RenderInternal(vtkRenderer* renderer,
unsigned long typeflags,
bool forceCompileOnly)
{
vtkPainterDeviceAdapter* device = renderer->GetRenderWindow()->
GetPainterDeviceAdapter();
vtkCompositeDataSet* input = vtkCompositeDataSet::SafeDownCast(this->GetInput());
if (!input || !this->DelegatePainter)
{
this->Superclass::RenderInternal(renderer, actor, typeflags,
forceCompileOnly);
this->Superclass::RenderInternal(renderer, actor, typeflags,
forceCompileOnly);
return;
}
//turn off antialising and lighting so that the colors we draw will be the
//colors we read back
int origMultisample = device->QueryMultisampling();
int origLighting = device->QueryLighting();
int origBlending = device->QueryBlending();
if (this->ColorLeaves)
{
device->MakeMultisampling(0);
device->MakeLighting(0);
device->MakeBlending(0);
}
vtkHardwareSelector* selector = renderer->GetSelector();
vtkCompositeDataIterator* iter = input->NewIterator();
unsigned int index=1; // start from 1 since 0 cannot be a color.
for (iter->InitTraversal(); !iter->IsDoneWithTraversal();
iter->GoToNextItem(), index++)
for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
{
vtkDataObject* dobj = iter->GetCurrentDataObject();
if (dobj)
{
if (this->ColorLeaves)
if (selector)
{
unsigned char params[4] = {255, 255, 0, 255};
params[0] = static_cast<unsigned char>(index & 0x0000ff);
params[1] = static_cast<unsigned char>((index & 0x00ff00)>>8);
params[2] = static_cast<unsigned char>((index & 0xff0000)>>16);
params[3] = 255;
float color[4];
color[0] = params[0]/255.0;
color[1] = params[1]/255.0;
color[2] = params[2]/255.0;
color[3] = params[3]/255.0;
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
// If hardware selection is in progress, we need to pass the composite
// index to the selection framework,
selector->RenderCompositeIndex(iter->GetCurrentFlatIndex());
}
this->DelegatePainter->SetInput(dobj);
......@@ -125,14 +78,6 @@ void vtkCompositePainter::RenderInternal(vtkRenderer* renderer,
}
}
iter->Delete();
if (this->ColorLeaves)
{
//reset lighting back to the default
device->MakeBlending(origBlending);
device->MakeLighting(origLighting);
device->MakeMultisampling(origMultisample);
}
}
//-----------------------------------------------------------------------------
......@@ -143,11 +88,9 @@ void vtkCompositePainter::ReportReferences(vtkGarbageCollector *collector)
vtkGarbageCollectorReport(collector, this->OutputData, "Output");
}
//----------------------------------------------------------------------------
void vtkCompositePainter::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "ColorLeaves: " << this->ColorLeaves << endl;
}
......@@ -24,8 +24,6 @@
#include "vtkPainter.h"
class vtkInformationIntegerKey;
class VTK_RENDERING_EXPORT vtkCompositePainter : public vtkPainter
{
public:
......@@ -33,11 +31,6 @@ public:
vtkTypeMacro(vtkCompositePainter, vtkPainter);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// When this key is present and set to 1 in the information passed to the
// painter, the painter colors each block using a unique color.
static vtkInformationIntegerKey* COLOR_LEAVES();
// Description:
// Get the output data object from this painter. The default implementation
// simply forwards the input data object as the output.
......@@ -52,24 +45,14 @@ protected:
// Take part in garbage collection.
virtual void ReportReferences(vtkGarbageCollector *collector);
// Description:
// Called before RenderInternal() if the Information has been changed
// since the last time this method was called.
// Overridden to update the state of COLOR_LEAVES key.
virtual void ProcessInformation(vtkInformation*);
// Description:
// Performs the actual rendering. Subclasses may override this method.
// default implementation merely call a Render on the DelegatePainter,
// if any. When RenderInternal() is called, it is assured that the
// if any. When RenderInternal() is called, it is assured that the
// DelegatePainter is in sync with this painter i.e. UpdateDelegatePainter()
// has been called.
virtual void RenderInternal(vtkRenderer* renderer, vtkActor* actor,
unsigned long typeflags, bool forceCompileOnly);
vtkSetMacro(ColorLeaves, int);
vtkGetMacro(ColorLeaves, int);
int ColorLeaves;
virtual void RenderInternal(vtkRenderer* renderer, vtkActor* actor,
unsigned long typeflags, bool forceCompileOnly);
vtkDataObject* OutputData;
private:
......
......@@ -35,7 +35,12 @@ vtkStandardNewMacro(vtkCompositePolyDataMapper2);
//----------------------------------------------------------------------------
vtkCompositePolyDataMapper2::vtkCompositePolyDataMapper2()
{
this->ColorBlocks = 0;
// Insert the vtkCompositePainter in the selection pipeline, so that the
// selection painter can handle composite datasets as well.
vtkCompositePainter* selectionPainter = vtkCompositePainter::New();
selectionPainter->SetDelegatePainter(this->SelectionPainter);
this->SetSelectionPainter(selectionPainter);
selectionPainter->FastDelete();
}
//----------------------------------------------------------------------------
......@@ -47,7 +52,8 @@ vtkCompositePolyDataMapper2::~vtkCompositePolyDataMapper2()
int vtkCompositePolyDataMapper2::FillInputPortInformation(
int vtkNotUsed(port), vtkInformation* info)
{
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataObject");
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData");
info->Append(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkCompositeDataSet");
return 1;
}
......@@ -57,99 +63,6 @@ vtkExecutive* vtkCompositePolyDataMapper2::CreateDefaultExecutive()
return vtkCompositeDataPipeline::New();
}
//-----------------------------------------------------------------------------
void vtkCompositePolyDataMapper2::RenderPiece(vtkRenderer* ren, vtkActor* act)
{
vtkDataObject* inputDO = this->GetInputDataObject(0, 0);
vtkCompositeDataSet* inputCD = vtkCompositeDataSet::SafeDownCast(inputDO);
if (!inputCD)
{
this->Superclass::RenderPiece(ren, act);
return;
}
//
// make sure that we've been properly initialized
//
if (ren->GetRenderWindow()->CheckAbortStatus())
{
return;
}
if ( inputCD == NULL )
{
vtkErrorMacro(<< "No input!");
return;
}
this->InvokeEvent(vtkCommand::StartEvent,NULL);
if (!this->Static)
{
inputCD->Update();
}
this->InvokeEvent(vtkCommand::EndEvent,NULL);
// make sure our window is current
ren->GetRenderWindow()->MakeCurrent();
this->TimeToDraw = 0.0;
if (this->Painter)
{
// Update Painter information if obsolete.
if (this->PainterUpdateTime < this->GetMTime())
{
this->UpdatePainterInformation();
this->PainterUpdateTime.Modified();
}
// Pass polydata if changed.
if (this->Painter->GetInput() != inputDO)
{
this->Painter->SetInput(inputDO);
}
this->Painter->Render(ren, act, 0xff,this->ForceCompileOnly==1);
this->TimeToDraw = this->Painter->GetTimeToDraw();
}
// If the timer is not accurate enough, set it to a small
// time so that it is not zero
if ( this->TimeToDraw == 0.0 )
{
this->TimeToDraw = 0.0001;
}
this->UpdateProgress(1.0);
}
//-----------------------------------------------------------------------------
void vtkCompositePolyDataMapper2::Render(vtkRenderer *ren, vtkActor *act)
{
if (this->Static)
{
this->RenderPiece(ren,act);
return;
}
int currentPiece, nPieces;
vtkDataObject *input = this->GetInputDataObject(0, 0);
if (input == NULL)
{
vtkErrorMacro("Mapper has no input.");
return;
}
nPieces = this->NumberOfPieces * this->NumberOfSubPieces;
for(int i=0; i<this->NumberOfSubPieces; i++)
{
// If more than one pieces, render in loop.
currentPiece = this->NumberOfSubPieces * this->Piece + i;
input->SetUpdateExtent(currentPiece, nPieces, this->GhostLevel);
this->RenderPiece(ren, act);
}
}
//-----------------------------------------------------------------------------
//Looks at each DataSet and finds the union of all the bounds
void vtkCompositePolyDataMapper2::ComputeBounds()
......@@ -163,14 +76,10 @@ void vtkCompositePolyDataMapper2::ComputeBounds()
// the bounds of the input polydata.
if (!input)
{
this->Superclass::GetBounds();
this->Superclass::ComputeBounds();
return;
}
this->Update();
input = vtkCompositeDataSet::SafeDownCast(
this->GetInputDataObject(0, 0));
// We do have hierarchical data - so we need to loop over
// it and get the total bounds.
vtkCompositeDataIterator* iter = input->NewIterator();
......@@ -191,52 +100,12 @@ void vtkCompositePolyDataMapper2::ComputeBounds()
}
iter->Delete();
bbox.GetBounds(this->Bounds);
this->BoundsMTime.Modified();
}
//-----------------------------------------------------------------------------
double *vtkCompositePolyDataMapper2::GetBounds()
{
if ( !this->GetExecutive()->GetInputData(0, 0) )
{
vtkMath::UninitializeBounds(this->Bounds);
return this->Bounds;
}
else
{
if (!this->Static)
{
this->Update();
}
//only compute bounds when the input data has changed
vtkCompositeDataPipeline * executive =
vtkCompositeDataPipeline::SafeDownCast(this->GetExecutive());
if( executive->GetPipelineMTime() >= this->BoundsMTime.GetMTime() )
{
this->ComputeBounds();
}
return this->Bounds;
}
}
//-----------------------------------------------------------------------------
void vtkCompositePolyDataMapper2::UpdatePainterInformation()
{
vtkInformation* info = this->PainterInformation;
this->Superclass::UpdatePainterInformation();
if (this->ColorBlocks)
{
info->Set(vtkScalarsToColorsPainter::SCALAR_VISIBILITY(), 0);
}
info->Set(vtkCompositePainter::COLOR_LEAVES(), this->ColorBlocks);
// this->BoundsMTime.Modified();
}
//----------------------------------------------------------------------------
void vtkCompositePolyDataMapper2::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "ColorBlocks: " << this->ColorBlocks << endl;
}
......@@ -31,28 +31,6 @@ public:
vtkTypeMacro(vtkCompositePolyDataMapper2, vtkPainterPolyDataMapper);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Implemented by sub classes. Actual rendering is done here.
virtual void RenderPiece(vtkRenderer *ren, vtkActor *act);
// Description:
// Standard vtkProp method to get 3D bounds of a 3D prop
double *GetBounds();
void GetBounds(double bounds[6]) { this->Superclass::GetBounds( bounds ); };
// Description:
// This calls RenderPiece (in a for loop is streaming is necessary).
// Basically a reimplementation for vtkPolyDataMapper::Render() since we don't
// want it to give up when vtkCompositeDataSet is encountered.
virtual void Render(vtkRenderer *ren, vtkActor *act);
// Description:
// When set, each block is colored with a different color. Note that scalar
// coloring will be ignored.
vtkSetMacro(ColorBlocks, int);
vtkGetMacro(ColorBlocks, int);
//BTX
protected:
vtkCompositePolyDataMapper2();
......@@ -72,16 +50,10 @@ protected:
// Need to loop over the hierarchy to compute bounds
virtual void ComputeBounds();
// Description:
// Called when the PainterInformation becomes obsolete.
// It is called before the Render is initiated on the Painter.
virtual void UpdatePainterInformation();
// Description:
// Time stamp for computation of bounds.
vtkTimeStamp BoundsMTime;
int ColorBlocks;
private:
vtkCompositePolyDataMapper2(const vtkCompositePolyDataMapper2&); // Not implemented.
void operator=(const vtkCompositePolyDataMapper2&); // Not implemented.
......
......@@ -32,13 +32,13 @@ static inline int vtkHardwareSelectionPolyDataPainterGetTotalCells(vtkPolyData*
unsigned long typeflags)
{
int total_cells = 0;
total_cells += (typeflags & vtkPainter::VERTS)?
total_cells += (typeflags & vtkPainter::VERTS)?
pd->GetNumberOfVerts() : 0;
total_cells += (typeflags & vtkPainter::LINES)?
total_cells += (typeflags & vtkPainter::LINES)?
pd->GetNumberOfLines() : 0;
total_cells += (typeflags & vtkPainter::POLYS)?
total_cells += (typeflags & vtkPainter::POLYS)?
pd->GetNumberOfPolys() : 0;
total_cells += (typeflags & vtkPainter::STRIPS)?
total_cells += (typeflags & vtkPainter::STRIPS)?
pd->GetNumberOfStrips() : 0;
return total_cells;
}
......@@ -99,13 +99,13 @@ void vtkHardwareSelectionPolyDataPainter::RenderInternal(
{
this->DrawCells(VTK_POLY_LINE, pd->GetLines(), startCell, renderer);
}
startCell += pd->GetNumberOfLines();
if (typeflags & vtkPainter::POLYS)
{
this->DrawCells(VTK_POLYGON, pd->GetPolys(), startCell, renderer);
}
startCell += pd->GetNumberOfPolys();
if (typeflags & vtkPainter::STRIPS)
{
......@@ -146,7 +146,7 @@ void vtkHardwareSelectionPolyDataPainter::DrawCells(
vtkPoints* p = pd->GetPoints();
vtkIdType npts, *pts;
vtkIdType cellId = startCellId;
int pointtype = p->GetDataType();
void* voidpoints = p->GetVoidPointer(0);
int count = 0;
......@@ -168,12 +168,12 @@ void vtkHardwareSelectionPolyDataPainter::DrawCells(
{
selector->RenderAttributeId(pointId);
}
device->SendAttribute(vtkPointData::NUM_ATTRIBUTES, 3,
device->SendAttribute(vtkPointData::NUM_ATTRIBUTES, 3,
pointtype, voidpoints, 3*pointId);
}
device->EndPrimitive();
cellId++;
if (count == 10000)
if (count == 10000)
{
count = 0;
// report progress
......
......@@ -28,6 +28,7 @@
#include "vtkSelection.h"
#include "vtkSelectionNode.h"
#include "vtkSmartPointer.h"
#include "vtkStructuredExtent.h"
#include <vtkstd/set>
#include <vtkstd/map>
......@@ -412,6 +413,7 @@ vtkHardwareSelector::PixelInformation vtkHardwareSelector::GetPixelInformation(
info.Valid = true;
actorid--;
info.PropID = actorid;
info.Prop = this->Internals->Props[actorid];
int composite_id = this->Convert(display_position,
......@@ -513,104 +515,116 @@ bool vtkHardwareSelector::GetPixelInformation(unsigned int display_position[2],
#endif // !defined(VTK_LEGACY_REMOVE)
namespace
{
class PixelInformationComparator
{
public:
bool operator() (const vtkHardwareSelector::PixelInformation& a,
const vtkHardwareSelector::PixelInformation& b)
{
if (a.Valid != b.Valid)
{
return a.Valid < b.Valid;
}
if (a.ProcessID != b.ProcessID)
{
return a.ProcessID < b.ProcessID;
}
if (a.Prop != b.Prop)
{
return a.Prop < b.Prop;
}
if (a.PropID != b.PropID)
{
return a.PropID < b.PropID;
}
return a.CompositeID < b.CompositeID;
// We don't consider AttributeID in this comparison
}
};
}
//----------------------------------------------------------------------------
vtkSelection* vtkHardwareSelector::GenerateSelection(
unsigned int x1, unsigned int y1,
unsigned int x2, unsigned int y2)
{
// Clamp to saved region
x1 = x1 < this->Area[0] ? this->Area[0] : x1;
x1 = x1 > this->Area[2] ? this->Area[2] : x1;
x2 = x2 < this->Area[0] ? this->Area[0] : x2;
x2 = x2 > this->Area[2] ? this->Area[2] : x2;
y1 = y1 < this->Area[1] ? this->Area[1] : y1;
y1 = y1 > this->Area[3] ? this->Area[3] : y1;
y2 = y2 < this->Area[1] ? this->Area[1] : y2;
y2 = y2 > this->Area[3] ? this->Area[3] : y2;
typedef vtkstd::map<int, vtkstd::map<int, vtkstd::set<vtkIdType> > > MapType;
MapType dataMap;
typedef vtkstd::map<int, vtkstd::map<int, vtkIdType> > PixelCountType;
int extent[6] = { x1, x2, y1, y2, 0, 0};
int whole_extent[6] = {this->Area[0], this->Area[2], this->Area[1],
this->Area[3], 0, 0};
vtkStructuredExtent::Clamp(extent, whole_extent);
typedef vtkstd::map<PixelInformation, vtkstd::set<vtkIdType>,
PixelInformationComparator> MapOfAttributeIds;
MapOfAttributeIds dataMap;
typedef vtkstd::map<PixelInformation, vtkIdType, PixelInformationComparator> PixelCountType;
PixelCountType pixelCounts;
for (int yy = y1 - Area[1]; yy <= static_cast<int>(y2 - this->Area[1]); yy++)
{
for (int xx = x1 - Area[0]; xx <= static_cast<int>(x2 - this->Area[0]); xx++)
{
int processid = this->Convert(xx, yy, this->PixBuffer[PROCESS_PASS]);
processid--;
int actorid = this->Convert(xx, yy, this->PixBuffer[ACTOR_PASS]);
if (actorid <= 0)
{
// the pixel did not hit any actor.
continue;
}
actorid--;
int low24 = this->Convert(xx, yy, this->PixBuffer[ID_LOW24]);
int mid24 = this->Convert(xx, yy, this->PixBuffer[ID_MID24]);
int high16 = this->Convert(xx, yy, this->PixBuffer[ID_HIGH16]);
// id 0 is reserved for nothing present.
vtkIdType elemid = this->GetID(low24, mid24, high16);
elemid = (elemid - ID_OFFSET);
if (elemid < 0)
unsigned int pos[2] = {xx, yy};
PixelInformation info = this->GetPixelInformation(pos, 0);
if (info.Valid)
{
continue;
dataMap[info].insert(info.AttributeID);
pixelCounts[info]++;
}
dataMap[processid][actorid].insert(elemid);
pixelCounts[processid][actorid]++;
}
}
vtkSelection* sel = vtkSelection::New();
MapType::iterator procIter;
for (procIter = dataMap.begin(); procIter != dataMap.end(); ++procIter)
MapOfAttributeIds::iterator iter;
for (iter = dataMap.begin(); iter != dataMap.end(); ++iter)
{
int processid = procIter->first;
vtkstd::map<int, vtkstd::set<vtkIdType> >::iterator iter;
for (iter = procIter->second.begin(); iter != procIter->second.end(); ++iter)
const PixelInformation &key = iter->first;
vtkstd::set<vtkIdType> &id_values = iter->second;
vtkSelectionNode* child = vtkSelectionNode::New();
child->SetContentType(vtkSelectionNode::INDICES);
switch (this->FieldAssociation)
{
vtkSelectionNode* child = vtkSelectionNode::New();
child->SetContentType(vtkSelectionNode::INDICES);
switch (this->FieldAssociation)
{
case vtkDataObject::FIELD_ASSOCIATION_CELLS:
child->SetFieldType(vtkSelectionNode::CELL);
break;
case vtkDataObject::FIELD_ASSOCIATION_CELLS:
child->SetFieldType(vtkSelectionNode::CELL);
break;
case vtkDataObject::FIELD_ASSOCIATION_POINTS:
child->SetFieldType(vtkSelectionNode::POINT);
break;
}
child->GetProperties()->Set(vtkSelectionNode::PROP_ID(), iter->first);
child->GetProperties()->Set(vtkSelectionNode::PROP(),
this->Internals->Props[iter->first]);
child->GetProperties()->Set(vtkSelectionNode::PIXEL_COUNT(),
pixelCounts[processid][iter->first]);
if (processid >= 0)
{
child->GetProperties()->Set(vtkSelectionNode::PROCESS_ID(), processid);
}
case vtkDataObject::FIELD_ASSOCIATION_POINTS:
child->SetFieldType(vtkSelectionNode::POINT);
break;
}
child->GetProperties()->Set(vtkSelectionNode::PROP_ID(), key.PropID);
child->GetProperties()->Set(vtkSelectionNode::PROP(), key.Prop);
child->GetProperties()->Set(vtkSelectionNode::PIXEL_COUNT(), pixelCounts[key]);
if (key.ProcessID >= 0)
{
child->GetProperties()->Set(vtkSelectionNode::PROCESS_ID(),
key.ProcessID);
}
if (key.CompositeID > 0)
{
child->GetProperties()->Set(vtkSelectionNode::COMPOSITE_INDEX(),
key.CompositeID);
}
vtkIdTypeArray* ids = vtkIdTypeArray::New();
ids->SetName("SelectedIds");
ids->SetNumberOfComponents(1);
ids->SetNumberOfTuples(iter->second.size());
vtkstd::set<vtkIdType>::iterator idIter;
vtkIdType cc=0;
for (idIter = iter->second.begin(); idIter != iter->second.end();
++idIter, ++cc)
{
ids->SetValue(cc, *idIter);
}
child->SetSelectionList(ids);
ids->Delete();
sel->AddNode(child);
child->Delete();
vtkIdTypeArray* ids = vtkIdTypeArray::New();
ids->SetName("SelectedIds");
ids->SetNumberOfComponents(1);
ids->SetNumberOfTuples(iter->second.size());
vtkIdType* ptr = ids->GetPointer(0);
vtkstd::set<vtkIdType>::iterator idIter;
vtkIdType cc=0;
for (idIter = id_values.begin(); idIter != id_values.end(); ++idIter, ++cc)
{
ptr[cc] = *idIter;
}
child->SetSelectionList(ids);
ids->FastDelete();
sel->AddNode(child);
child->FastDelete();
}
return sel;
......
......@@ -73,6 +73,7 @@ public:
{
bool Valid;
int ProcessID;
int PropID;
vtkProp* Prop;
unsigned int CompositeID;
vtkIdType AttributeID;
......
......@@ -279,13 +279,14 @@ void vtkPainterPolyDataMapper::UpdatePainterInformation()
//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::RenderPiece(vtkRenderer* ren, vtkActor* act)
{
vtkPolyData *input= this->GetInput();
vtkStandardPolyDataPainter * painter =
vtkDataObject *input= this->GetInputDataObject(0, 0);
vtkStandardPolyDataPainter * painter =
vtkStandardPolyDataPainter::SafeDownCast(this->Painter);
if(painter != NULL)
if (painter != NULL && vtkPolyData::SafeDownCast(input))
{
vtkInformationVector *inArrayVec =
// FIXME: This is not supported currently for composite datasets.
vtkInformationVector *inArrayVec =
this->Information->Get(INPUT_ARRAYS_TO_PROCESS());
int numArrays = inArrayVec->GetNumberOfInformationObjects();
......@@ -294,7 +295,6 @@ void vtkPainterPolyDataMapper::RenderPiece(vtkRenderer* ren, vtkActor* act)
painter->AddMultiTextureCoordsArray(this->GetInputArrayToProcess(i,input));