Color texture generated by vtkMapper can be incorrect
When activating the color texture on vtkMapper using the "InterpolateScalarsBeforeMapping" flag and using above and below range colors, the generated texture can be wrong, omitting the last color preceding the "Above Range" color. The code to reproduce the bug:
#include <vtkNew.h>
#include <vtkPolyData.h>
#include <vtkPlaneSource.h>
#include <vtkDoubleArray.h>
#include <vtkPointData.h>
#include <vtkColorSeries.h>
#include <vtkLookupTable.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkScalarBarActor.h>
#include <vtkRenderer.h>
#include <vtkCamera.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
int main(int, char *[])
{
// The maximum point scalar value
const double maxValue = 867552144.0; // trigger the bug
//const double maxValue = 900000000.0; // no bug
// The plane dimension
const double dim = 10.0;
// Create a plane
vtkNew<vtkPlaneSource> source;
source->SetOrigin(-dim, -dim, 0.0);
source->SetPoint2(-dim, dim, 0.0);
source->SetPoint1(dim, -dim, 0.0);
source->SetXResolution(20);
source->SetYResolution(20);
source->Update();
vtkPolyData* plane = source->GetOutput();
// Generate waves
vtkIdType numberOfPoints = plane->GetPoints()->GetNumberOfPoints();
vtkNew<vtkDoubleArray> scalars;
scalars->SetNumberOfValues(numberOfPoints);
double invRadiusMax = maxValue / dim;
for (vtkIdType i = 0; i < numberOfPoints; ++i)
{
double* value = plane->GetPoints()->GetPoint(i);
double radius = sqrt(pow(value[0], 2) + pow(value[1], 2));
scalars->SetValue(i, maxValue - invRadiusMax * radius);
}
plane->GetPointData()->SetScalars(scalars.Get());
// Create the LUT and affect its special colors
vtkNew<vtkColorSeries> colorSeries;
colorSeries->SetColorScheme(vtkColorSeries::BREWER_DIVERGING_SPECTRAL_11);
vtkNew<vtkLookupTable> lut;
lut->SetNanColor(1, 0, 0, 1);
lut->SetAboveRangeColor(0.0, 1.0, 0.0, 1.0);
lut->UseAboveRangeColorOn();
lut->SetBelowRangeColor(0.0, 0.0, 1.0, 1.0);
lut->UseBelowRangeColorOn();
colorSeries->BuildLookupTable(lut.Get(), 0);
lut->SetTableRange(0.0, maxValue);
// Create the mapper
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputData(plane);
// Set the mapper LUT and activate the color texture mapping
mapper->SetLookupTable(lut.Get());
mapper->UseLookupTableScalarRangeOn();
mapper->InterpolateScalarsBeforeMappingOn();
// Create the actor
vtkNew<vtkActor> actor;
actor->SetMapper(mapper.Get());
actor->RotateX(-45);
actor->RotateZ(45);
// Add a scalar bar
vtkNew<vtkScalarBarActor> scalarBar;
scalarBar->SetLookupTable(lut.Get());
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer.Get());
vtkNew<vtkRenderWindowInteractor> interactor;
interactor->SetRenderWindow(renderWindow.Get());
// add actors
renderer->AddViewProp(actor.Get());
renderer->AddActor2D(scalarBar.Get());
renderer->SetBackground(0.7, 0.8, 1.0);
renderWindow->SetSize(800, 800);
renderWindow->Render();
renderer->GetActiveCamera()->Zoom(1.5);
interactor->Render();
interactor->Start();
return EXIT_SUCCESS;
}
The renderer showing the bug: the color in the middle should be purple instead if the above range green color:
This is how the renderer should look like:
The bug is easy to fix, I'll provide a patch.