Commit 04bf1a8a authored by Dan Lipsa's avatar Dan Lipsa Committed by Code Review
Browse files

Merge topic 'map-scalars-14943' into master

2d61deaa Add a test for VTK_COLOR_MODE_DIRECT_SCALARS
00de9a94 Add VTK_COLOR_MODE_DIRECT_SCALARS. See vtkScalarsToColors::MapScalars.
parents e5cc53ea 2d61deaa
......@@ -15,6 +15,7 @@
#include "vtkScalarsToColors.h"
#include "vtkAbstractArray.h"
#include "vtkCharArray.h"
#include "vtkStringArray.h"
#include "vtkTemplateAliasMacro.h"
#include "vtkUnsignedCharArray.h"
......@@ -211,10 +212,10 @@ unsigned char *vtkScalarsToColors::MapValue(double v)
this->GetColor(v, rgb);
double alpha = this->GetOpacity(v);
this->RGBABytes[0] = static_cast<unsigned char>(rgb[0]*255 + 0.5);
this->RGBABytes[1] = static_cast<unsigned char>(rgb[1]*255 + 0.5);
this->RGBABytes[2] = static_cast<unsigned char>(rgb[2]*255 + 0.5);
this->RGBABytes[3] = static_cast<unsigned char>(alpha*255 + 0.5);
this->RGBABytes[0] = ColorToUChar(rgb[0]);
this->RGBABytes[1] = ColorToUChar(rgb[1]);
this->RGBABytes[2] = ColorToUChar(rgb[2]);
this->RGBABytes[3] = ColorToUChar(alpha);
return this->RGBABytes;
}
......@@ -225,15 +226,15 @@ vtkUnsignedCharArray *vtkScalarsToColors::MapScalars(vtkDataArray *scalars,
{
int numberOfComponents = scalars->GetNumberOfComponents();
vtkUnsignedCharArray *newColors;
vtkUnsignedCharArray *colors;
// map scalars through lookup table only if needed
if (colorMode == VTK_COLOR_MODE_DEFAULT &&
(colors=vtkUnsignedCharArray::SafeDownCast(scalars)) != NULL)
if ((colorMode == VTK_COLOR_MODE_DEFAULT &&
vtkUnsignedCharArray::SafeDownCast(scalars) != NULL) ||
colorMode == VTK_COLOR_MODE_DIRECT_SCALARS)
{
newColors = this->
ConvertUnsignedCharToRGBA(colors, colors->GetNumberOfComponents(),
scalars->GetNumberOfTuples());
ConvertToRGBA(scalars, scalars->GetNumberOfComponents(),
scalars->GetNumberOfTuples());
}
else
{
......@@ -483,7 +484,7 @@ void vtkScalarsToColorsLuminanceToLuminanceAlpha(
const unsigned char *inPtr, unsigned char *outPtr, vtkIdType count,
int numComponents, double alpha)
{
unsigned char a = static_cast<unsigned char>(alpha*255 + 0.5);
unsigned char a = vtkScalarsToColors::ColorToUChar(alpha);
do
{
......@@ -495,15 +496,17 @@ void vtkScalarsToColorsLuminanceToLuminanceAlpha(
while (--count);
}
template<typename T>
void vtkScalarsToColorsLuminanceToRGBA(
const unsigned char *inPtr, unsigned char *outPtr, vtkIdType count,
const T *inPtr, unsigned char *outPtr, vtkIdType count,
int numComponents, double alpha)
{
unsigned char a = static_cast<unsigned char>(alpha*255 + 0.5);
unsigned char a = vtkScalarsToColors::ColorToUChar(alpha);
do
{
unsigned char l = inPtr[0];
unsigned char l = vtkScalarsToColors::ColorToUChar(inPtr[0]);
outPtr[0] = l;
outPtr[1] = l;
outPtr[2] = l;
......@@ -518,7 +521,7 @@ void vtkScalarsToColorsRGBToLuminanceAlpha(
const unsigned char *inPtr, unsigned char *outPtr, vtkIdType count,
int numComponents, double alpha)
{
unsigned char a = static_cast<unsigned char>(alpha*255 + 0.5);
unsigned char a = vtkScalarsToColors::ColorToUChar(alpha);
do
{
......@@ -534,17 +537,18 @@ void vtkScalarsToColorsRGBToLuminanceAlpha(
while (--count);
}
template<typename T>
void vtkScalarsToColorsRGBToRGBA(
const unsigned char *inPtr, unsigned char *outPtr, vtkIdType count,
const T *inPtr, unsigned char *outPtr, vtkIdType count,
int numComponents, double alpha)
{
unsigned char a = static_cast<unsigned char>(alpha*255 + 0.5);
unsigned char a = vtkScalarsToColors::ColorToUChar(alpha);
do
{
outPtr[0] = inPtr[0];
outPtr[1] = inPtr[1];
outPtr[2] = inPtr[2];
outPtr[0] = vtkScalarsToColors::ColorToUChar(inPtr[0]);
outPtr[1] = vtkScalarsToColors::ColorToUChar(inPtr[1]);
outPtr[2] = vtkScalarsToColors::ColorToUChar(inPtr[2]);
outPtr[3] = a;
inPtr += numComponents;
outPtr += 4;
......@@ -581,16 +585,17 @@ void vtkScalarsToColorsLuminanceAlphaToLuminanceAlpha(
}
}
template<typename T>
void vtkScalarsToColorsLuminanceAlphaToRGBA(
const unsigned char *inPtr, unsigned char *outPtr, vtkIdType count,
const T *inPtr, unsigned char *outPtr, vtkIdType count,
int numComponents, double alpha)
{
if (alpha >= 1)
{
do
{
unsigned char l = inPtr[0];
unsigned char a = inPtr[1];
unsigned char l = vtkScalarsToColors::ColorToUChar(inPtr[0]);
unsigned char a = vtkScalarsToColors::ColorToUChar(inPtr[1]);
outPtr[0] = l;
outPtr[1] = l;
outPtr[2] = l;
......@@ -604,8 +609,8 @@ void vtkScalarsToColorsLuminanceAlphaToRGBA(
{
do
{
unsigned char l = inPtr[0];
unsigned char a = inPtr[1];
unsigned char l = vtkScalarsToColors::ColorToUChar(inPtr[0]);
unsigned char a = vtkScalarsToColors::ColorToUChar(inPtr[1]);
outPtr[0] = l;
outPtr[1] = l;
outPtr[2] = l;
......@@ -636,18 +641,19 @@ void vtkScalarsToColorsRGBAToLuminanceAlpha(
while (--count);
}
template<typename T>
void vtkScalarsToColorsRGBAToRGBA(
const unsigned char *inPtr, unsigned char *outPtr, vtkIdType count,
const T *inPtr, unsigned char *outPtr, vtkIdType count,
int numComponents, double alpha)
{
if (alpha >= 1)
{
do
{
outPtr[0] = inPtr[0];
outPtr[1] = inPtr[1];
outPtr[2] = inPtr[2];
outPtr[3] = inPtr[3];
outPtr[0] = vtkScalarsToColors::ColorToUChar(inPtr[0]);
outPtr[1] = vtkScalarsToColors::ColorToUChar(inPtr[1]);
outPtr[2] = vtkScalarsToColors::ColorToUChar(inPtr[2]);
outPtr[3] = vtkScalarsToColors::ColorToUChar(inPtr[3]);
inPtr += numComponents;
outPtr += 4;
}
......@@ -657,9 +663,9 @@ void vtkScalarsToColorsRGBAToRGBA(
{
do
{
outPtr[0] = inPtr[0];
outPtr[1] = inPtr[1];
outPtr[2] = inPtr[2];
outPtr[0] = vtkScalarsToColors::ColorToUChar(inPtr[0]);
outPtr[1] = vtkScalarsToColors::ColorToUChar(inPtr[1]);
outPtr[2] = vtkScalarsToColors::ColorToUChar(inPtr[2]);
outPtr[3] = static_cast<unsigned char>(inPtr[3]*alpha + 0.5);
inPtr += numComponents;
outPtr += 4;
......@@ -785,7 +791,7 @@ void vtkScalarsToColorsLuminanceToLuminanceAlpha(
const T *inPtr, unsigned char *outPtr, vtkIdType count,
int numComponents, double shift, double scale, double alpha)
{
unsigned char a = static_cast<unsigned char>(alpha*255 + 0.5);
unsigned char a = vtkScalarsToColors::ColorToUChar(alpha);
static double minval = 0;
static double maxval = 255.0;
......@@ -809,7 +815,7 @@ void vtkScalarsToColorsLuminanceToRGBA(
const T *inPtr, unsigned char *outPtr, vtkIdType count,
int numComponents, double shift, double scale, double alpha)
{
unsigned char a = static_cast<unsigned char>(alpha*255 + 0.5);
unsigned char a = vtkScalarsToColors::ColorToUChar(alpha);
static double minval = 0;
static double maxval = 255.0;
......@@ -835,7 +841,7 @@ void vtkScalarsToColorsRGBToLuminanceAlpha(
const T *inPtr, unsigned char *outPtr, vtkIdType count,
int numComponents, double shift, double scale, double alpha)
{
unsigned char a = static_cast<unsigned char>(alpha*255 + 0.5);
unsigned char a = vtkScalarsToColors::ColorToUChar(alpha);
static double minval = 0;
static double maxval = 255.0;
......@@ -867,7 +873,7 @@ void vtkScalarsToColorsRGBToRGBA(
const T *inPtr, unsigned char *outPtr, vtkIdType count,
int numComponents, double shift, double scale, double alpha)
{
unsigned char a = static_cast<unsigned char>(alpha*255 + 0.5);
unsigned char a = vtkScalarsToColors::ColorToUChar(alpha);
static double minval = 0;
static double maxval = 255.0;
......@@ -1493,17 +1499,38 @@ void vtkScalarsToColors::MapScalarsThroughTable2(
delete [] newPtr;
}
// The callForAnyType is used to write generic code that works with any
// vtkDataArray derived types.
//
// This macro calls a template function (on the data type stored in the
// array). Example usage:
// callForAnyType(array, myFunc(static_cast<VTK_TT*>(data), arg2));
// where 'array' is a vtkDataArray and
// 'data' could be: array->GetVoidPointer(0)
#define callForAnyType(array, call) \
switch(array->GetDataType()) \
{ \
vtkTemplateMacro(call); \
}
//----------------------------------------------------------------------------
vtkUnsignedCharArray *vtkScalarsToColors::ConvertUnsignedCharToRGBA(
vtkUnsignedCharArray *colors, int numComp, int numTuples)
vtkUnsignedCharArray *vtkScalarsToColors::ConvertToRGBA(
vtkDataArray *colors, int numComp, int numTuples)
{
if (numComp == 4 && this->Alpha >= 1.0)
if (vtkCharArray::SafeDownCast(colors) != NULL)
{
colors->Register(this);
return colors;
vtkErrorMacro(<<"char type does not have enough values to hold a color");
return NULL;
}
if (numComp == 4 && this->Alpha >= 1.0 &&
vtkUnsignedCharArray::SafeDownCast(colors) != NULL)
{
vtkUnsignedCharArray* c = vtkUnsignedCharArray::SafeDownCast(colors);
c->Register(this);
return c;
}
unsigned char *cptr = colors->GetPointer(0);
vtkUnsignedCharArray *newColors = vtkUnsignedCharArray::New();
newColors->SetNumberOfComponents(4);
newColors->SetNumberOfTuples(numTuples);
......@@ -1520,23 +1547,31 @@ vtkUnsignedCharArray *vtkScalarsToColors::ConvertUnsignedCharToRGBA(
switch (numComp)
{
case 1:
vtkScalarsToColorsLuminanceToRGBA(
cptr, nptr, numTuples, numComp, alpha);
callForAnyType(
colors, vtkScalarsToColorsLuminanceToRGBA(
static_cast<VTK_TT*>(colors->GetVoidPointer(0)),
nptr, numTuples, numComp, alpha));
break;
case 2:
vtkScalarsToColorsLuminanceAlphaToRGBA(
cptr, nptr, numTuples, numComp, alpha);
callForAnyType(
colors, vtkScalarsToColorsLuminanceAlphaToRGBA(
static_cast<VTK_TT*>(colors->GetVoidPointer(0)),
nptr, numTuples, numComp, alpha));
break;
case 3:
vtkScalarsToColorsRGBToRGBA(
cptr, nptr, numTuples, numComp, alpha);
callForAnyType(
colors, vtkScalarsToColorsRGBToRGBA(
static_cast<VTK_TT*>(colors->GetVoidPointer(0)),
nptr, numTuples, numComp, alpha));
break;
case 4:
vtkScalarsToColorsRGBAToRGBA(
cptr, nptr, numTuples, numComp, alpha);
callForAnyType(
colors, vtkScalarsToColorsRGBAToRGBA(
static_cast<VTK_TT*>(colors->GetVoidPointer(0)),
nptr, numTuples, numComp, alpha));
break;
default:
......
......@@ -120,7 +120,12 @@ public:
// unsigned char RGBA array. The color mode determines the behavior
// of mapping. If VTK_COLOR_MODE_DEFAULT is set, then unsigned char
// data arrays are treated as colors (and converted to RGBA if
// necessary); otherwise, the data is mapped through this instance
// necessary); If VTK_COLOR_MODE_DIRECT_SCALARS is set, then all arrays
// are treated as colors (integer types are clamped in the range 0-255,
// floating point arrays are clamped in the range 0.0-1.0. Note 'char' does
// not have enough values to represent a color so mapping this type is
// considered an error);
// otherwise, the data is mapped through this instance
// of ScalarsToColors. The component argument is used for data
// arrays with more than one component; it indicates which component
// to use to do the blending. When the component argument is -1,
......@@ -208,13 +213,6 @@ public:
int inputIncrement,
int outputFormat);
// Description:
// An internal method used to convert a color array to RGBA. The
// method instantiates a vtkUnsignedCharArray and returns it. The user is
// responsible for managing the memory.
virtual vtkUnsignedCharArray *ConvertUnsignedCharToRGBA(
vtkUnsignedCharArray *colors, int numComp, int numTuples);
// Description:
// Copy the contents from another object.
virtual void DeepCopy(vtkScalarsToColors *o);
......@@ -316,6 +314,24 @@ public:
vtkGetMacro(IndexedLookup,int);
vtkBooleanMacro(IndexedLookup,int);
// Description:
// Converts a color from numeric type T to uchar. We assume the integral type
// is already in the range 0-255. If it is not, it is going to be truncated.
// Floating point types are assumed to be in interval 0.0-1.0
template<typename T> static
unsigned char ColorToUChar(T t)
{
return t;
}
template<typename T> static
void ColorToUChar(T t, unsigned char* dest)
{
*dest = ColorToUChar(t);
}
protected:
vtkScalarsToColors();
~vtkScalarsToColors();
......@@ -335,6 +351,14 @@ protected:
int numberOfComponents, int vectorSize,
int outputFormat);
// Description:
// An internal method used to convert a color array to RGBA. The
// method instantiates a vtkUnsignedCharArray and returns it. The user is
// responsible for managing the memory.
vtkUnsignedCharArray *ConvertToRGBA(
vtkDataArray *colors, int numComp, int numTuples);
// Description:
// An internal method for converting vectors to magnitudes, used as
// a preliminary step before doing magnitude mapping.
......@@ -381,4 +405,20 @@ private:
void operator=(const vtkScalarsToColors&); // Not implemented.
};
// Description:
// Specializations of vtkScalarsToColors::ColorToUChar
// Converts from a color in a floating point type in range 0.0-1.0 to a uchar
// in range 0-255.
template<> inline
unsigned char vtkScalarsToColors::ColorToUChar(double t)
{
return static_cast<unsigned char>(t*255 + 0.5);
}
template<> inline
unsigned char vtkScalarsToColors::ColorToUChar(float t)
{
return static_cast<unsigned char>(t*255 + 0.5);
}
#endif
......@@ -95,6 +95,7 @@
#define VTK_COLOR_MODE_DEFAULT 0
#define VTK_COLOR_MODE_MAP_SCALARS 1
#define VTK_COLOR_MODE_DIRECT_SCALARS 2
// Constants for InterpolationType
#define VTK_NEAREST_INTERPOLATION 0
......
......@@ -29,6 +29,7 @@
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkScalarBarActor.h"
#include "vtkScalarsToColors.h"
#include "vtkStructuredGrid.h"
#include "vtkStructuredGridGeometryFilter.h"
#include "vtkTextProperty.h"
......
......@@ -18,6 +18,7 @@ vtk_add_test_cxx(${vtk-module}CxxTests tests
TestBackfaceCulling.cxx
TestBareScalarsToColors.cxx
TestBlockOpacity.cxx
TestDirectScalarsToColors.cxx
TestDiscretizableColorTransferFunction.cxx,NO_VALID
TestEdgeFlags.cxx
TestFollowerPicking.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestDirectScalarsToColors.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 "vtkActor2D.h"
#include "vtkCharArray.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkImageData.h"
#include "vtkIntArray.h"
#include "vtkImageMapper.h"
#include "vtkLongArray.h"
#include "vtkNew.h"
#include "vtkPointData.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkScalarsToColors.h"
#include "vtkShortArray.h"
#include "vtkSmartPointer.h"
#include "vtkTestUtilities.h"
#include "vtkUnsignedCharArray.h"
#include "vtkUnsignedIntArray.h"
#include "vtkUnsignedLongArray.h"
#include "vtkUnsignedShortArray.h"
#include <math.h>
namespace {
template<typename T>
void UCharToColor(unsigned char src, T* dest)
{
*dest = src;
}
template<> inline
void UCharToColor(unsigned char src, double* dest)
{
*dest = ((static_cast<double>(src) / 255.0));
}
template<> inline
void UCharToColor(unsigned char src, float* dest)
{
*dest = (static_cast<float>(src) / 255.0);
}
};
template<typename T, typename BaseT>
void addViews (vtkRenderWindow* renWin, int typeIndex)
{
vtkNew<vtkScalarsToColors> map;
// Make the four sets of test scalars
vtkSmartPointer<T> inputs[4];
for (int ncomp = 1; ncomp <= 4; ncomp++)
{
int posX = ((ncomp - 1) & 1);
int posY = ((ncomp - 1) >> 1);
inputs[ncomp-1] = vtkSmartPointer<T>::New();
T *arr = inputs[ncomp-1].GetPointer();
arr->SetNumberOfComponents(ncomp);
arr->SetNumberOfTuples(6400);
// luminance conversion factors
static float a = 0.30;
static float b = 0.59;
static float c = 0.11;
static float d = 0.50;
static int f = 85;
BaseT cval[4];
vtkIdType i = 0;
for (int j = 0; j < 16; j++)
{
for (int jj = 0; jj < 5; jj++)
{
for (int k = 0; k < 16; k++)
{
cval[0] = (((k >> 2) & 3)*f);
cval[1] = ((k & 3)*f);
cval[2] = (((j >> 2) & 3)*f);
cval[3] = ((j & 3)*f);
float l = cval[0]*a + cval[1]*b + cval[2]*c + d;
unsigned char lc = static_cast<unsigned char>(l);
cval[0] = ((ncomp > 2 ? cval[0] : lc));
cval[1] = ((ncomp > 2 ? cval[1] : cval[3]));
// store values between 0 and 1 for floating point colors.
for (int index = 0; index < 4; ++index)
{
UCharToColor (cval[index], &cval[index]);
}
for (int kk = 0; kk < 5; kk++)
{
arr->SetTupleValue(i++, cval);
}
}
}
}
vtkNew<vtkImageData> image;
image->SetDimensions(80, 80, 1);
vtkUnsignedCharArray *colors =
map->MapScalars(arr, VTK_COLOR_MODE_DIRECT_SCALARS, -1);
if (colors == NULL)
{
continue;
}
image->GetPointData()->SetScalars(colors);
colors->Delete();
int pos[2];
pos[0] = (((typeIndex & 3) << 1) + posX) * 80;
pos[1] = ((((typeIndex >> 2) & 3) << 1) + posY) * 80;
vtkNew<vtkImageMapper> mapper;
mapper->SetColorWindow(255.0);
mapper->SetColorLevel(127.5);
mapper->SetInputData(image.GetPointer());
vtkNew<vtkActor2D> actor;
actor->SetMapper(mapper.GetPointer());
vtkNew<vtkRenderer> ren;
ren->AddViewProp(actor.GetPointer());
ren->SetViewport(pos[0]/640.0, pos[1]/640.0,
(pos[0] + 80)/640.0, (pos[1] + 80)/640.0);
renWin->AddRenderer(ren.GetPointer());
}
}
// Modified from TestBareScalarsToColors
int TestDirectScalarsToColors(int argc, char *argv[])
{
// Cases to check:
// 1, 2, 3, 4 components
vtkNew<vtkRenderWindow> renWin;
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin.GetPointer());
renWin->SetSize(640, 640);
int i = -1;
addViews<vtkUnsignedCharArray, unsigned char> (renWin.GetPointer(), ++i);
// This line generates an expected ERROR message.
// addViews<vtkCharArray, char>(renWin.GetPointer(), ++i);
addViews<vtkUnsignedShortArray, unsigned short> (renWin.GetPointer(), ++i);
addViews<vtkShortArray, short>(renWin.GetPointer(), ++i);
addViews<vtkUnsignedIntArray, unsigned int> (renWin.GetPointer(), ++i);
addViews<vtkIntArray, int>(renWin.GetPointer(), ++i);
addViews<vtkUnsignedLongArray, unsigned long> (renWin.GetPointer(), ++i);
addViews<vtkLongArray, long>(renWin.GetPointer(), ++i);
addViews<vtkFloatArray, float> (renWin.GetPointer(), ++i);
addViews<vtkDoubleArray, double>(renWin.GetPointer(), ++i);
// Mac-Lion-64-gcc-4.2.1 (kamino) does not clear the render window
// unless we create renderers for the whole window.
for (++i; i < 16; ++i)
{
int pos[2];
pos[0] = (i & 3) * 160;
pos[1] = ((i>>2) & 3) * 160;
vtkNew<vtkRenderer> ren;
ren->SetViewport(pos[0]/640.0, pos[1]/640.0,
(pos[0] + 160)/640.0, (pos[1] + 160)/640.0);
renWin->AddRenderer(ren.GetPointer());
}
renWin->Render();
int retVal = vtkRegressionTestImage(renWin.GetPointer());
if ( retVal == vtkRegressionTester::DO_INTERACTOR)