3a812b044e
Changed the "default" ColorTable preset from "cool to warm" to "viridis." Also made a default constructor for ColorTable that sets it to this default preset. The main reason to change to viridis for the default is that it is in LAB space. We are concerned that having the default ColorTable preset being Diverging space could lead to users using that color space inappropriately.
520 lines
21 KiB
C++
520 lines
21 KiB
C++
//============================================================================
|
|
// Copyright (c) Kitware, Inc.
|
|
// All rights reserved.
|
|
// See LICENSE.txt 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.
|
|
//
|
|
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
|
// Copyright 2014 UT-Battelle, LLC.
|
|
// Copyright 2014 Los Alamos National Security.
|
|
//
|
|
// Under the terms of Contract DE-NA0003525 with NTESS,
|
|
// the U.S. Government retains certain rights in this software.
|
|
//
|
|
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
|
// Laboratory (LANL), the U.S. Government retains certain rights in
|
|
// this software.
|
|
//============================================================================
|
|
#ifndef vtk_m_cont_testing_TestingColorTable_h
|
|
#define vtk_m_cont_testing_TestingColorTable_h
|
|
|
|
#include <vtkm/Types.h>
|
|
#include <vtkm/cont/ColorTable.h>
|
|
#include <vtkm/cont/ColorTableSamples.h>
|
|
#include <vtkm/cont/testing/Testing.h>
|
|
|
|
// Required for implementation of ArrayRangeCompute for "odd" arrays
|
|
#include <vtkm/cont/ArrayRangeCompute.hxx>
|
|
|
|
// Required for implementation of ColorTable
|
|
#include <vtkm/cont/ColorTable.hxx>
|
|
|
|
#include <algorithm>
|
|
#include <iostream>
|
|
|
|
namespace vtkm
|
|
{
|
|
namespace cont
|
|
{
|
|
namespace testing
|
|
{
|
|
|
|
template <typename DeviceAdapterTag>
|
|
class TestingColorTable
|
|
{
|
|
|
|
public:
|
|
static void TestConstructors()
|
|
{
|
|
vtkm::Range inValidRange{ 1.0, 0.0 };
|
|
vtkm::Range range{ 0.0, 1.0 };
|
|
vtkm::Vec<float, 3> rgb1{ 0.0f, 0.0f, 0.0f };
|
|
vtkm::Vec<float, 3> rgb2{ 1.0f, 1.0f, 1.0f };
|
|
auto rgbspace = vtkm::cont::ColorSpace::RGB;
|
|
auto hsvspace = vtkm::cont::ColorSpace::HSV;
|
|
auto diverging = vtkm::cont::ColorSpace::DIVERGING;
|
|
|
|
vtkm::cont::ColorTable table(rgbspace);
|
|
VTKM_TEST_ASSERT(table.GetColorSpace() == rgbspace, "color space not saved");
|
|
VTKM_TEST_ASSERT(table.GetRange() == inValidRange, "default range incorrect");
|
|
|
|
vtkm::cont::ColorTable tableRGB(range, rgb1, rgb2, hsvspace);
|
|
VTKM_TEST_ASSERT(tableRGB.GetColorSpace() == hsvspace, "color space not saved");
|
|
VTKM_TEST_ASSERT(tableRGB.GetRange() == range, "color range not saved");
|
|
|
|
vtkm::Vec<float, 4> rgba1{ 0.0f, 0.0f, 0.0f, 1.0f };
|
|
vtkm::Vec<float, 4> rgba2{ 1.0f, 1.0f, 1.0f, 0.0f };
|
|
vtkm::cont::ColorTable tableRGBA(range, rgba1, rgba2, diverging);
|
|
VTKM_TEST_ASSERT(tableRGBA.GetColorSpace() == diverging, "color space not saved");
|
|
VTKM_TEST_ASSERT(tableRGBA.GetRange() == range, "color range not saved");
|
|
}
|
|
|
|
static void TestLoadPresets()
|
|
{
|
|
vtkm::Range range{ 0.0, 1.0 };
|
|
auto rgbspace = vtkm::cont::ColorSpace::RGB;
|
|
auto hsvspace = vtkm::cont::ColorSpace::HSV;
|
|
auto labspace = vtkm::cont::ColorSpace::LAB;
|
|
auto diverging = vtkm::cont::ColorSpace::DIVERGING;
|
|
|
|
vtkm::cont::ColorTable table(rgbspace);
|
|
VTKM_TEST_ASSERT(table.LoadPreset("Linear YGB"), "failed to find Linear YGB preset");
|
|
VTKM_TEST_ASSERT(table.GetColorSpace() == labspace,
|
|
"color space not switched when loading preset");
|
|
VTKM_TEST_ASSERT(table.GetRange() == range, "color range not correct after loading preset");
|
|
VTKM_TEST_ASSERT(table.GetNumberOfPoints() == 22,
|
|
"color range not correct after loading preset");
|
|
|
|
table.SetColorSpace(diverging);
|
|
VTKM_TEST_ASSERT(table.LoadPreset("inferno"), "failed to find inferno");
|
|
VTKM_TEST_ASSERT(table.GetColorSpace() == labspace,
|
|
"color space not switched when loading preset");
|
|
VTKM_TEST_ASSERT(table.GetRange() == range, "color range not correct after loading preset");
|
|
VTKM_TEST_ASSERT(table.GetNumberOfPoints() == 256,
|
|
"color range not correct after loading preset");
|
|
|
|
|
|
table.SetColorSpace(hsvspace);
|
|
VTKM_TEST_ASSERT((table.LoadPreset("no table with this name") == false),
|
|
"failed to error out on bad preset table name");
|
|
//verify that after a failure we still have the previous preset loaded
|
|
VTKM_TEST_ASSERT(table.GetColorSpace() == hsvspace,
|
|
"color space not switched when loading preset");
|
|
VTKM_TEST_ASSERT(table.GetRange() == range, "color range not correct after loading preset");
|
|
VTKM_TEST_ASSERT(table.GetNumberOfPoints() == 256,
|
|
"color range not correct after loading preset");
|
|
|
|
|
|
//verify that we can get the presets
|
|
std::set<std::string> names = table.GetPresets();
|
|
VTKM_TEST_ASSERT(names.size() == 15, "incorrect number of names in preset set");
|
|
|
|
VTKM_TEST_ASSERT(names.count("inferno") == 1, "names should contain inferno");
|
|
VTKM_TEST_ASSERT(names.count("black-body radiation") == 1,
|
|
"names should contain black-body radiation");
|
|
VTKM_TEST_ASSERT(names.count("viridis") == 1, "names should contain viridis");
|
|
VTKM_TEST_ASSERT(names.count("black, blue and white") == 1,
|
|
"names should contain black, blue and white");
|
|
VTKM_TEST_ASSERT(names.count("samsel fire") == 1, "names should contain samsel fire");
|
|
VTKM_TEST_ASSERT(names.count("jet") == 1, "names should contain jet");
|
|
}
|
|
|
|
static void TestClamping()
|
|
{
|
|
vtkm::Range range{ 0.0, 1.0 };
|
|
vtkm::Vec<float, 3> rgb1{ 0.0f, 1.0f, 0.0f };
|
|
vtkm::Vec<float, 3> rgb2{ 1.0f, 0.0f, 1.0f };
|
|
auto rgbspace = vtkm::cont::ColorSpace::RGB;
|
|
|
|
vtkm::cont::ColorTable table(range, rgb1, rgb2, rgbspace);
|
|
VTKM_TEST_ASSERT(table.GetClamping() == true, "clamping not setup properly");
|
|
|
|
constexpr vtkm::Id nvals = 4;
|
|
constexpr int data[nvals] = { -1, 0, 1, 2 };
|
|
auto field = vtkm::cont::make_ArrayHandle(data, nvals);
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>> colors;
|
|
const bool ran = table.Map(field, colors);
|
|
VTKM_TEST_ASSERT(ran, "color table failed to execute");
|
|
|
|
//verify that we clamp the values to the expected range
|
|
const vtkm::Vec<vtkm::UInt8, 3> correct[nvals] = {
|
|
{ 0, 255, 0 }, { 0, 255, 0 }, { 255, 0, 255 }, { 255, 0, 255 }
|
|
};
|
|
auto portal = colors.GetPortalConstControl();
|
|
for (std::size_t i = 0; i < nvals; ++i)
|
|
{
|
|
auto result = portal.Get(static_cast<vtkm::Id>(i));
|
|
VTKM_TEST_ASSERT(result == correct[i], "incorrect value in color from clamp test");
|
|
}
|
|
}
|
|
|
|
static void TestRangeColors()
|
|
{
|
|
vtkm::Range range{ -1.0, 2.0 };
|
|
vtkm::Vec<float, 3> rgb1{ 0.0f, 1.0f, 0.0f };
|
|
vtkm::Vec<float, 3> rgb2{ 1.0f, 0.0f, 1.0f };
|
|
auto rgbspace = vtkm::cont::ColorSpace::RGB;
|
|
|
|
vtkm::cont::ColorTable table(range, rgb1, rgb2, rgbspace);
|
|
table.SetClampingOff();
|
|
VTKM_TEST_ASSERT(table.GetClamping() == false, "clamping not setup properly");
|
|
|
|
constexpr vtkm::Id nvals = 4;
|
|
constexpr int data[nvals] = { -2, -1, 2, 3 };
|
|
auto field = vtkm::cont::make_ArrayHandle(data, nvals);
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>> colors;
|
|
const bool ran = table.Map(field, colors);
|
|
VTKM_TEST_ASSERT(ran, "color table failed to execute");
|
|
|
|
//verify that both the above and below range colors are used,
|
|
//and that the default value of both is 0,0,0
|
|
const vtkm::Vec<vtkm::UInt8, 3> correct_range_defaults[nvals] = {
|
|
{ 0, 0, 0 }, { 0, 255, 0 }, { 255, 0, 255 }, { 0, 0, 0 }
|
|
};
|
|
auto portal = colors.GetPortalConstControl();
|
|
for (std::size_t i = 0; i < nvals; ++i)
|
|
{
|
|
auto result = portal.Get(static_cast<vtkm::Id>(i));
|
|
VTKM_TEST_ASSERT(result == correct_range_defaults[i],
|
|
"incorrect value in color from default range color test");
|
|
}
|
|
|
|
|
|
//verify that we can specify custom above and below range colors
|
|
table.SetAboveRangeColor(vtkm::Vec<float, 3>{ 1.0f, 0.0f, 0.0f }); //red
|
|
table.SetBelowRangeColor(vtkm::Vec<float, 3>{ 0.0f, 0.0f, 1.0f }); //green
|
|
const bool ran2 = table.Map(field, colors);
|
|
VTKM_TEST_ASSERT(ran2, "color table failed to execute");
|
|
const vtkm::Vec<vtkm::UInt8, 3> correct_custom_range_colors[nvals] = {
|
|
{ 0, 0, 255 }, { 0, 255, 0 }, { 255, 0, 255 }, { 255, 0, 0 }
|
|
};
|
|
portal = colors.GetPortalConstControl();
|
|
for (std::size_t i = 0; i < nvals; ++i)
|
|
{
|
|
auto result = portal.Get(static_cast<vtkm::Id>(i));
|
|
VTKM_TEST_ASSERT(result == correct_custom_range_colors[i],
|
|
"incorrect value in custom above/below range color test");
|
|
}
|
|
}
|
|
|
|
static void TestRescaleRange()
|
|
{
|
|
vtkm::Range range{ -100.0, 100.0 };
|
|
|
|
//implement a blue2yellow color table
|
|
vtkm::Vec<float, 3> rgb1{ 0.0f, 0.0f, 1.0f };
|
|
vtkm::Vec<float, 3> rgb2{ 1.0f, 1.0f, 0.0f };
|
|
auto lab = vtkm::cont::ColorSpace::LAB;
|
|
|
|
vtkm::cont::ColorTable table(range, rgb1, rgb2, lab);
|
|
table.AddPoint(0.0, vtkm::Vec<float, 3>{ 0.5f, 0.5f, 0.5f });
|
|
VTKM_TEST_ASSERT(table.GetRange() == range, "custom range not saved");
|
|
|
|
vtkm::cont::ColorTable newTable = table.MakeDeepCopy();
|
|
VTKM_TEST_ASSERT(newTable.GetRange() == range, "custom range not saved");
|
|
|
|
vtkm::Range normalizedRange{ 0.0, 50.0 };
|
|
newTable.RescaleToRange(normalizedRange);
|
|
VTKM_TEST_ASSERT(table.GetRange() == range, "deep copy not working properly");
|
|
VTKM_TEST_ASSERT(newTable.GetRange() == normalizedRange, "rescale of range failed");
|
|
VTKM_TEST_ASSERT(newTable.GetNumberOfPoints() == 3,
|
|
"rescaled has incorrect number of control points");
|
|
|
|
//Verify that the rescaled color table generates correct colors
|
|
constexpr vtkm::Id nvals = 6;
|
|
constexpr int data[nvals] = { 0, 10, 20, 30, 40, 50 };
|
|
auto field = vtkm::cont::make_ArrayHandle(data, nvals);
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>> colors;
|
|
const bool ran = newTable.Map(field, colors);
|
|
VTKM_TEST_ASSERT(ran, "color table failed to execute");
|
|
|
|
//values confirmed with ParaView 5.4
|
|
const vtkm::Vec<vtkm::UInt8, 3> correct_lab_values[nvals] = {
|
|
{ 0, 0, 255 }, { 105, 69, 204 }, { 126, 109, 153 },
|
|
{ 156, 151, 117 }, { 207, 202, 87 }, { 255, 255, 0 }
|
|
};
|
|
auto portal = colors.GetPortalConstControl();
|
|
for (std::size_t i = 0; i < nvals; ++i)
|
|
{
|
|
auto result = portal.Get(static_cast<vtkm::Id>(i));
|
|
VTKM_TEST_ASSERT(result == correct_lab_values[i],
|
|
"incorrect value in color after rescaling the color table");
|
|
}
|
|
}
|
|
|
|
static void TestAddPoints()
|
|
{
|
|
vtkm::Range initalRange{ 0, 1.0 };
|
|
vtkm::Range range{ -20, 20.0 };
|
|
auto rgbspace = vtkm::cont::ColorSpace::RGB;
|
|
|
|
vtkm::cont::ColorTable table(rgbspace);
|
|
table.AddPoint(-10.0, vtkm::Vec<float, 3>{ 0.0f, 1.0f, 1.0f });
|
|
table.AddPoint(-20.0, vtkm::Vec<float, 3>{ 1.0f, 1.0f, 1.0f });
|
|
table.AddPoint(20.0, vtkm::Vec<float, 3>{ 0.0f, 0.0f, 0.0f });
|
|
table.AddPoint(0.0, vtkm::Vec<float, 3>{ 0.0f, 0.0f, 1.0f });
|
|
|
|
VTKM_TEST_ASSERT(table.GetRange() == range, "adding points to make range expand properly");
|
|
VTKM_TEST_ASSERT(table.GetNumberOfPoints() == 4,
|
|
"adding points caused number of control points to be wrong");
|
|
|
|
constexpr vtkm::Id nvals = 3;
|
|
constexpr float data[nvals] = { 10.0f, -5.0f, -15.0f };
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>> colors;
|
|
auto field = vtkm::cont::make_ArrayHandle(data, nvals);
|
|
const bool ran = table.Map(field, colors);
|
|
VTKM_TEST_ASSERT(ran, "color table failed to execute");
|
|
|
|
const vtkm::Vec<vtkm::UInt8, 3> correct_rgb_values[nvals] = { { 0, 0, 128 },
|
|
{ 0, 128, 255 },
|
|
{ 128, 255, 255 } };
|
|
auto portal = colors.GetPortalConstControl();
|
|
for (std::size_t i = 0; i < nvals; ++i)
|
|
{
|
|
auto result = portal.Get(static_cast<vtkm::Id>(i));
|
|
VTKM_TEST_ASSERT(result == correct_rgb_values[i],
|
|
"incorrect value when interpolating between values");
|
|
}
|
|
}
|
|
|
|
static void TestAddSegments()
|
|
{
|
|
vtkm::Range range{ 0.0, 50.0 };
|
|
auto diverging = vtkm::cont::ColorSpace::DIVERGING;
|
|
|
|
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::COOL_TO_WARM);
|
|
VTKM_TEST_ASSERT(table.GetColorSpace() == diverging,
|
|
"color space not switched when loading preset");
|
|
|
|
|
|
//Opacity Ramp from 0 to 1
|
|
table.AddSegmentAlpha(0.0, 0.0f, 1.0, 1.0f);
|
|
VTKM_TEST_ASSERT(table.GetNumberOfPointsAlpha() == 2, "incorrect number of alpha points");
|
|
|
|
table.RescaleToRange(range);
|
|
|
|
//Verify that the opacity points have moved
|
|
vtkm::Vec<double, 4> opacityData;
|
|
table.GetPointAlpha(1, opacityData);
|
|
VTKM_TEST_ASSERT(opacityData[0] == range.Max, "rescale to range failed on opacity");
|
|
VTKM_TEST_ASSERT(opacityData[1] == 1.0, "rescale changed opacity values");
|
|
VTKM_TEST_ASSERT(opacityData[2] == 0.5, "rescale modified mid/sharp of opacity");
|
|
VTKM_TEST_ASSERT(opacityData[3] == 0.0, "rescale modified mid/sharp of opacity");
|
|
|
|
|
|
constexpr vtkm::Id nvals = 6;
|
|
constexpr int data[nvals] = { 0, 10, 20, 30, 40, 50 };
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>> colors;
|
|
auto field = vtkm::cont::make_ArrayHandle(data, nvals);
|
|
const bool ran = table.Map(field, colors);
|
|
VTKM_TEST_ASSERT(ran, "color table failed to execute");
|
|
|
|
//values confirmed with ParaView 5.4
|
|
const vtkm::Vec<vtkm::UInt8, 4> correct_diverging_values[nvals] = {
|
|
{ 59, 76, 192, 0 }, { 124, 159, 249, 51 }, { 192, 212, 245, 102 },
|
|
{ 242, 203, 183, 153 }, { 238, 133, 104, 204 }, { 180, 4, 38, 255 }
|
|
};
|
|
auto portal = colors.GetPortalConstControl();
|
|
for (std::size_t i = 0; i < nvals; ++i)
|
|
{
|
|
auto result = portal.Get(static_cast<vtkm::Id>(i));
|
|
VTKM_TEST_ASSERT(result == correct_diverging_values[i],
|
|
"incorrect value when interpolating between values");
|
|
}
|
|
}
|
|
|
|
static void TestRemovePoints()
|
|
{
|
|
auto hsv = vtkm::cont::ColorSpace::HSV;
|
|
|
|
vtkm::cont::ColorTable table(hsv);
|
|
//implement Blue to Red Rainbow color table
|
|
table.AddSegment(0,
|
|
vtkm::Vec<float, 3>{ 0.0f, 0.0f, 1.0f },
|
|
1., //second points color should be replaced by following segment
|
|
vtkm::Vec<float, 3>{ 1.0f, 0.0f, 0.0f });
|
|
|
|
table.AddPoint(-10.0, vtkm::Vec<float, 3>{ 0.0f, 1.0f, 1.0f });
|
|
table.AddPoint(-20.0, vtkm::Vec<float, 3>{ 1.0f, 1.0f, 1.0f });
|
|
table.AddPoint(20.0, vtkm::Vec<float, 3>{ 1.0f, 0.0f, 0.0f });
|
|
|
|
VTKM_TEST_ASSERT(table.RemovePoint(-10.) == true, "failed to remove a existing point");
|
|
VTKM_TEST_ASSERT(table.RemovePoint(-20.) == true, "failed to remove a existing point");
|
|
VTKM_TEST_ASSERT(table.RemovePoint(20.) == true, "failed to remove a existing point");
|
|
VTKM_TEST_ASSERT(table.RemovePoint(20.) == false, "can't remove a point that doesn't exist");
|
|
|
|
VTKM_TEST_ASSERT((table.GetRange() == vtkm::Range{ 0.0, 1.0 }),
|
|
"removing points didn't update range");
|
|
table.RescaleToRange(vtkm::Range{ 0.0, 50.0 });
|
|
|
|
constexpr vtkm::Id nvals = 6;
|
|
constexpr float data[nvals] = { 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f };
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>> colors;
|
|
auto field = vtkm::cont::make_ArrayHandle(data, nvals);
|
|
const bool ran = table.Map(field, colors);
|
|
VTKM_TEST_ASSERT(ran, "color table failed to execute");
|
|
|
|
//values confirmed with ParaView 5.4
|
|
const vtkm::Vec<vtkm::UInt8, 3> correct_hsv_values[nvals] = { { 0, 0, 255 }, { 0, 204, 255 },
|
|
{ 0, 255, 102 }, { 102, 255, 0 },
|
|
{ 255, 204, 0 }, { 255, 0, 0 } };
|
|
auto portal = colors.GetPortalConstControl();
|
|
for (std::size_t i = 0; i < nvals; ++i)
|
|
{
|
|
auto result = portal.Get(static_cast<vtkm::Id>(i));
|
|
VTKM_TEST_ASSERT(result == correct_hsv_values[i],
|
|
"incorrect value when interpolating between values");
|
|
}
|
|
}
|
|
|
|
static void TestOpacityOnlyPoints()
|
|
{
|
|
auto hsv = vtkm::cont::ColorSpace::HSV;
|
|
|
|
vtkm::cont::ColorTable table(hsv);
|
|
//implement only a color table
|
|
table.AddPointAlpha(0.0, 0.0f, 0.75f, 0.25f);
|
|
table.AddPointAlpha(1.0, 1.0f);
|
|
|
|
table.AddPointAlpha(10.0, 0.5f, 0.5f, 0.0f);
|
|
table.AddPointAlpha(-10.0, 0.0f);
|
|
table.AddPointAlpha(-20.0, 1.0f);
|
|
table.AddPointAlpha(20.0, 0.5f);
|
|
|
|
VTKM_TEST_ASSERT(table.RemovePointAlpha(10.) == true, "failed to remove a existing point");
|
|
VTKM_TEST_ASSERT(table.RemovePointAlpha(-10.) == true, "failed to remove a existing point");
|
|
VTKM_TEST_ASSERT(table.RemovePointAlpha(-20.) == true, "failed to remove a existing point");
|
|
VTKM_TEST_ASSERT(table.RemovePointAlpha(20.) == true, "failed to remove a existing point");
|
|
VTKM_TEST_ASSERT(table.RemovePointAlpha(20.) == false,
|
|
"can't remove a point that doesn't exist");
|
|
|
|
VTKM_TEST_ASSERT((table.GetRange() == vtkm::Range{ 0.0, 1.0 }),
|
|
"removing points didn't update range");
|
|
table.RescaleToRange(vtkm::Range{ 0.0, 50.0 });
|
|
|
|
constexpr vtkm::Id nvals = 6;
|
|
constexpr float data[nvals] = { 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f };
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>> colors;
|
|
auto field = vtkm::cont::make_ArrayHandle(data, nvals);
|
|
const bool ran = table.Map(field, colors);
|
|
VTKM_TEST_ASSERT(ran, "color table failed to execute");
|
|
|
|
//values confirmed with ParaView 5.4
|
|
const vtkm::Vec<vtkm::UInt8, 4> correct_opacity_values[nvals] = {
|
|
{ 0, 0, 0, 0 }, { 0, 0, 0, 1 }, { 0, 0, 0, 11 },
|
|
{ 0, 0, 0, 52 }, { 0, 0, 0, 203 }, { 0, 0, 0, 255 }
|
|
};
|
|
auto portal = colors.GetPortalConstControl();
|
|
for (std::size_t i = 0; i < nvals; ++i)
|
|
{
|
|
auto result = portal.Get(static_cast<vtkm::Id>(i));
|
|
VTKM_TEST_ASSERT(result == correct_opacity_values[i],
|
|
"incorrect value when interpolating between opacity values");
|
|
}
|
|
}
|
|
|
|
static void TestSampling()
|
|
{
|
|
|
|
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::LINEAR_GREEN);
|
|
VTKM_TEST_ASSERT((table.GetRange() == vtkm::Range{ 0.0, 1.0 }),
|
|
"loading linear green table failed with wrong range");
|
|
VTKM_TEST_ASSERT((table.GetNumberOfPoints() == 21),
|
|
"loading linear green table failed with number of control points");
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>> colors;
|
|
constexpr vtkm::Id nvals = 3;
|
|
table.Sample(3, colors);
|
|
|
|
const vtkm::Vec<vtkm::UInt8, 4> correct_sampling_points[nvals] = { { 14, 28, 31, 255 },
|
|
{ 21, 150, 21, 255 },
|
|
{ 255, 251, 230, 255 } };
|
|
auto portal = colors.GetPortalConstControl();
|
|
for (std::size_t i = 0; i < nvals; ++i)
|
|
{
|
|
auto result = portal.Get(static_cast<vtkm::Id>(i));
|
|
VTKM_TEST_ASSERT(result == correct_sampling_points[i],
|
|
"incorrect value when interpolating in linear green preset");
|
|
}
|
|
}
|
|
|
|
static void TestLookupTable()
|
|
{
|
|
//build a color table with clamping off and verify that sampling works
|
|
vtkm::Range range{ 0.0, 50.0 };
|
|
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::COOL_TO_WARM);
|
|
table.RescaleToRange(range);
|
|
table.SetClampingOff();
|
|
table.SetAboveRangeColor(vtkm::Vec<float, 3>{ 1.0f, 0.0f, 0.0f }); //red
|
|
table.SetBelowRangeColor(vtkm::Vec<float, 3>{ 0.0f, 0.0f, 1.0f }); //green
|
|
|
|
vtkm::cont::ColorTableSamplesRGB samples;
|
|
table.Sample(256, samples);
|
|
VTKM_TEST_ASSERT((samples.Samples.GetNumberOfValues() == 260), "invalid sample length");
|
|
|
|
constexpr vtkm::Id nvals = 8;
|
|
constexpr int data[nvals] = { -1, 0, 10, 20, 30, 40, 50, 60 };
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>> colors;
|
|
auto field = vtkm::cont::make_ArrayHandle(data, nvals);
|
|
const bool ran = table.Map(field, samples, colors);
|
|
VTKM_TEST_ASSERT(ran, "color table failed to execute");
|
|
|
|
//values confirmed with ParaView 5.4
|
|
const vtkm::Vec<vtkm::UInt8, 3> correct_diverging_values[nvals] = {
|
|
{ 0, 0, 255 }, { 59, 76, 192 }, { 122, 157, 248 }, { 191, 211, 246 },
|
|
{ 241, 204, 184 }, { 238, 134, 105 }, { 180, 4, 38 }, { 255, 0, 0 }
|
|
};
|
|
auto portal = colors.GetPortalConstControl();
|
|
for (std::size_t i = 0; i < nvals; ++i)
|
|
{
|
|
auto result = portal.Get(static_cast<vtkm::Id>(i));
|
|
VTKM_TEST_ASSERT(result == correct_diverging_values[i],
|
|
"incorrect value when interpolating between values");
|
|
}
|
|
}
|
|
|
|
|
|
struct TestAll
|
|
{
|
|
VTKM_CONT void operator()() const
|
|
{
|
|
TestConstructors();
|
|
TestLoadPresets();
|
|
TestClamping(); //this needs to also verify default opacity
|
|
TestRangeColors();
|
|
|
|
TestRescaleRange(); //uses Lab
|
|
TestAddPoints(); //uses RGB
|
|
TestAddSegments(); //uses Diverging && opacity
|
|
TestRemovePoints(); //use HSV
|
|
|
|
TestOpacityOnlyPoints();
|
|
|
|
TestSampling();
|
|
TestLookupTable();
|
|
}
|
|
};
|
|
|
|
static int Run()
|
|
{
|
|
//We need to verify the color table runs on this specific device
|
|
//so we need to force our single device
|
|
vtkm::cont::GetGlobalRuntimeDeviceTracker().ForceDevice(DeviceAdapterTag());
|
|
return vtkm::cont::testing::Testing::Run(TestAll());
|
|
}
|
|
};
|
|
}
|
|
}
|
|
}
|
|
#endif
|