You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
459 lines
15 KiB
C++
459 lines
15 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkPainterPolyDataMapper.cxx
|
|
|
|
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 "vtkPainterPolyDataMapper.h"
|
|
|
|
#include "vtkChooserPainter.h"
|
|
#include "vtkClipPlanesPainter.h"
|
|
#include "vtkCoincidentTopologyResolutionPainter.h"
|
|
#include "vtkCommand.h"
|
|
#include "vtkDefaultPainter.h"
|
|
#include "vtkDisplayListPainter.h"
|
|
#include "vtkGarbageCollector.h"
|
|
#include "vtkGenericVertexAttributeMapping.h"
|
|
#include "vtkHardwareSelectionPolyDataPainter.h"
|
|
#include "vtkInformation.h"
|
|
#include "vtkInformationObjectBaseKey.h"
|
|
#include "vtkInformationVector.h"
|
|
#include "vtkMath.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkPlaneCollection.h"
|
|
#include "vtkPolyData.h"
|
|
#include "vtkPrimitivePainter.h"
|
|
#include "vtkRenderer.h"
|
|
#include "vtkRenderWindow.h"
|
|
#include "vtkScalarsToColors.h"
|
|
#include "vtkScalarsToColorsPainter.h"
|
|
#include "vtkStandardPolyDataPainter.h"
|
|
|
|
vtkStandardNewMacro(vtkPainterPolyDataMapper);
|
|
//-----------------------------------------------------------------------------
|
|
class vtkPainterPolyDataMapperObserver : public vtkCommand
|
|
{
|
|
public:
|
|
static vtkPainterPolyDataMapperObserver* New()
|
|
{ return new vtkPainterPolyDataMapperObserver; }
|
|
|
|
virtual void Execute(vtkObject* caller, unsigned long event, void*)
|
|
{
|
|
vtkPainter* p = vtkPainter::SafeDownCast(caller);
|
|
if (this->Target && p && event == vtkCommand::ProgressEvent)
|
|
{
|
|
this->Target->UpdateProgress(p->GetProgress());
|
|
}
|
|
}
|
|
vtkPainterPolyDataMapperObserver()
|
|
{
|
|
this->Target = 0;
|
|
}
|
|
vtkPainterPolyDataMapper* Target;
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkPainterPolyDataMapper::vtkPainterPolyDataMapper()
|
|
{
|
|
this->Painter = 0;
|
|
|
|
this->PainterInformation = vtkInformation::New();
|
|
|
|
this->Observer = vtkPainterPolyDataMapperObserver::New();
|
|
this->Observer->Target = this;
|
|
|
|
vtkDefaultPainter* dp = vtkDefaultPainter::New();
|
|
this->SetPainter(dp);
|
|
dp->Delete();
|
|
|
|
vtkChooserPainter* cp = vtkChooserPainter::New();
|
|
this->Painter->SetDelegatePainter(cp);
|
|
cp->Delete();
|
|
|
|
this->SelectionPainter = 0;
|
|
vtkPainter* selPainter = vtkHardwareSelectionPolyDataPainter::New();
|
|
this->SetSelectionPainter(selPainter);
|
|
selPainter->Delete();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkPainterPolyDataMapper::~vtkPainterPolyDataMapper()
|
|
{
|
|
this->SetPainter(NULL);
|
|
this->SetSelectionPainter(0);
|
|
this->Observer->Target = NULL;
|
|
this->Observer->Delete();
|
|
this->PainterInformation->Delete();
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
void vtkPainterPolyDataMapper::MapDataArrayToVertexAttribute(
|
|
const char* vertexAttributeName,
|
|
const char* dataArrayName,
|
|
int field,
|
|
int componentno)
|
|
{
|
|
vtkGenericVertexAttributeMapping* mappings = 0;
|
|
if( this->PainterInformation->Has(
|
|
vtkPrimitivePainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()) )
|
|
{
|
|
mappings = vtkGenericVertexAttributeMapping::SafeDownCast(
|
|
this->PainterInformation->Get(
|
|
vtkPolyDataPainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()));
|
|
}
|
|
|
|
if (mappings==NULL)
|
|
{
|
|
mappings = vtkGenericVertexAttributeMapping::New();
|
|
this->PainterInformation->Set(
|
|
vtkPolyDataPainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE(), mappings);
|
|
mappings->Delete();
|
|
}
|
|
|
|
mappings->AddMapping(
|
|
vertexAttributeName, dataArrayName, field, componentno);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
void vtkPainterPolyDataMapper::MapDataArrayToMultiTextureAttribute(
|
|
int unit,
|
|
const char* dataArrayName,
|
|
int field,
|
|
int componentno)
|
|
{
|
|
vtkGenericVertexAttributeMapping* mappings = 0;
|
|
if( this->PainterInformation->Has(
|
|
vtkPrimitivePainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()) )
|
|
{
|
|
mappings = vtkGenericVertexAttributeMapping::SafeDownCast(
|
|
this->PainterInformation->Get(
|
|
vtkPolyDataPainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()));
|
|
}
|
|
|
|
if (mappings==NULL)
|
|
{
|
|
mappings = vtkGenericVertexAttributeMapping::New();
|
|
this->PainterInformation->Set(
|
|
vtkPolyDataPainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE(), mappings);
|
|
mappings->Delete();
|
|
}
|
|
|
|
mappings->AddMapping(
|
|
unit, dataArrayName, field, componentno);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainterPolyDataMapper::RemoveAllVertexAttributeMappings()
|
|
{
|
|
vtkGenericVertexAttributeMapping* mappings = 0;
|
|
if( this->PainterInformation->Has(
|
|
vtkPrimitivePainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()) )
|
|
{
|
|
mappings = vtkGenericVertexAttributeMapping::SafeDownCast(
|
|
this->PainterInformation->Get(
|
|
vtkPolyDataPainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()));
|
|
mappings->RemoveAllMappings();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainterPolyDataMapper::RemoveVertexAttributeMapping(
|
|
const char* vertexAttributeName)
|
|
{
|
|
vtkGenericVertexAttributeMapping* mappings = 0;
|
|
if( this->PainterInformation->Has(
|
|
vtkPrimitivePainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()) )
|
|
{
|
|
mappings = vtkGenericVertexAttributeMapping::SafeDownCast(
|
|
this->PainterInformation->Get(
|
|
vtkPolyDataPainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()));
|
|
mappings->RemoveMapping(vertexAttributeName);
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainterPolyDataMapper::SetPainter(vtkPainter* p)
|
|
{
|
|
if (this->Painter)
|
|
{
|
|
this->Painter->RemoveObservers(vtkCommand::ProgressEvent, this->Observer);
|
|
this->Painter->SetInformation(0);
|
|
}
|
|
vtkSetObjectBodyMacro(Painter, vtkPainter, p);
|
|
|
|
if (this->Painter)
|
|
{
|
|
this->Painter->AddObserver(vtkCommand::ProgressEvent, this->Observer);
|
|
this->Painter->SetInformation(this->PainterInformation);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainterPolyDataMapper::SetSelectionPainter(vtkPainter* p)
|
|
{
|
|
if (this->SelectionPainter)
|
|
{
|
|
this->SelectionPainter->SetInformation(0);
|
|
this->SelectionPainter->RemoveObservers(vtkCommand::ProgressEvent, this->Observer);
|
|
}
|
|
vtkSetObjectBodyMacro(SelectionPainter, vtkPainter, p);
|
|
if (this->SelectionPainter)
|
|
{
|
|
this->SelectionPainter->AddObserver(vtkCommand::ProgressEvent, this->Observer);
|
|
this->SelectionPainter->SetInformation(this->PainterInformation);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainterPolyDataMapper::ReportReferences(vtkGarbageCollector *collector)
|
|
{
|
|
this->Superclass::ReportReferences(collector);
|
|
vtkGarbageCollectorReport(collector, this->Painter, "Painter");
|
|
vtkGarbageCollectorReport(collector, this->SelectionPainter, "SelectionPainter");
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainterPolyDataMapper::ReleaseGraphicsResources(vtkWindow *w)
|
|
{
|
|
if (this->Painter)
|
|
{
|
|
this->Painter->ReleaseGraphicsResources(w);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainterPolyDataMapper::UpdatePainterInformation()
|
|
{
|
|
vtkInformation* info = this->PainterInformation;
|
|
|
|
info->Set(vtkPainter::STATIC_DATA(), this->Static);
|
|
|
|
info->Set(vtkScalarsToColorsPainter::USE_LOOKUP_TABLE_SCALAR_RANGE(),
|
|
this->GetUseLookupTableScalarRange());
|
|
info->Set(vtkScalarsToColorsPainter::SCALAR_RANGE(),
|
|
this->GetScalarRange(), 2);
|
|
info->Set(vtkScalarsToColorsPainter::SCALAR_MODE(), this->GetScalarMode());
|
|
info->Set(vtkScalarsToColorsPainter::COLOR_MODE(), this->GetColorMode());
|
|
info->Set(vtkScalarsToColorsPainter::INTERPOLATE_SCALARS_BEFORE_MAPPING(),
|
|
this->GetInterpolateScalarsBeforeMapping());
|
|
info->Set(vtkScalarsToColorsPainter::LOOKUP_TABLE(), this->LookupTable);
|
|
info->Set(vtkScalarsToColorsPainter::SCALAR_VISIBILITY(),
|
|
this->GetScalarVisibility());
|
|
info->Set(vtkScalarsToColorsPainter::ARRAY_ACCESS_MODE(),
|
|
this->ArrayAccessMode);
|
|
info->Set(vtkScalarsToColorsPainter::ARRAY_ID(), this->ArrayId);
|
|
info->Set(vtkScalarsToColorsPainter::ARRAY_NAME(), this->ArrayName);
|
|
info->Set(vtkScalarsToColorsPainter::ARRAY_COMPONENT(), this->ArrayComponent);
|
|
info->Set(vtkScalarsToColorsPainter::FIELD_DATA_TUPLE_ID(), this->FieldDataTupleId);
|
|
info->Set(vtkScalarsToColorsPainter::SCALAR_MATERIAL_MODE(),
|
|
this->GetScalarMaterialMode());
|
|
|
|
info->Set(vtkClipPlanesPainter::CLIPPING_PLANES(), this->ClippingPlanes);
|
|
|
|
info->Set(vtkCoincidentTopologyResolutionPainter::RESOLVE_COINCIDENT_TOPOLOGY(),
|
|
this->GetResolveCoincidentTopology());
|
|
info->Set(vtkCoincidentTopologyResolutionPainter::Z_SHIFT(),
|
|
this->GetResolveCoincidentTopologyZShift());
|
|
double p[2];
|
|
this->GetResolveCoincidentTopologyPolygonOffsetParameters(p[0], p[1]);
|
|
info->Set(vtkCoincidentTopologyResolutionPainter::POLYGON_OFFSET_PARAMETERS(),
|
|
p, 2);
|
|
info->Set(vtkCoincidentTopologyResolutionPainter::POLYGON_OFFSET_FACES(),
|
|
this->GetResolveCoincidentTopologyPolygonOffsetFaces());
|
|
|
|
int immr = (this->ImmediateModeRendering ||
|
|
vtkMapper::GetGlobalImmediateModeRendering());
|
|
info->Set(vtkDisplayListPainter::IMMEDIATE_MODE_RENDERING(), immr);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainterPolyDataMapper::RenderPiece(vtkRenderer* ren, vtkActor* act)
|
|
{
|
|
vtkDataObject *input= this->GetInputDataObject(0, 0);
|
|
|
|
vtkStandardPolyDataPainter * painter =
|
|
vtkStandardPolyDataPainter::SafeDownCast(this->Painter);
|
|
if (painter != NULL && vtkPolyData::SafeDownCast(input))
|
|
{
|
|
// FIXME: This is not supported currently for composite datasets.
|
|
vtkInformationVector *inArrayVec =
|
|
this->Information->Get(INPUT_ARRAYS_TO_PROCESS());
|
|
int numArrays = (inArrayVec?inArrayVec->GetNumberOfInformationObjects():0);
|
|
|
|
for(int i = 0; i < numArrays; i++)
|
|
{
|
|
painter->AddMultiTextureCoordsArray(this->GetInputArrayToProcess(i,input));
|
|
}
|
|
}
|
|
|
|
//
|
|
// make sure that we've been properly initialized
|
|
//
|
|
if (ren->GetRenderWindow()->CheckAbortStatus())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( input == NULL )
|
|
{
|
|
vtkErrorMacro(<< "No input!");
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
this->InvokeEvent(vtkCommand::StartEvent,NULL);
|
|
if (!this->Static)
|
|
{
|
|
this->GetInputAlgorithm()->Update();
|
|
}
|
|
this->InvokeEvent(vtkCommand::EndEvent,NULL);
|
|
|
|
// This check is unnecessary since the mapper will be cropped out by culling
|
|
// if it returns invalid bounds which is what will happen when input has no
|
|
// points.
|
|
// vtkIdType numPts = input->GetNumberOfPoints();
|
|
// if (numPts == 0)
|
|
// {
|
|
// vtkDebugMacro(<< "No points!");
|
|
// return;
|
|
// }
|
|
}
|
|
|
|
// Update Painter information if obsolete.
|
|
if (this->PainterUpdateTime < this->GetMTime())
|
|
{
|
|
this->UpdatePainterInformation();
|
|
this->PainterUpdateTime.Modified();
|
|
}
|
|
|
|
// make sure our window is current
|
|
ren->GetRenderWindow()->MakeCurrent();
|
|
this->TimeToDraw = 0.0;
|
|
|
|
// If we are rendering in selection mode, then we use the selection painter
|
|
// instead of the standard painter.
|
|
if (this->SelectionPainter && ren->GetSelector())
|
|
{
|
|
this->SelectionPainter->SetInput(input);
|
|
this->SelectionPainter->Render(ren, act, 0xff,
|
|
(this->ForceCompileOnly==1));
|
|
this->TimeToDraw = this->SelectionPainter->GetTimeToDraw();
|
|
}
|
|
else if (this->SelectionPainter && this->SelectionPainter != this->Painter)
|
|
{
|
|
this->SelectionPainter->ReleaseGraphicsResources(ren->GetRenderWindow());
|
|
}
|
|
|
|
if (this->Painter && ren->GetSelector() == 0)
|
|
{
|
|
// Pass polydata.
|
|
this->Painter->SetInput(input);
|
|
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 vtkPainterPolyDataMapper::ComputeBounds()
|
|
{
|
|
if (!this->GetInput())
|
|
{
|
|
vtkMath::UninitializeBounds(this->Bounds);
|
|
return;
|
|
}
|
|
|
|
this->GetInput()->GetBounds(this->Bounds);
|
|
|
|
// if the mapper has a painter, update the bounds in the painter
|
|
vtkPainter *painter = this->GetPainter();
|
|
if (painter)
|
|
{
|
|
// Update Painter information if obsolete.
|
|
if (this->PainterUpdateTime < this->GetMTime())
|
|
{
|
|
this->UpdatePainterInformation();
|
|
this->PainterUpdateTime.Modified();
|
|
}
|
|
painter->UpdateBounds(this->Bounds);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool vtkPainterPolyDataMapper::GetIsOpaque()
|
|
{
|
|
if (this->ScalarVisibility &&
|
|
(this->ColorMode == VTK_COLOR_MODE_DEFAULT ||
|
|
this->ColorMode == VTK_COLOR_MODE_DIRECT_SCALARS))
|
|
{
|
|
vtkPolyData* input =
|
|
vtkPolyData::SafeDownCast(this->GetInputDataObject(0, 0));
|
|
if (input)
|
|
{
|
|
int cellFlag;
|
|
vtkDataArray* scalars = this->GetScalars(input,
|
|
this->ScalarMode, this->ArrayAccessMode, this->ArrayId,
|
|
this->ArrayName, cellFlag);
|
|
|
|
if (scalars &&
|
|
(scalars->IsA("vtkUnsignedCharArray") ||
|
|
this->ColorMode == VTK_COLOR_MODE_DIRECT_SCALARS) &&
|
|
(scalars->GetNumberOfComponents() == 4 /*(RGBA)*/ ||
|
|
scalars->GetNumberOfComponents() == 2 /*(LuminanceAlpha)*/))
|
|
{
|
|
int opacityIndex = scalars->GetNumberOfComponents() - 1;
|
|
unsigned char opacity = 0;
|
|
switch (scalars->GetDataType())
|
|
{
|
|
vtkTemplateMacro(
|
|
vtkScalarsToColors::ColorToUChar(
|
|
static_cast<VTK_TT>(scalars->GetRange(opacityIndex)[0]),
|
|
&opacity));
|
|
}
|
|
if (opacity < 255)
|
|
{
|
|
// If the opacity is 255, despite the fact that the user specified
|
|
// RGBA, we know that the Alpha is 100% opaque. So treat as opaque.
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return this->Superclass::GetIsOpaque();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainterPolyDataMapper::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
os << indent << "Painter: " ;
|
|
if (this->Painter)
|
|
{
|
|
os << endl;
|
|
this->Painter->PrintSelf(os, indent.GetNextIndent());
|
|
}
|
|
else
|
|
{
|
|
os << indent << "(none)" << endl;
|
|
}
|
|
os << indent << "SelectionPainter: " << this->SelectionPainter << endl;
|
|
}
|