Remove virtual methods from ColorTable

Virtual methods are being deprecated, so remove their use from the
ColorTable classes. Instead of using a virtual method to look up a value
in the ColorTable, we essentially use a switch statement. This change
also simplified the code quite a bit.

The execution object used to use pointers to handle the virtual objects.
That is no longer necessary, so a simple `vtkm::exec::ColorTable` is
returned for execution objects. (Note that this `ColorTable` contains
pointers that are specific for the particular device.) This is a non-
backward compabible change. However, the only place (outside of the
`ColorTable` implementation itself) was a single worklet for converting
scalars to colors (`vtkm::worklet::colorconversion::TransferFunction`).
This is unlikely to affect anyone.

I also "fixed" some names in enum structs. There has been some
inconsistencies in VTK-m on whether items in an enum struct are
capitolized or camel case. We seem to moving toward camel case, so
deprecate some old names.
This commit is contained in:
Kenneth Moreland 2020-09-14 13:26:16 -06:00
parent fbb69b7655
commit 11996f133f
13 changed files with 1087 additions and 1141 deletions

@ -110,7 +110,6 @@ function(do_verify root_dir prefix)
)
set(file_exceptions
cont/ColorTablePrivate.hxx
thirdparty/diy/vtkmdiy/cmake/mpi_types.h
# Ignore deprecated virtual classes (which are not installed if VTKm_NO_DEPRECATED_VIRTUAL

File diff suppressed because it is too large Load Diff

@ -17,43 +17,35 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ColorTableSamples.h>
#include <vtkm/cont/ExecutionObjectBase.h>
#include <vtkm/exec/ColorTable.h>
#include <set>
namespace vtkm
{
namespace exec
{
//forward declare exec objects
class ColorTableBase;
}
namespace cont
{
template <typename T>
class VirtualObjectHandle;
namespace detail
{
struct ColorTableInternals;
}
enum struct ColorSpace
struct VTKM_DEPRECATED(1.6, "Use vtkm::ColorSpace.") ColorSpace
{
RGB,
HSV,
HSV_WRAP,
LAB,
DIVERGING
static constexpr vtkm::ColorSpace RGB = vtkm::ColorSpace::RGB;
static constexpr vtkm::ColorSpace HSV = vtkm::ColorSpace::HSV;
static constexpr vtkm::ColorSpace HSV_WRAP = vtkm::ColorSpace::HSVWrap;
static constexpr vtkm::ColorSpace LAB = vtkm::ColorSpace::Lab;
static constexpr vtkm::ColorSpace DIVERGING = vtkm::ColorSpace::Diverging;
};
/// \brief Color Table for coloring arbitrary fields
///
///
/// The vtkm::cont::ColorTable allows for color mapping in RGB or HSV space and
/// The `vtkm::cont::ColorTable` allows for color mapping in RGB or HSV space and
/// uses a piecewise hermite functions to allow opacity interpolation that can be
/// piecewise constant, piecewise linear, or somewhere in-between
/// (a modified piecewise hermite function that squishes the function
@ -76,51 +68,77 @@ enum struct ColorSpace
/// will default to to Midpoint = 0.5 (halfway between the control points) and
/// Sharpness = 0.0 (linear).
///
/// ColorTable also contains which ColorSpace should be used for interpolation
/// ColorTable also contains which ColorSpace should be used for interpolation.
/// The color space is selected with the `vtkm::ColorSpace` enumeration.
/// Currently the valid ColorSpaces are:
/// - RGB
/// - HSV
/// - HSV_WRAP
/// - LAB
/// - Diverging
/// - `RGB`
/// - `HSV`
/// - `HSVWrap`
/// - `Lab`
/// - `Diverging`
///
/// In HSV_WRAP mode, it will take the shortest path
/// In `HSVWrap` mode, it will take the shortest path
/// in Hue (going back through 0 if that is the shortest way around the hue
/// circle) whereas HSV will not go through 0 (in order the
/// match the current functionality of vtkLookupTable). In Lab mode,
/// circle) whereas HSV will not go through 0 (in order to
/// match the current functionality of `vtkLookupTable`). In `Lab` mode,
/// it will take the shortest path in the Lab color space with respect to the
/// CIE Delta E 2000 color distance measure. Diverging is a special
/// CIE Delta E 2000 color distance measure. `Diverging` is a special
/// mode where colors will pass through white when interpolating between two
/// saturated colors.
///
/// To map a field from a vtkm::cont::DataSet through the color and opacity transfer
/// functions and into a RGB or RGBA array you should use vtkm::filter::FieldToColor.
/// To map a field from a `vtkm::cont::DataSet` through the color and opacity transfer
/// functions and into a RGB or RGBA array you should use `vtkm::filter::FieldToColor`.
///
class VTKM_CONT_EXPORT ColorTable
/// Note that modifications of `vtkm::cont::ColorTable` are not thread safe. You should
/// not modify a `ColorTable` simultaneously in 2 or more threads. Also, you should not
/// modify a `ColorTable` that might be used in the execution environment. However,
/// the `ColorTable` can be used in multiple threads and on multiple devices as long
/// as no modifications are made.
///
class VTKM_CONT_EXPORT ColorTable : public vtkm::cont::ExecutionObjectBase
{
std::shared_ptr<detail::ColorTableInternals> Impl;
std::shared_ptr<detail::ColorTableInternals> Internals;
public:
enum struct Preset
{
DEFAULT,
COOL_TO_WARM,
COOL_TO_WARM_EXTENDED,
VIRIDIS,
INFERNO,
PLASMA,
BLACK_BODY_RADIATION,
X_RAY,
GREEN,
BLACK_BLUE_WHITE,
BLUE_TO_ORANGE,
GRAY_TO_RED,
COLD_AND_HOT,
BLUE_GREEN_ORANGE,
YELLOW_GRAY_BLUE,
RAINBOW_UNIFORM,
JET,
RAINBOW_DESATURATED
Default,
CoolToWarm,
CoolToWarmExtended,
Viridis,
Inferno,
Plasma,
BlackBodyRadiation,
XRay,
Green,
BlackBlueWhite,
BlueToOrange,
GrayToRed,
ColdAndHot,
BlueGreenOrange,
YellowGrayBlue,
RainbowUniform,
Jet,
RainbowDesaturated,
DEFAULT VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::Default."),
COOL_TO_WARM VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::CoolToWarm."),
COOL_TO_WARM_EXTENDED VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::CoolToWarmExtended."),
VIRIDIS VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::Viridis."),
INFERNO VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::Inferno."),
PLASMA VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::Plasma."),
BLACK_BODY_RADIATION VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::BlackBodyRadiation."),
X_RAY VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::XRay."),
GREEN VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::Green."),
BLACK_BLUE_WHITE VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::BlackBlueWhite."),
BLUE_TO_ORANGE VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::BlueToOrange."),
GRAY_TO_RED VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::GrayToRed."),
COLD_AND_HOT VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::ColdAndHot."),
BLUE_GREEN_ORANGE VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::BlueGreenOrange."),
YELLOW_GRAY_BLUE VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::YellowGrayBlue."),
RAINBOW_UNIFORM VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::RainbowUniform."),
JET VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::Jet."),
RAINBOW_DESATURATED VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::RainbowDesaturated.")
};
/// \brief Construct a color table from a preset
@ -130,7 +148,7 @@ public:
///
/// Note: these are a select set of the presets you can get by providing a string identifier.
///
ColorTable(vtkm::cont::ColorTable::Preset preset = vtkm::cont::ColorTable::Preset::DEFAULT);
ColorTable(vtkm::cont::ColorTable::Preset preset = vtkm::cont::ColorTable::Preset::Default);
/// \brief Construct a color table from a preset color table
///
@ -165,41 +183,42 @@ public:
///
/// Note: The color table will have 0 entries
/// Note: The alpha table will have 0 entries
explicit ColorTable(ColorSpace space);
explicit ColorTable(vtkm::ColorSpace space);
/// Construct a color table with a 2 positions
///
/// Note: The color table will have 2 entries of rgb = {1.0,1.0,1.0}
/// Note: The alpha table will have 2 entries of alpha = 1.0 with linear
/// interpolation
ColorTable(const vtkm::Range& range, ColorSpace space = ColorSpace::LAB);
ColorTable(const vtkm::Range& range, vtkm::ColorSpace space = vtkm::ColorSpace::Lab);
/// Construct a color table with 2 positions
//
/// Note: The alpha table will have 2 entries of alpha = 1.0 with linear
/// interpolation
ColorTable(const vtkm::Range& range,
const vtkm::Vec<float, 3>& rgb1,
const vtkm::Vec<float, 3>& rgb2,
ColorSpace space = ColorSpace::LAB);
const vtkm::Vec3f_32& rgb1,
const vtkm::Vec3f_32& rgb2,
vtkm::ColorSpace space = vtkm::ColorSpace::Lab);
/// Construct color and alpha and table with 2 positions
///
/// Note: The alpha table will use linear interpolation
ColorTable(const vtkm::Range& range,
const vtkm::Vec<float, 4>& rgba1,
const vtkm::Vec<float, 4>& rgba2,
ColorSpace space = ColorSpace::LAB);
const vtkm::Vec4f_32& rgba1,
const vtkm::Vec4f_32& rgba2,
vtkm::ColorSpace space = vtkm::ColorSpace::Lab);
/// Construct a color table with a list of colors and alphas. For this version you must also
/// specify a name.
///
/// This constructor is mostly used for presets.
ColorTable(const std::string& name,
vtkm::cont::ColorSpace colorSpace,
const vtkm::Vec<double, 3>& nanColor,
const std::vector<double>& rgbPoints,
const std::vector<double>& alphaPoints = { 0.0, 1.0, 0.5, 0.0, 1.0, 1.0, 0.5, 0.0 });
ColorTable(
const std::string& name,
vtkm::ColorSpace colorSpace,
const vtkm::Vec3f_64& nanColor,
const std::vector<vtkm::Float64>& rgbPoints,
const std::vector<vtkm::Float64>& alphaPoints = { 0.0, 1.0, 0.5, 0.0, 1.0, 1.0, 0.5, 0.0 });
~ColorTable();
@ -257,8 +276,8 @@ public:
ColorTable MakeDeepCopy();
///
ColorSpace GetColorSpace() const;
void SetColorSpace(ColorSpace space);
vtkm::ColorSpace GetColorSpace() const;
void SetColorSpace(vtkm::ColorSpace space);
/// If clamping is disabled values that lay out side
/// the color table range are colored based on Below
@ -274,19 +293,19 @@ public:
/// that is below the given range
///
/// Default value is {0,0,0}
void SetBelowRangeColor(const vtkm::Vec<float, 3>& c);
const vtkm::Vec<float, 3>& GetBelowRangeColor() const;
void SetBelowRangeColor(const vtkm::Vec3f_32& c);
const vtkm::Vec3f_32& GetBelowRangeColor() const;
/// Color to use when clamping is disabled for any value
/// that is above the given range
///
/// Default value is {0,0,0}
void SetAboveRangeColor(const vtkm::Vec<float, 3>& c);
const vtkm::Vec<float, 3>& GetAboveRangeColor() const;
void SetAboveRangeColor(const vtkm::Vec3f_32& c);
const vtkm::Vec3f_32& GetAboveRangeColor() const;
///
void SetNaNColor(const vtkm::Vec<float, 3>& c);
const vtkm::Vec<float, 3>& GetNaNColor() const;
void SetNaNColor(const vtkm::Vec3f_32& c);
const vtkm::Vec3f_32& GetNaNColor() const;
/// Remove all existing values in both color and alpha tables.
/// Does not remove the clamping, below, and above range state or colors.
@ -321,40 +340,40 @@ public:
///
/// Note: rgb values need to be between 0 and 1.0 (inclusive).
/// Return the index of the point (0 based), or -1 osn error.
vtkm::Int32 AddPoint(double x, const vtkm::Vec<float, 3>& rgb);
vtkm::Int32 AddPoint(vtkm::Float64 x, const vtkm::Vec3f_32& rgb);
/// Adds a point to the color function. If the point already exists, it
/// will be updated to the new value.
///
/// Note: hsv values need to be between 0 and 1.0 (inclusive).
/// Return the index of the point (0 based), or -1 on error.
vtkm::Int32 AddPointHSV(double x, const vtkm::Vec<float, 3>& hsv);
vtkm::Int32 AddPointHSV(vtkm::Float64 x, const vtkm::Vec3f_32& hsv);
/// Add a line segment to the color function. All points which lay between x1 and x2
/// (inclusive) are removed from the function.
///
/// Note: rgb1, and rgb2 values need to be between 0 and 1.0 (inclusive).
/// Return the index of the point x1 (0 based), or -1 on error.
vtkm::Int32 AddSegment(double x1,
const vtkm::Vec<float, 3>& rgb1,
double x2,
const vtkm::Vec<float, 3>& rgb2);
vtkm::Int32 AddSegment(vtkm::Float64 x1,
const vtkm::Vec3f_32& rgb1,
vtkm::Float64 x2,
const vtkm::Vec3f_32& rgb2);
/// Add a line segment to the color function. All points which lay between x1 and x2
/// (inclusive) are removed from the function.
///
/// Note: hsv1, and hsv2 values need to be between 0 and 1.0 (inclusive)
/// Return the index of the point x1 (0 based), or -1 on error
vtkm::Int32 AddSegmentHSV(double x1,
const vtkm::Vec<float, 3>& hsv1,
double x2,
const vtkm::Vec<float, 3>& hsv2);
vtkm::Int32 AddSegmentHSV(vtkm::Float64 x1,
const vtkm::Vec3f_32& hsv1,
vtkm::Float64 x2,
const vtkm::Vec3f_32& hsv2);
/// Get the location, and rgb information for an existing point in the opacity function.
///
/// Note: components 1-3 are rgb and will have values between 0 and 1.0 (inclusive)
/// Return the index of the point (0 based), or -1 on error.
bool GetPoint(vtkm::Int32 index, vtkm::Vec<double, 4>&) const;
bool GetPoint(vtkm::Int32 index, vtkm::Vec4f_64&) const;
/// Update the location, and rgb information for an existing point in the color function.
/// If the location value for the index is modified the point is removed from
@ -362,12 +381,12 @@ public:
///
/// Note: components 1-3 are rgb and must have values between 0 and 1.0 (inclusive).
/// Return the new index of the updated point (0 based), or -1 on error.
vtkm::Int32 UpdatePoint(vtkm::Int32 index, const vtkm::Vec<double, 4>&);
vtkm::Int32 UpdatePoint(vtkm::Int32 index, const vtkm::Vec4f_64&);
/// Remove the Color function point that exists at exactly x
///
/// Return true if the point x exists and has been removed
bool RemovePoint(double x);
bool RemovePoint(vtkm::Float64 x);
/// Remove the Color function point n
///
@ -385,14 +404,20 @@ public:
///
/// Note: alpha needs to be a value between 0 and 1.0 (inclusive).
/// Return the index of the point (0 based), or -1 on error.
vtkm::Int32 AddPointAlpha(double x, float alpha) { return AddPointAlpha(x, alpha, 0.5f, 0.0f); }
vtkm::Int32 AddPointAlpha(vtkm::Float64 x, vtkm::Float32 alpha)
{
return AddPointAlpha(x, alpha, 0.5f, 0.0f);
}
/// Adds a point to the opacity function. If the point already exists, it
/// will be updated to the new value.
///
/// Note: alpha, midpoint, and sharpness values need to be between 0 and 1.0 (inclusive)
/// Return the index of the point (0 based), or -1 on error.
vtkm::Int32 AddPointAlpha(double x, float alpha, float midpoint, float sharpness);
vtkm::Int32 AddPointAlpha(vtkm::Float64 x,
vtkm::Float32 alpha,
vtkm::Float32 midpoint,
vtkm::Float32 sharpness);
/// Add a line segment to the opacity function. All points which lay between x1 and x2
/// (inclusive) are removed from the function. Uses a midpoint of
@ -400,9 +425,12 @@ public:
///
/// Note: alpha values need to be between 0 and 1.0 (inclusive)
/// Return the index of the point x1 (0 based), or -1 on error
vtkm::Int32 AddSegmentAlpha(double x1, float alpha1, double x2, float alpha2)
vtkm::Int32 AddSegmentAlpha(vtkm::Float64 x1,
vtkm::Float32 alpha1,
vtkm::Float64 x2,
vtkm::Float32 alpha2)
{
vtkm::Vec<float, 2> mid_sharp(0.5f, 0.0f);
vtkm::Vec2f_32 mid_sharp(0.5f, 0.0f);
return AddSegmentAlpha(x1, alpha1, x2, alpha2, mid_sharp, mid_sharp);
}
@ -411,19 +439,19 @@ public:
///
/// Note: alpha, midpoint, and sharpness values need to be between 0 and 1.0 (inclusive)
/// Return the index of the point x1 (0 based), or -1 on error
vtkm::Int32 AddSegmentAlpha(double x1,
float alpha1,
double x2,
float alpha2,
const vtkm::Vec<float, 2>& mid_sharp1,
const vtkm::Vec<float, 2>& mid_sharp2);
vtkm::Int32 AddSegmentAlpha(vtkm::Float64 x1,
vtkm::Float32 alpha1,
vtkm::Float64 x2,
vtkm::Float32 alpha2,
const vtkm::Vec2f_32& mid_sharp1,
const vtkm::Vec2f_32& mid_sharp2);
/// Get the location, alpha, midpoint and sharpness information for an existing
/// point in the opacity function.
///
/// Note: alpha, midpoint, and sharpness values all will be between 0 and 1.0 (inclusive)
/// Return the index of the point (0 based), or -1 on error.
bool GetPointAlpha(vtkm::Int32 index, vtkm::Vec<double, 4>&) const;
bool GetPointAlpha(vtkm::Int32 index, vtkm::Vec4f_64&) const;
/// Update the location, alpha, midpoint and sharpness information for an existing
/// point in the opacity function.
@ -432,12 +460,12 @@ public:
///
/// Note: alpha, midpoint, and sharpness values need to be between 0 and 1.0 (inclusive)
/// Return the new index of the updated point (0 based), or -1 on error.
vtkm::Int32 UpdatePointAlpha(vtkm::Int32 index, const vtkm::Vec<double, 4>&);
vtkm::Int32 UpdatePointAlpha(vtkm::Int32 index, const vtkm::Vec4f_64&);
/// Remove the Opacity function point that exists at exactly x
///
/// Return true if the point x exists and has been removed
bool RemovePointAlpha(double x);
bool RemovePointAlpha(vtkm::Float64 x);
/// Remove the Opacity function point n
///
@ -447,9 +475,9 @@ public:
/// Returns the number of points in the alpha function
vtkm::Int32 GetNumberOfPointsAlpha() const;
/// Fill the Color table from a double pointer
/// Fill the Color table from a vtkm::Float64 pointer
///
/// The double pointer is required to have the layout out of [X1, R1,
/// The vtkm::Float64 pointer is required to have the layout out of [X1, R1,
/// G1, B1, X2, R2, G2, B2, ..., Xn, Rn, Gn, Bn] where n is the
/// number of nodes.
/// This will remove any existing color control points.
@ -458,11 +486,11 @@ public:
///
/// Note: This is provided as a interoperability method with VTK
/// Will return false and not modify anything if n is <= 0 or ptr == nullptr
bool FillColorTableFromDataPointer(vtkm::Int32 n, const double* ptr);
bool FillColorTableFromDataPointer(vtkm::Int32 n, const vtkm::Float64* ptr);
/// Fill the Color table from a float pointer
/// Fill the Color table from a vtkm::Float32 pointer
///
/// The double pointer is required to have the layout out of [X1, R1,
/// The vtkm::Float64 pointer is required to have the layout out of [X1, R1,
/// G1, B1, X2, R2, G2, B2, ..., Xn, Rn, Gn, Bn] where n is the
/// number of nodes.
/// This will remove any existing color control points.
@ -471,11 +499,11 @@ public:
///
/// Note: This is provided as a interoperability method with VTK
/// Will return false and not modify anything if n is <= 0 or ptr == nullptr
bool FillColorTableFromDataPointer(vtkm::Int32 n, const float* ptr);
bool FillColorTableFromDataPointer(vtkm::Int32 n, const vtkm::Float32* ptr);
/// Fill the Opacity table from a double pointer
/// Fill the Opacity table from a vtkm::Float64 pointer
///
/// The double pointer is required to have the layout out of [X1, A1, M1, S1, X2, A2, M2, S2,
/// The vtkm::Float64 pointer is required to have the layout out of [X1, A1, M1, S1, X2, A2, M2, S2,
/// ..., Xn, An, Mn, Sn] where n is the number of nodes. The Xi values represent the value to
/// map, the Ai values represent alpha (opacity) value, the Mi values represent midpoints, and
/// the Si values represent sharpness. Use 0.5 for midpoint and 0.0 for sharpness to have linear
@ -486,11 +514,11 @@ public:
/// Note: n represents the length of the array, so ( n/4 == number of control points )
///
/// Will return false and not modify anything if n is <= 0 or ptr == nullptr
bool FillOpacityTableFromDataPointer(vtkm::Int32 n, const double* ptr);
bool FillOpacityTableFromDataPointer(vtkm::Int32 n, const vtkm::Float64* ptr);
/// Fill the Opacity table from a float pointer
/// Fill the Opacity table from a vtkm::Float32 pointer
///
/// The float pointer is required to have the layout out of [X1, A1, M1, S1, X2, A2, M2, S2,
/// The vtkm::Float32 pointer is required to have the layout out of [X1, A1, M1, S1, X2, A2, M2, S2,
/// ..., Xn, An, Mn, Sn] where n is the number of nodes. The Xi values represent the value to
/// map, the Ai values represent alpha (opacity) value, the Mi values represent midpoints, and
/// the Si values represent sharpness. Use 0.5 for midpoint and 0.0 for sharpness to have linear
@ -501,7 +529,7 @@ public:
/// Note: n represents the length of the array, so ( n/4 == number of control points )
///
/// Will return false and not modify anything if n is <= 0 or ptr == nullptr
bool FillOpacityTableFromDataPointer(vtkm::Int32 n, const float* ptr);
bool FillOpacityTableFromDataPointer(vtkm::Int32 n, const vtkm::Float32* ptr);
/// \brief Sample each value through an intermediate lookup/sample table to generate RGBA colors
@ -628,8 +656,8 @@ public:
///
/// Will use the current range of the color table to generate evenly spaced
/// values using either vtkm::Float32 or vtkm::Float64 space.
/// Will use vtkm::Float32 space when the difference between the float and double
/// values when the range is within float space and the following are within a tolerance:
/// Will use vtkm::Float32 space when the difference between the vtkm::Float32 and vtkm::Float64
/// values when the range is within vtkm::Float32 space and the following are within a tolerance:
///
/// - (max-min) / numSamples
/// - ((max-min) / numSamples) * numSamples
@ -637,14 +665,14 @@ public:
/// Note: This will return false if the number of samples is less than 2
inline bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ColorTableSamplesRGBA& samples,
double tolerance = 0.002) const;
vtkm::Float64 tolerance = 0.002) const;
/// \brief generate a sample lookup table using regular spaced samples along the range.
///
/// Will use the current range of the color table to generate evenly spaced
/// values using either vtkm::Float32 or vtkm::Float64 space.
/// Will use vtkm::Float32 space when the difference between the float and double
/// values when the range is within float space and the following are within a tolerance:
/// Will use vtkm::Float32 space when the difference between the vtkm::Float32 and vtkm::Float64
/// values when the range is within vtkm::Float32 space and the following are within a tolerance:
///
/// - (max-min) / numSamples
/// - ((max-min) / numSamples) * numSamples
@ -652,14 +680,14 @@ public:
/// Note: This will return false if the number of samples is less than 2
inline bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ColorTableSamplesRGB& samples,
double tolerance = 0.002) const;
vtkm::Float64 tolerance = 0.002) const;
/// \brief generate RGBA colors using regular spaced samples along the range.
///
/// Will use the current range of the color table to generate evenly spaced
/// values using either vtkm::Float32 or vtkm::Float64 space.
/// Will use vtkm::Float32 space when the difference between the float and double
/// values when the range is within float space and the following are within a tolerance:
/// Will use vtkm::Float32 space when the difference between the vtkm::Float32 and vtkm::Float64
/// values when the range is within vtkm::Float32 space and the following are within a tolerance:
///
/// - (max-min) / numSamples
/// - ((max-min) / numSamples) * numSamples
@ -667,14 +695,14 @@ public:
/// Note: This will return false if the number of samples is less than 2
inline bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& colors,
double tolerance = 0.002) const;
vtkm::Float64 tolerance = 0.002) const;
/// \brief generate RGB colors using regular spaced samples along the range.
///
/// Will use the current range of the color table to generate evenly spaced
/// values using either vtkm::Float32 or vtkm::Float64 space.
/// Will use vtkm::Float32 space when the difference between the float and double
/// values when the range is within float space and the following are within a tolerance:
/// Will use vtkm::Float32 space when the difference between the vtkm::Float32 and vtkm::Float64
/// values when the range is within vtkm::Float32 space and the following are within a tolerance:
///
/// - (max-min) / numSamples
/// - ((max-min) / numSamples) * numSamples
@ -682,48 +710,30 @@ public:
/// Note: This will return false if the number of samples is less than 2
inline bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& colors,
double tolerance = 0.002) const;
vtkm::Float64 tolerance = 0.002) const;
/// \brief returns a virtual object pointer of the exec color table
///
/// This pointer is only valid as long as the ColorTable is unmodified
inline const vtkm::exec::ColorTableBase* PrepareForExecution(vtkm::cont::DeviceAdapterId deviceId,
vtkm::cont::Token& token) const;
vtkm::exec::ColorTable PrepareForExecution(vtkm::cont::DeviceAdapterId deviceId,
vtkm::cont::Token& token) const;
VTKM_DEPRECATED(1.6, "PrepareForExecution now requires a vtkm::cont::Token object")
inline const vtkm::exec::ColorTableBase* PrepareForExecution(
vtkm::cont::DeviceAdapterId deviceId) const;
inline vtkm::exec::ColorTable PrepareForExecution(vtkm::cont::DeviceAdapterId deviceId) const;
/// \brief returns the modified count for the virtual object handle of the exec color table
/// \brief Returns the modified count for changes of the color table
///
/// The `ModifiedCount` of the color table starts at 1 and gets incremented
/// every time a change is made to the color table.
/// The modified count allows consumers of a shared color table to keep track
/// if the color table has been modified since the last time they used it.
/// This is important for consumers that need to sample the color table.
/// You only want to resample the color table if changes have been made.
vtkm::Id GetModifiedCount() const;
struct TransferState
{
bool NeedsTransfer;
vtkm::exec::ColorTableBase* Portal;
const vtkm::cont::ArrayHandle<double>& ColorPosHandle;
const vtkm::cont::ArrayHandle<vtkm::Vec<float, 3>>& ColorRGBHandle;
const vtkm::cont::ArrayHandle<double>& OpacityPosHandle;
const vtkm::cont::ArrayHandle<float>& OpacityAlphaHandle;
const vtkm::cont::ArrayHandle<vtkm::Vec<float, 2>>& OpacityMidSharpHandle;
};
private:
bool NeedToCreateExecutionColorTable() const;
//takes ownership of the pointer passed in
void UpdateExecutionColorTable(
vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase>*) const;
ColorTable::TransferState GetExecutionDataForTransfer() const;
vtkm::exec::ColorTableBase* GetControlRepresentation() const;
vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase> const* GetExecutionHandle() const;
void UpdateArrayHandles() const;
};
}
} //namespace vtkm::cont

@ -29,52 +29,6 @@ namespace cont
namespace detail
{
template <typename T>
inline T* get_ptr(T* t)
{
return t;
}
#if defined(VTKM_MSVC)
//ArrayPortalToIteratorBegin could be returning a checked_array_iterator so
//we need to grab the underlying pointer
template <typename T>
inline T* get_ptr(stdext::checked_array_iterator<T*> t)
{
return t.base();
}
#endif
struct transfer_color_table_to_device
{
template <typename DeviceAdapter>
inline bool operator()(DeviceAdapter device,
vtkm::cont::ColorTable::TransferState&& state,
vtkm::cont::Token& token) const
{
auto p1 = state.ColorPosHandle.PrepareForInput(device, token);
auto p2 = state.ColorRGBHandle.PrepareForInput(device, token);
auto p3 = state.OpacityPosHandle.PrepareForInput(device, token);
auto p4 = state.OpacityAlphaHandle.PrepareForInput(device, token);
auto p5 = state.OpacityMidSharpHandle.PrepareForInput(device, token);
//The rest of the data member on portal are set when-ever the user
//modifies the ColorTable instance and don't need to specified here
state.Portal->ColorSize = static_cast<vtkm::Int32>(state.ColorPosHandle.GetNumberOfValues());
state.Portal->OpacitySize =
static_cast<vtkm::Int32>(state.OpacityPosHandle.GetNumberOfValues());
state.Portal->ColorNodes = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p1));
state.Portal->RGB = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p2));
state.Portal->ONodes = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p3));
state.Portal->Alpha = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p4));
state.Portal->MidSharp = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p5));
state.Portal->Modified();
return true;
}
};
struct map_color_table
{
template <typename DeviceAdapter, typename ColorTable, typename... Args>
@ -349,77 +303,6 @@ bool ColorTable::Sample(vtkm::Int32 numSamples,
}
return sampleColorTable(this, numSamples, colors, tolerance, false);
}
//---------------------------------------------------------------------------
const vtkm::exec::ColorTableBase* ColorTable::PrepareForExecution(
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token) const
{
//Build the ColorTable instance that is needed for execution
if (this->NeedToCreateExecutionColorTable())
{
auto space = this->GetColorSpace();
auto hostPortal = this->GetControlRepresentation();
//Remove any existing host and execution data. The allocation of the
//virtual object handle needs to occur in the .hxx so that it happens
//in the same library as the user and will be a valid virtual object
using HandleType = vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase>;
switch (space)
{
case vtkm::cont::ColorSpace::RGB:
{
this->UpdateExecutionColorTable(
new HandleType(static_cast<vtkm::exec::ColorTableRGB*>(hostPortal), false));
break;
}
case vtkm::cont::ColorSpace::HSV:
{
this->UpdateExecutionColorTable(
new HandleType(static_cast<vtkm::exec::ColorTableHSV*>(hostPortal), false));
break;
}
case vtkm::cont::ColorSpace::HSV_WRAP:
{
this->UpdateExecutionColorTable(
new HandleType(static_cast<vtkm::exec::ColorTableHSVWrap*>(hostPortal), false));
break;
}
case vtkm::cont::ColorSpace::LAB:
{
this->UpdateExecutionColorTable(
new HandleType(static_cast<vtkm::exec::ColorTableLab*>(hostPortal), false));
break;
}
case vtkm::cont::ColorSpace::DIVERGING:
{
this->UpdateExecutionColorTable(
new HandleType(static_cast<vtkm::exec::ColorTableDiverging*>(hostPortal), false));
break;
}
}
}
//transfer ColorTable and all related data
auto&& info = this->GetExecutionDataForTransfer();
if (info.NeedsTransfer)
{
bool transfered = vtkm::cont::TryExecuteOnDevice(
device, detail::transfer_color_table_to_device{}, std::move(info), token);
if (!transfered)
{
throwFailedRuntimeDeviceTransfer("ColorTable", device);
}
}
return this->GetExecutionHandle()->PrepareForExecution(device, token);
}
const vtkm::exec::ColorTableBase* ColorTable::PrepareForExecution(
vtkm::cont::DeviceAdapterId device) const
{
vtkm::cont::Token token;
return this->PrepareForExecution(device, token);
}
}
}
#endif

@ -24,28 +24,28 @@ namespace cont
namespace internal
{
static vtkm::cont::ColorTable::Preset DEFAULT_PRESET = vtkm::cont::ColorTable::Preset::VIRIDIS;
static vtkm::cont::ColorTable::Preset DEFAULT_PRESET = vtkm::cont::ColorTable::Preset::Viridis;
std::string GetColorSpaceString(vtkm::cont::ColorSpace space)
std::string GetColorSpaceString(vtkm::ColorSpace space)
{
switch (space)
{
case vtkm::cont::ColorSpace::RGB:
case vtkm::ColorSpace::RGB:
return std::string("RGB");
case vtkm::cont::ColorSpace::HSV:
case vtkm::ColorSpace::HSV:
return std::string("HSV");
case vtkm::cont::ColorSpace::HSV_WRAP:
return std::string("HSV_WRAP");
case vtkm::cont::ColorSpace::LAB:
case vtkm::ColorSpace::HSVWrap:
return std::string("HSVWrap");
case vtkm::ColorSpace::Lab:
return std::string("Lab");
case vtkm::cont::ColorSpace::DIVERGING:
case vtkm::ColorSpace::Diverging:
return std::string("Diverging");
}
throw vtkm::cont::ErrorBadValue("Encountered invalid color space.");
}
vtkm::cont::ColorSpace GetColorSpaceEnum(const std::string& colorSpaceString)
vtkm::ColorSpace GetColorSpaceEnum(const std::string& colorSpaceString)
{
std::string spaceString = colorSpaceString;
@ -56,27 +56,27 @@ vtkm::cont::ColorSpace GetColorSpaceEnum(const std::string& colorSpaceString)
if (spaceString == "rgb")
{
return vtkm::cont::ColorSpace::RGB;
return vtkm::ColorSpace::RGB;
}
if (spaceString == "hsv")
{
return vtkm::cont::ColorSpace::HSV;
return vtkm::ColorSpace::HSV;
}
if ((spaceString == "hsv_wrap") || (spaceString == "hsv-wrap") || (spaceString == "hsvwrap"))
{
return vtkm::cont::ColorSpace::HSV_WRAP;
return vtkm::ColorSpace::HSVWrap;
}
if (spaceString == "lab")
{
return vtkm::cont::ColorSpace::LAB;
return vtkm::ColorSpace::Lab;
}
if (spaceString == "diverging")
{
return vtkm::cont::ColorSpace::DIVERGING;
return vtkm::ColorSpace::Diverging;
}
std::stringstream message;
@ -116,7 +116,7 @@ struct ColorTablePreset
{
vtkm::cont::ColorTable::Preset Preset;
std::string Name;
vtkm::cont::ColorSpace ColorSpace;
vtkm::ColorSpace ColorSpace;
vtkm::Vec<double, 3> NanColor;
std::vector<double> RGBPoints;
std::vector<double> AlphaPoints;
@ -124,13 +124,13 @@ struct ColorTablePreset
VTKM_CONT
ColorTablePreset(vtkm::cont::ColorTable::Preset preset,
std::string&& name,
vtkm::cont::ColorSpace colorSpace,
vtkm::ColorSpace colorSpace,
vtkm::Vec<double, 3>&& nanColor,
std::vector<double>&& rgbPoints,
std::vector<double>&& alphaPoints = { 0.0, 1.0, 0.5, 0.0, 1.0, 1.0, 0.5, 0.0 })
: Preset(preset)
, Name(std::move(name))
, ColorSpace(std::move(colorSpace))
, ColorSpace(colorSpace)
, NanColor(std::move(nanColor))
, RGBPoints(std::move(rgbPoints))
, AlphaPoints(std::move(alphaPoints))
@ -148,9 +148,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
{
// clang-format off
presets = std::vector<ColorTablePreset>{
{ vtkm::cont::ColorTable::Preset::COOL_TO_WARM,
{ vtkm::cont::ColorTable::Preset::CoolToWarm,
"Cool to Warm",
vtkm::cont::ColorSpace::DIVERGING,
vtkm::ColorSpace::Diverging,
{ 1, 1, 0 },
{
0, 0.23137254902, 0.298039215686, 0.752941176471,
@ -158,9 +158,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1, 0.705882352941, 0.0156862745098, 0.149019607843
}
},
{ vtkm::cont::ColorTable::Preset::COOL_TO_WARM_EXTENDED,
{ vtkm::cont::ColorTable::Preset::CoolToWarmExtended,
"Cool to Warm Extended",
vtkm::cont::ColorSpace::LAB,
vtkm::ColorSpace::Lab,
{ 0.25, 0, 0 },
{
0, 0, 0, 0.34902,
@ -200,9 +200,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1, 0.34902, 0.070588, 0.211765
}
},
{ vtkm::cont::ColorTable::Preset::VIRIDIS,
{ vtkm::cont::ColorTable::Preset::Viridis,
"Viridis",
vtkm::cont::ColorSpace::LAB,
vtkm::ColorSpace::Lab,
{ 1, 0, 0 },
{
0.000000, 0.282365, 0.000000, 0.331010,
@ -463,9 +463,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1.000000, 0.952999, 0.912545, 0.110859
}
},
{ vtkm::cont::ColorTable::Preset::INFERNO,
{ vtkm::cont::ColorTable::Preset::Inferno,
"Inferno",
vtkm::cont::ColorSpace::LAB,
vtkm::ColorSpace::Lab,
{ 0, 1, 0 },
{
0.000000, 0.002811, 0.000240, 0.013985,
@ -726,9 +726,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1.000000, 0.959400, 1.002963, 0.640626
}
},
{ vtkm::cont::ColorTable::Preset::PLASMA,
{ vtkm::cont::ColorTable::Preset::Plasma,
"Plasma",
vtkm::cont::ColorSpace::LAB,
vtkm::ColorSpace::Lab,
{ 0, 1, 0 },
{
0.000000, 0.185001, 0.000000, 0.530073,
@ -989,9 +989,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1.000000, 0.894058, 0.982254, 0.081069
}
},
{ vtkm::cont::ColorTable::Preset::BLACK_BODY_RADIATION,
{ vtkm::cont::ColorTable::Preset::BlackBodyRadiation,
"Black-Body Radiation",
vtkm::cont::ColorSpace::RGB,
vtkm::ColorSpace::RGB,
{ 0, 0.498039215686, 1 },
{
0, 0, 0, 0,
@ -1000,15 +1000,15 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1, 1, 1, 1
}
},
{ vtkm::cont::ColorTable::Preset::X_RAY,
{ vtkm::cont::ColorTable::Preset::XRay,
"X Ray",
vtkm::cont::ColorSpace::RGB,
vtkm::ColorSpace::RGB,
{ 1, 0, 0 },
{ 0, 1, 1, 1, 1, 0, 0, 0 }
},
{ vtkm::cont::ColorTable::Preset::GREEN,
{ vtkm::cont::ColorTable::Preset::Green,
"Green",
vtkm::cont::ColorSpace::LAB,
vtkm::ColorSpace::Lab,
{ 0.25, 0, 0 },
{
0.00, 0.054902, 0.109804, 0.121569,
@ -1034,9 +1034,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1.00, 1.000000, 0.984314, 0.901961
}
},
{ vtkm::cont::ColorTable::Preset::BLACK_BLUE_WHITE,
{ vtkm::cont::ColorTable::Preset::BlackBlueWhite,
"Black - Blue - White",
vtkm::cont::ColorSpace::RGB,
vtkm::ColorSpace::RGB,
{ 1, 1, 0 },
{
0, 0, 0, 0,
@ -1045,9 +1045,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1, 1, 1, 1
}
},
{ vtkm::cont::ColorTable::Preset::BLUE_TO_ORANGE,
{ vtkm::cont::ColorTable::Preset::BlueToOrange,
"Blue to Orange",
vtkm::cont::ColorSpace::LAB,
vtkm::ColorSpace::Lab,
{ 0.25, 0, 0 },
{
0.000000, 0.086275, 0.003922, 0.298039,
@ -1098,9 +1098,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1.000000, 0.188235, 0.000000, 0.070588
}
},
{vtkm::cont::ColorTable::Preset::GRAY_TO_RED,
{vtkm::cont::ColorTable::Preset::GrayToRed,
"Gray to Red",
vtkm::cont::ColorSpace::LAB,
vtkm::ColorSpace::Lab,
{ 0, 0.498039215686, 1 },
{
0.000000, 0.101961, 0.101961, 0.101961,
@ -1122,9 +1122,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1.000000, 0.403922, 0.000000, 0.121569
}
},
{ vtkm::cont::ColorTable::Preset::COLD_AND_HOT,
{ vtkm::cont::ColorTable::Preset::ColdAndHot,
"Cold and Hot",
vtkm::cont::ColorSpace::RGB,
vtkm::ColorSpace::RGB,
{ 1, 1, 0 },
{
0, 0, 1, 1,
@ -1134,9 +1134,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1, 1, 1, 0
}
},
{ vtkm::cont::ColorTable::Preset::BLUE_GREEN_ORANGE,
{ vtkm::cont::ColorTable::Preset::BlueGreenOrange,
"Blue - Green - Orange",
vtkm::cont::ColorSpace::LAB,
vtkm::ColorSpace::Lab,
{ 0.25, 0.0, 0.0 },
{
0.0,0.831373,0.909804,0.980392,
@ -1191,9 +1191,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1.0,0.45098,0.007843,0.0
}
},
{ vtkm::cont::ColorTable::Preset::YELLOW_GRAY_BLUE,
{ vtkm::cont::ColorTable::Preset::YellowGrayBlue,
"Yellow - Gray - Blue",
vtkm::cont::ColorSpace::LAB,
vtkm::ColorSpace::Lab,
{ 0.25, 0, 0 },
{
0.000000, 0.301961, 0.047059, 0.090196,
@ -1253,9 +1253,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1.000000, 0.890196, 0.956863, 0.984314
}
},
{ vtkm::cont::ColorTable::Preset::RAINBOW_UNIFORM,
{ vtkm::cont::ColorTable::Preset::RainbowUniform,
"Rainbow Uniform",
vtkm::cont::ColorSpace::RGB,
vtkm::ColorSpace::RGB,
{ 1, 0, 0 },
{
0.000000,0.020000,0.381300,0.998100,
@ -1303,9 +1303,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1.000000,0.683700,0.050000,0.413900
}
},
{ vtkm::cont::ColorTable::Preset::JET,
{ vtkm::cont::ColorTable::Preset::Jet,
"Jet",
vtkm::cont::ColorSpace::RGB,
vtkm::ColorSpace::RGB,
{ 0.25, 0, 0 },
{
0, 0, 0, 0.5625,
@ -1317,9 +1317,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1, 0.5, 0, 0
}
},
{ vtkm::cont::ColorTable::Preset::RAINBOW_DESATURATED,
{ vtkm::cont::ColorTable::Preset::RainbowDesaturated,
"Rainbow Desaturated",
vtkm::cont::ColorSpace::RGB,
vtkm::ColorSpace::RGB,
{ 1, 1, 0 },
{
0, 0.278431372549, 0.278431372549, 0.858823529412,
@ -1357,7 +1357,7 @@ namespace internal
VTKM_CONT_EXPORT
bool LoadColorTablePreset(vtkm::cont::ColorTable::Preset preset, vtkm::cont::ColorTable& table)
{
if (preset == vtkm::cont::ColorTable::Preset::DEFAULT)
if (preset == vtkm::cont::ColorTable::Preset::Default)
{
preset = DEFAULT_PRESET;
}
@ -1369,7 +1369,52 @@ bool LoadColorTablePreset(vtkm::cont::ColorTable::Preset preset, vtkm::cont::Col
return true;
}
}
return false;
VTKM_DEPRECATED_SUPPRESS_BEGIN
// Handle deprecated names
switch (preset)
{
case vtkm::cont::ColorTable::Preset::DEFAULT:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::Default, table);
case vtkm::cont::ColorTable::Preset::COOL_TO_WARM:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::CoolToWarm, table);
case vtkm::cont::ColorTable::Preset::COOL_TO_WARM_EXTENDED:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::CoolToWarmExtended, table);
case vtkm::cont::ColorTable::Preset::VIRIDIS:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::Viridis, table);
case vtkm::cont::ColorTable::Preset::INFERNO:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::Inferno, table);
case vtkm::cont::ColorTable::Preset::PLASMA:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::Plasma, table);
case vtkm::cont::ColorTable::Preset::BLACK_BODY_RADIATION:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::BlackBodyRadiation, table);
case vtkm::cont::ColorTable::Preset::X_RAY:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::XRay, table);
case vtkm::cont::ColorTable::Preset::GREEN:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::Green, table);
case vtkm::cont::ColorTable::Preset::BLACK_BLUE_WHITE:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::BlackBlueWhite, table);
case vtkm::cont::ColorTable::Preset::BLUE_TO_ORANGE:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::BlueToOrange, table);
case vtkm::cont::ColorTable::Preset::GRAY_TO_RED:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::GrayToRed, table);
case vtkm::cont::ColorTable::Preset::COLD_AND_HOT:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::ColdAndHot, table);
case vtkm::cont::ColorTable::Preset::BLUE_GREEN_ORANGE:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::BlueGreenOrange, table);
case vtkm::cont::ColorTable::Preset::YELLOW_GRAY_BLUE:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::YellowGrayBlue, table);
case vtkm::cont::ColorTable::Preset::RAINBOW_UNIFORM:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::RainbowUniform, table);
case vtkm::cont::ColorTable::Preset::JET:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::Jet, table);
case vtkm::cont::ColorTable::Preset::RAINBOW_DESATURATED:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::RainbowDesaturated, table);
default:
// Should not get here.
return false;
}
VTKM_DEPRECATED_SUPPRESS_END
}
VTKM_CONT_EXPORT std::set<std::string> GetPresetNames()

@ -1,295 +0,0 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/Range.h>
#include <vtkm/Types.h>
#include <vtkm/cont/VirtualObjectHandle.h>
#include <vtkm/exec/ColorTable.h>
#include <limits>
#include <vector>
namespace vtkm
{
namespace cont
{
namespace detail
{
struct ColorTableInternals
{
std::string Name;
ColorSpace CSpace = ColorSpace::LAB;
vtkm::Range TableRange = { 1.0, 0.0 };
//Host side version of the ColorTableBase. This holds data such as:
// NanColor
// BelowRangeColor
// AboveRangeColor
// UseClamping
// BelowRangeColor
// AboveRangeColor
//Note the pointers inside the host side portal are not valid, as they
//are execution pointers
std::unique_ptr<vtkm::exec::ColorTableBase> HostSideCache;
//Execution side version of the ColorTableBase.
std::unique_ptr<vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase>> ExecHandle;
std::vector<double> ColorNodePos;
std::vector<vtkm::Vec<float, 3>> ColorRGB;
std::vector<double> OpacityNodePos;
std::vector<float> OpacityAlpha;
std::vector<vtkm::Vec<float, 2>> OpacityMidSharp;
vtkm::cont::ArrayHandle<double> ColorPosHandle;
vtkm::cont::ArrayHandle<vtkm::Vec<float, 3>> ColorRGBHandle;
vtkm::cont::ArrayHandle<double> OpacityPosHandle;
vtkm::cont::ArrayHandle<float> OpacityAlphaHandle;
vtkm::cont::ArrayHandle<vtkm::Vec<float, 2>> OpacityMidSharpHandle;
bool ColorArraysChanged = true;
bool OpacityArraysChanged = true;
bool HostSideCacheChanged = true;
void RecalculateRange()
{
vtkm::Range r;
if (this->ColorNodePos.size() > 0)
{
r.Include(this->ColorNodePos.front());
r.Include(this->ColorNodePos.back());
}
if (this->OpacityNodePos.size() > 0)
{
r.Include(this->OpacityNodePos.front());
r.Include(this->OpacityNodePos.back());
}
this->TableRange = r;
}
};
} //namespace detail
namespace
{
template <typename T>
struct MinDelta
{
};
// This value seems to work well for float ranges we have tested
template <>
struct MinDelta<float>
{
static constexpr int value = 2048;
};
template <>
struct MinDelta<double>
{
static constexpr vtkm::Int64 value = 2048L;
};
// Reperesents the following:
// T m = std::numeric_limits<T>::min();
// EquivSizeIntT im;
// std::memcpy(&im, &m, sizeof(T));
//
template <typename EquivSizeIntT>
struct MinRepresentable
{
};
template <>
struct MinRepresentable<float>
{
static constexpr int value = 8388608;
};
template <>
struct MinRepresentable<double>
{
static constexpr vtkm::Int64 value = 4503599627370496L;
};
inline bool rangeAlmostEqual(const vtkm::Range& r)
{
vtkm::Int64 irange[2];
// needs to be a memcpy to avoid strict aliasing issues, doing a count
// of 2*sizeof(T) to couple both values at the same time
std::memcpy(irange, &r.Min, sizeof(vtkm::Int64));
std::memcpy(irange + 1, &r.Max, sizeof(vtkm::Int64));
// determine the absolute delta between these two numbers.
const vtkm::Int64 delta = std::abs(irange[1] - irange[0]);
// If the numbers are not nearly equal, we don't touch them. This avoids running into
// pitfalls like BUG PV #17152.
return (delta < 1024) ? true : false;
}
template <typename T>
inline double expandRange(T r[2])
{
constexpr bool is_float32_type = std::is_same<T, vtkm::Float32>::value;
using IRange = typename std::conditional<is_float32_type, vtkm::Int32, vtkm::Int64>::type;
IRange irange[2];
// needs to be a memcpy to avoid strict aliasing issues, doing a count
// of 2*sizeof(T) to couple both values at the same time
std::memcpy(irange, r, sizeof(T) * 2);
const bool denormal = !std::isnormal(r[0]);
const IRange minInt = MinRepresentable<T>::value;
const IRange minDelta = denormal ? minInt + MinDelta<T>::value : MinDelta<T>::value;
// determine the absolute delta between these two numbers.
const vtkm::Int64 delta = std::abs(irange[1] - irange[0]);
// if our delta is smaller than the min delta push out the max value
// so that it is equal to minRange + minDelta. When our range is entirely
// negative we should instead subtract from our max, to max a larger negative
// value
if (delta < minDelta)
{
if (irange[0] < 0)
{
irange[1] = irange[0] - minDelta;
}
else
{
irange[1] = irange[0] + minDelta;
}
T result;
std::memcpy(&result, irange + 1, sizeof(T));
return static_cast<double>(result);
}
return static_cast<double>(r[1]);
}
inline vtkm::Range adjustRange(const vtkm::Range& r)
{
const bool spans_zero_boundary = r.Min < 0 && r.Max > 0;
if (spans_zero_boundary)
{ // nothing needs to be done, but this check is required.
// if we convert into integer space the delta difference will overflow
// an integer
return r;
}
if (rangeAlmostEqual(r))
{
return r;
}
// range should be left untouched as much as possible to
// to avoid loss of precision whenever possible. That is why
// we only modify the Max value
vtkm::Range result = r;
if (r.Min > static_cast<double>(std::numeric_limits<float>::lowest()) &&
r.Max < static_cast<double>(std::numeric_limits<float>::max()))
{ //We've found it best to offset it in float space if the numbers
//lay inside that representable range
float frange[2] = { static_cast<float>(r.Min), static_cast<float>(r.Max) };
result.Max = expandRange(frange);
}
else
{
double drange[2] = { r.Min, r.Max };
result.Max = expandRange(drange);
}
return result;
}
inline vtkm::Vec<float, 3> hsvTorgb(const vtkm::Vec<float, 3>& hsv)
{
vtkm::Vec<float, 3> rgb;
constexpr float onethird = 1.0f / 3.0f;
constexpr float onesixth = 1.0f / 6.0f;
constexpr float twothird = 2.0f / 3.0f;
constexpr float fivesixth = 5.0f / 6.0f;
// compute RGB from HSV
if (hsv[0] > onesixth && hsv[0] <= onethird) // green/red
{
rgb[1] = 1.0f;
rgb[0] = (onethird - hsv[0]) * 6.0f;
rgb[2] = 0.0f;
}
else if (hsv[0] > onethird && hsv[0] <= 0.5f) // green/blue
{
rgb[1] = 1.0f;
rgb[2] = (hsv[0] - onethird) * 6.0f;
rgb[0] = 0.0f;
}
else if (hsv[0] > 0.5 && hsv[0] <= twothird) // blue/green
{
rgb[2] = 1.0f;
rgb[1] = (twothird - hsv[0]) * 6.0f;
rgb[0] = 0.0f;
}
else if (hsv[0] > twothird && hsv[0] <= fivesixth) // blue/red
{
rgb[2] = 1.0f;
rgb[0] = (hsv[0] - twothird) * 6.0f;
rgb[1] = 0.0f;
}
else if (hsv[0] > fivesixth && hsv[0] <= 1.0) // red/blue
{
rgb[0] = 1.0f;
rgb[2] = (1.0f - hsv[0]) * 6.0f;
rgb[1] = 0.0f;
}
else // red/green
{
rgb[0] = 1.0f;
rgb[1] = hsv[0] * 6;
rgb[2] = 0.0f;
}
// add Saturation to the equation.
rgb[0] = (hsv[1] * rgb[0] + (1.0f - hsv[1]));
rgb[1] = (hsv[1] * rgb[1] + (1.0f - hsv[1]));
rgb[2] = (hsv[1] * rgb[2] + (1.0f - hsv[1]));
rgb[0] *= hsv[2];
rgb[1] *= hsv[2];
rgb[2] *= hsv[2];
return rgb;
}
// clang-format off
inline bool outside_vrange(double x) { return x < 0.0 || x > 1.0; }
inline bool outside_vrange(const vtkm::Vec<double, 2>& x)
{ return x[0] < 0.0 || x[0] > 1.0 || x[1] < 0.0 || x[1] > 1.0; }
inline bool outside_vrange(const vtkm::Vec<double, 3>& x)
{ return x[0] < 0.0 || x[0] > 1.0 || x[1] < 0.0 || x[1] > 1.0 || x[2] < 0.0 || x[2] > 1.0; }
inline bool outside_vrange(float x) { return x < 0.0f || x > 1.0f; }
inline bool outside_vrange(const vtkm::Vec<float, 2>& x)
{ return x[0] < 0.0f || x[0] > 1.0f || x[1] < 0.0f || x[1] > 1.0f; }
inline bool outside_vrange(const vtkm::Vec<float, 3>& x)
{ return x[0] < 0.0f || x[0] > 1.0f || x[1] < 0.0f || x[1] > 1.0f || x[2] < 0.0f || x[2] > 1.0f; }
inline bool outside_range() { return false; }
template <typename T>
inline bool outside_range(T&& t) { return outside_vrange(t); }
template <typename T, typename U>
inline bool outside_range(T&& t, U&& u) { return outside_vrange(t) || outside_vrange(u); }
template <typename T, typename U, typename V, typename... Args>
inline bool outside_range(T&& t, U&& u, V&& v, Args&&... args)
{
return outside_vrange(t) || outside_vrange(u) || outside_vrange(v) ||
outside_range(std::forward<Args>(args)...);
}
// clang-format on
}
} //namespace cont
} //namespace vtkm

@ -59,9 +59,9 @@ public:
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;
auto rgbspace = vtkm::ColorSpace::RGB;
auto hsvspace = vtkm::ColorSpace::HSV;
auto diverging = vtkm::ColorSpace::Diverging;
vtkm::cont::ColorTable table(rgbspace);
VTKM_TEST_ASSERT(table.GetColorSpace() == rgbspace, "color space not saved");
@ -90,10 +90,10 @@ public:
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;
auto rgbspace = vtkm::ColorSpace::RGB;
auto hsvspace = vtkm::ColorSpace::HSV;
auto labspace = vtkm::ColorSpace::Lab;
auto diverging = vtkm::ColorSpace::Diverging;
{
vtkm::cont::ColorTable table(rgbspace);
@ -103,7 +103,7 @@ public:
VTKM_TEST_ASSERT(table.GetRange() == range, "color range not correct after loading preset");
VTKM_TEST_ASSERT(table.GetNumberOfPoints() == 3);
VTKM_TEST_ASSERT(table.LoadPreset(vtkm::cont::ColorTable::Preset::COOL_TO_WARM_EXTENDED));
VTKM_TEST_ASSERT(table.LoadPreset(vtkm::cont::ColorTable::Preset::CoolToWarmExtended));
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");
@ -140,24 +140,24 @@ public:
VTKM_TEST_ASSERT(table.GetNumberOfPoints() > 0, "Issue loading preset ", name);
}
auto presetEnum = { vtkm::cont::ColorTable::Preset::DEFAULT,
vtkm::cont::ColorTable::Preset::COOL_TO_WARM,
vtkm::cont::ColorTable::Preset::COOL_TO_WARM_EXTENDED,
vtkm::cont::ColorTable::Preset::VIRIDIS,
vtkm::cont::ColorTable::Preset::INFERNO,
vtkm::cont::ColorTable::Preset::PLASMA,
vtkm::cont::ColorTable::Preset::BLACK_BODY_RADIATION,
vtkm::cont::ColorTable::Preset::X_RAY,
vtkm::cont::ColorTable::Preset::GREEN,
vtkm::cont::ColorTable::Preset::BLACK_BLUE_WHITE,
vtkm::cont::ColorTable::Preset::BLUE_TO_ORANGE,
vtkm::cont::ColorTable::Preset::GRAY_TO_RED,
vtkm::cont::ColorTable::Preset::COLD_AND_HOT,
vtkm::cont::ColorTable::Preset::BLUE_GREEN_ORANGE,
vtkm::cont::ColorTable::Preset::YELLOW_GRAY_BLUE,
vtkm::cont::ColorTable::Preset::RAINBOW_UNIFORM,
vtkm::cont::ColorTable::Preset::JET,
vtkm::cont::ColorTable::Preset::RAINBOW_DESATURATED };
auto presetEnum = { vtkm::cont::ColorTable::Preset::Default,
vtkm::cont::ColorTable::Preset::CoolToWarm,
vtkm::cont::ColorTable::Preset::CoolToWarmExtended,
vtkm::cont::ColorTable::Preset::Viridis,
vtkm::cont::ColorTable::Preset::Inferno,
vtkm::cont::ColorTable::Preset::Plasma,
vtkm::cont::ColorTable::Preset::BlackBodyRadiation,
vtkm::cont::ColorTable::Preset::XRay,
vtkm::cont::ColorTable::Preset::Green,
vtkm::cont::ColorTable::Preset::BlackBlueWhite,
vtkm::cont::ColorTable::Preset::BlueToOrange,
vtkm::cont::ColorTable::Preset::GrayToRed,
vtkm::cont::ColorTable::Preset::ColdAndHot,
vtkm::cont::ColorTable::Preset::BlueGreenOrange,
vtkm::cont::ColorTable::Preset::YellowGrayBlue,
vtkm::cont::ColorTable::Preset::RainbowUniform,
vtkm::cont::ColorTable::Preset::Jet,
vtkm::cont::ColorTable::Preset::RainbowDesaturated };
for (vtkm::cont::ColorTable::Preset preset : presetEnum)
{
vtkm::cont::ColorTable table(preset);
@ -172,7 +172,7 @@ public:
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;
auto rgbspace = vtkm::ColorSpace::RGB;
vtkm::cont::ColorTable table(range, rgb1, rgb2, rgbspace);
VTKM_TEST_ASSERT(table.GetClamping() == true, "clamping not setup properly");
@ -194,7 +194,7 @@ public:
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;
auto rgbspace = vtkm::ColorSpace::RGB;
vtkm::cont::ColorTable table(range, rgb1, rgb2, rgbspace);
table.SetClampingOff();
@ -228,7 +228,7 @@ public:
//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;
auto lab = vtkm::ColorSpace::Lab;
vtkm::cont::ColorTable table(range, rgb1, rgb2, lab);
table.AddPoint(0.0, vtkm::Vec<float, 3>{ 0.5f, 0.5f, 0.5f });
@ -266,7 +266,7 @@ public:
std::cout << "Test Add Points" << std::endl;
vtkm::Range range{ -20, 20.0 };
auto rgbspace = vtkm::cont::ColorSpace::RGB;
auto rgbspace = vtkm::ColorSpace::RGB;
vtkm::cont::ColorTable table(rgbspace);
table.AddPoint(-10.0, vtkm::Vec<float, 3>{ 0.0f, 1.0f, 1.0f });
@ -291,9 +291,9 @@ public:
std::cout << "Test Add Segments" << std::endl;
vtkm::Range range{ 0.0, 50.0 };
auto diverging = vtkm::cont::ColorSpace::DIVERGING;
auto diverging = vtkm::ColorSpace::Diverging;
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::COOL_TO_WARM);
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::CoolToWarm);
VTKM_TEST_ASSERT(table.GetColorSpace() == diverging,
"color space not switched when loading preset");
@ -332,7 +332,7 @@ public:
{
std::cout << "Test Remove Points" << std::endl;
auto hsv = vtkm::cont::ColorSpace::HSV;
auto hsv = vtkm::ColorSpace::HSV;
vtkm::cont::ColorTable table(hsv);
//implement Blue to Red Rainbow color table
@ -370,7 +370,7 @@ public:
std::cout << " Change Color Space" << std::endl;
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8> colors_rgb;
table.SetColorSpace(vtkm::cont::ColorSpace::RGB);
table.SetColorSpace(vtkm::ColorSpace::RGB);
table.Map(field, colors_rgb);
CheckColors(colors_rgb,
@ -386,7 +386,7 @@ public:
{
std::cout << "Test Opacity Only Points" << std::endl;
auto hsv = vtkm::cont::ColorSpace::HSV;
auto hsv = vtkm::ColorSpace::HSV;
vtkm::cont::ColorTable table(hsv);
//implement only a color table
@ -430,7 +430,7 @@ public:
using namespace vtkm::worklet::colorconversion;
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::GREEN);
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::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),
@ -454,7 +454,7 @@ public:
{
std::cout << "Test Sampling" << std::endl;
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::GREEN);
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::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),
@ -473,7 +473,7 @@ public:
//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);
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::CoolToWarm);
table.RescaleToRange(range);
table.SetClampingOff();
table.SetAboveRangeColor(vtkm::Vec<float, 3>{ 1.0f, 0.0f, 0.0f }); //red

@ -10,85 +10,121 @@
#ifndef vtk_m_exec_ColorTable_h
#define vtk_m_exec_ColorTable_h
#include <vtkm/VirtualObjectBase.h>
#include <vtkm/Deprecated.h>
#include <vtkm/Types.h>
namespace vtkm
{
enum struct ColorSpace
{
RGB,
HSV,
HSVWrap,
Lab,
Diverging
};
} // namespace vtkm
namespace vtkm
{
namespace exec
{
class VTKM_ALWAYS_EXPORT ColorTableBase : public vtkm::VirtualObjectBase
class VTKM_ALWAYS_EXPORT ColorTable
{
public:
inline VTKM_EXEC vtkm::Vec<float, 3> MapThroughColorSpace(double) const;
inline VTKM_EXEC vtkm::Vec3f_32 MapThroughColorSpace(vtkm::Float64) const;
VTKM_EXEC virtual vtkm::Vec<float, 3> MapThroughColorSpace(const vtkm::Vec<float, 3>& rgb1,
const vtkm::Vec<float, 3>& rgb2,
float weight) const = 0;
inline VTKM_EXEC vtkm::Vec3f_32 MapThroughColorSpace(const vtkm::Vec3f_32& rgb1,
const vtkm::Vec3f_32& rgb2,
vtkm::Float32 weight) const;
inline VTKM_EXEC float MapThroughOpacitySpace(double value) const;
inline VTKM_EXEC vtkm::Float32 MapThroughOpacitySpace(vtkm::Float64 value) const;
double const* ColorNodes = nullptr;
vtkm::Vec<float, 3> const* RGB = nullptr;
vtkm::ColorSpace Space;
double const* ONodes = nullptr;
float const* Alpha = nullptr;
vtkm::Vec<float, 2> const* MidSharp = nullptr;
vtkm::Float64 const* ColorNodes = nullptr;
vtkm::Vec3f_32 const* RGB = nullptr;
vtkm::Float64 const* ONodes = nullptr;
vtkm::Float32 const* Alpha = nullptr;
vtkm::Vec2f_32 const* MidSharp = nullptr;
vtkm::Int32 ColorSize = 0;
vtkm::Int32 OpacitySize = 0;
vtkm::Vec<float, 3> NaNColor = { 0.5f, 0.0f, 0.0f };
vtkm::Vec<float, 3> BelowRangeColor = { 0.0f, 0.0f, 0.0f };
vtkm::Vec<float, 3> AboveRangeColor = { 0.0f, 0.0f, 0.0f };
vtkm::Vec3f_32 NaNColor = { 0.5f, 0.0f, 0.0f };
vtkm::Vec3f_32 BelowRangeColor = { 0.0f, 0.0f, 0.0f };
vtkm::Vec3f_32 AboveRangeColor = { 0.0f, 0.0f, 0.0f };
bool UseClamping = true;
private:
inline VTKM_EXEC void FindColors(double value,
vtkm::Vec<float, 3>& first,
vtkm::Vec<float, 3>& second,
float& weight) const;
inline VTKM_EXEC void FindColors(vtkm::Float64 value,
vtkm::Vec3f_32& first,
vtkm::Vec3f_32& second,
vtkm::Float32& weight) const;
inline VTKM_EXEC vtkm::Vec3f_32 MapThroughColorSpaceRGB(const vtkm::Vec3f_32& rgb1,
const vtkm::Vec3f_32& rgb2,
vtkm::Float32 weight) const;
inline VTKM_EXEC vtkm::Vec3f_32 MapThroughColorSpaceHSV(const vtkm::Vec3f_32& rgb1,
const vtkm::Vec3f_32& rgb2,
vtkm::Float32 weight) const;
inline VTKM_EXEC vtkm::Vec3f_32 MapThroughColorSpaceHSVWrap(const vtkm::Vec3f_32& rgb1,
const vtkm::Vec3f_32& rgb2,
vtkm::Float32 weight) const;
inline VTKM_EXEC vtkm::Vec3f_32 MapThroughColorSpaceLab(const vtkm::Vec3f_32& rgb1,
const vtkm::Vec3f_32& rgb2,
vtkm::Float32 weight) const;
inline VTKM_EXEC vtkm::Vec3f_32 MapThroughColorSpaceDiverging(const vtkm::Vec3f_32& rgb1,
const vtkm::Vec3f_32& rgb2,
vtkm::Float32 weight) const;
};
class VTKM_ALWAYS_EXPORT ColorTableRGB final : public ColorTableBase
class VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6, "Use vtkm::exec::ColorTable.") ColorTableBase
: public vtkm::exec::ColorTable
{
public:
inline VTKM_EXEC vtkm::Vec<float, 3> MapThroughColorSpace(const vtkm::Vec<float, 3>& rgb1,
const vtkm::Vec<float, 3>& rgb2,
float weight) const;
};
class VTKM_ALWAYS_EXPORT ColorTableHSV final : public ColorTableBase
class VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6, "Use vtkm::exec::ColorTable.") ColorTableRGB final
: public ColorTable
{
public:
inline VTKM_EXEC vtkm::Vec<float, 3> MapThroughColorSpace(const vtkm::Vec<float, 3>& rgb1,
const vtkm::Vec<float, 3>& rgb2,
float weight) const;
ColorTableRGB() { this->Space = vtkm::ColorSpace::RGB; }
};
class VTKM_ALWAYS_EXPORT ColorTableHSVWrap final : public ColorTableBase
class VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6, "Use vtkm::exec::ColorTable.") ColorTableHSV final
: public ColorTable
{
public:
inline VTKM_EXEC vtkm::Vec<float, 3> MapThroughColorSpace(const vtkm::Vec<float, 3>& rgb1,
const vtkm::Vec<float, 3>& rgb2,
float weight) const;
ColorTableHSV() { this->Space = vtkm::ColorSpace::HSV; }
};
class VTKM_ALWAYS_EXPORT ColorTableLab final : public ColorTableBase
class VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6, "Use vtkm::exec::ColorTable.") ColorTableHSVWrap final
: public ColorTable
{
public:
inline VTKM_EXEC vtkm::Vec<float, 3> MapThroughColorSpace(const vtkm::Vec<float, 3>& rgb1,
const vtkm::Vec<float, 3>& rgb2,
float weight) const;
ColorTableHSVWrap() { this->Space = vtkm::ColorSpace::HSVWrap; }
};
class VTKM_ALWAYS_EXPORT ColorTableDiverging final : public ColorTableBase
class VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6, "Use vtkm::exec::ColorTable.") ColorTableLab final
: public ColorTable
{
public:
inline VTKM_EXEC vtkm::Vec<float, 3> MapThroughColorSpace(const vtkm::Vec<float, 3>& rgb1,
const vtkm::Vec<float, 3>& rgb2,
float weight) const;
ColorTableLab() { this->Space = vtkm::ColorSpace::Lab; }
};
class VTKM_ALWAYS_EXPORT ColorTableDiverging final : public ColorTable
{
public:
ColorTableDiverging() { this->Space = vtkm::ColorSpace::Diverging; }
};
}
}

@ -21,14 +21,14 @@ namespace detail
{
VTKM_EXEC
inline void RGBToHSV(const vtkm::Vec<float, 3>& rgb, vtkm::Vec<float, 3>& hsv)
inline void RGBToHSV(const vtkm::Vec3f_32& rgb, vtkm::Vec3f_32& hsv)
{
constexpr float onethird = 1.0f / 3.0f;
constexpr float onesixth = 1.0f / 6.0f;
constexpr float twothird = 2.0f / 3.0f;
constexpr vtkm::Float32 onethird = 1.0f / 3.0f;
constexpr vtkm::Float32 onesixth = 1.0f / 6.0f;
constexpr vtkm::Float32 twothird = 2.0f / 3.0f;
const float cmax = vtkm::Max(rgb[0], vtkm::Max(rgb[1], rgb[2]));
const float cmin = vtkm::Min(rgb[0], vtkm::Min(rgb[1], rgb[2]));
const vtkm::Float32 cmax = vtkm::Max(rgb[0], vtkm::Max(rgb[1], rgb[2]));
const vtkm::Float32 cmin = vtkm::Min(rgb[0], vtkm::Min(rgb[1], rgb[2]));
hsv[0] = 0.0f;
hsv[1] = 0.0f;
@ -57,13 +57,13 @@ inline void RGBToHSV(const vtkm::Vec<float, 3>& rgb, vtkm::Vec<float, 3>& hsv)
}
VTKM_EXEC
inline vtkm::Vec<float, 3> HSVToRGB(const vtkm::Vec<float, 3>& hsv)
inline vtkm::Vec3f_32 HSVToRGB(const vtkm::Vec3f_32& hsv)
{
vtkm::Vec<float, 3> rgb;
constexpr float onethird = 1.0f / 3.0f;
constexpr float onesixth = 1.0f / 6.0f;
constexpr float twothird = 2.0f / 3.0f;
constexpr float fivesixth = 5.0f / 6.0f;
vtkm::Vec3f_32 rgb;
constexpr vtkm::Float32 onethird = 1.0f / 3.0f;
constexpr vtkm::Float32 onesixth = 1.0f / 6.0f;
constexpr vtkm::Float32 twothird = 2.0f / 3.0f;
constexpr vtkm::Float32 fivesixth = 5.0f / 6.0f;
// compute RGB from HSV
if (hsv[0] > onesixth && hsv[0] <= onethird) // green/red
@ -115,7 +115,7 @@ inline vtkm::Vec<float, 3> HSVToRGB(const vtkm::Vec<float, 3>& hsv)
}
VTKM_EXEC
inline void RGBToLab(const vtkm::Vec<float, 3>& rgb, vtkm::Vec<float, 3>& lab)
inline void RGBToLab(const vtkm::Vec3f_32& rgb, vtkm::Vec3f_32& lab)
{
// clang-format off
@ -128,9 +128,9 @@ inline void RGBToLab(const vtkm::Vec<float, 3>& rgb, vtkm::Vec<float, 3>& lab)
// management. OpenGL is agnostic on its RGB color space, but it is reasonable
// to assume it is close to this one.
{ //rgb to xyz start ( lab == xyz )
float r = rgb[0];
float g = rgb[1];
float b = rgb[2];
vtkm::Float32 r = rgb[0];
vtkm::Float32 g = rgb[1];
vtkm::Float32 b = rgb[2];
if ( r > 0.04045f ) r = vtkm::Pow(( r + 0.055f ) / 1.055f, 2.4f);
else r = r / 12.92f;
if ( g > 0.04045f ) g = vtkm::Pow(( g + 0.055f ) / 1.055f, 2.4f);
@ -145,15 +145,15 @@ inline void RGBToLab(const vtkm::Vec<float, 3>& rgb, vtkm::Vec<float, 3>& lab)
} //rgb to xyz end ( lab == xyz )
//xyz to lab start
constexpr float onethird = 1.0f / 3.0f;
constexpr float sixteen_onesixteen = 16.0f / 116.0f;
constexpr vtkm::Float32 onethird = 1.0f / 3.0f;
constexpr vtkm::Float32 sixteen_onesixteen = 16.0f / 116.0f;
constexpr float ref_X = 0.9505f;
constexpr float ref_Y = 1.000f;
constexpr float ref_Z = 1.089f;
float var_X = lab[0] / ref_X;
float var_Y = lab[1] / ref_Y;
float var_Z = lab[2] / ref_Z;
constexpr vtkm::Float32 ref_X = 0.9505f;
constexpr vtkm::Float32 ref_Y = 1.000f;
constexpr vtkm::Float32 ref_Z = 1.089f;
vtkm::Float32 var_X = lab[0] / ref_X;
vtkm::Float32 var_Y = lab[1] / ref_Y;
vtkm::Float32 var_Z = lab[2] / ref_Z;
if ( var_X > 0.008856f ) var_X = vtkm::Pow(var_X, onethird);
else var_X = ( 7.787f * var_X ) + sixteen_onesixteen;
@ -170,12 +170,12 @@ inline void RGBToLab(const vtkm::Vec<float, 3>& rgb, vtkm::Vec<float, 3>& lab)
}
VTKM_EXEC
inline vtkm::Vec<float, 3> LabToRGB(const vtkm::Vec<float, 3>& lab)
inline vtkm::Vec3f_32 LabToRGB(const vtkm::Vec3f_32& lab)
{
// clang-format off
vtkm::Vec<float, 3> rgb;
vtkm::Vec3f_32 rgb;
{ //lab to xyz start ( rgb == xyz )
constexpr float sixteen_onesixteen = 16.0f / 116.0f;
constexpr vtkm::Float32 sixteen_onesixteen = 16.0f / 116.0f;
//notice that we are mapping L => g, a => r, and b => b
rgb[1] = ( lab[0] + 16.0f ) / 116.0f;
@ -190,22 +190,22 @@ inline vtkm::Vec<float, 3> LabToRGB(const vtkm::Vec<float, 3>& lab)
if ( vtkm::Pow(rgb[2],3) > 0.008856f ) rgb[2] = vtkm::Pow(rgb[2],3);
else rgb[2] = ( rgb[2] - sixteen_onesixteen ) / 7.787f;
constexpr float ref_X = 0.9505f;
constexpr float ref_Y = 1.000f;
constexpr float ref_Z = 1.089f;
constexpr vtkm::Float32 ref_X = 0.9505f;
constexpr vtkm::Float32 ref_Y = 1.000f;
constexpr vtkm::Float32 ref_Z = 1.089f;
rgb[0] *= ref_X; //Observer= 2 deg Illuminant= D65
rgb[1] *= ref_Y;
rgb[2] *= ref_Z;
} // lab to xyz end
//xyz to rgb start
rgb = vtkm::Vec<float,3>(
rgb = vtkm::Vec3f_32(
rgb[0] * 3.2406f + rgb[1] * -1.5372f + rgb[2] * -0.4986f,
rgb[0] * -0.9689f + rgb[1] * 1.8758f + rgb[2] * 0.0415f,
rgb[0] * 0.0557f + rgb[1] * -0.2040f + rgb[2] * 1.0570f);
float& r = rgb[0];
float& g = rgb[1];
float& b = rgb[2];
vtkm::Float32& r = rgb[0];
vtkm::Float32& g = rgb[1];
vtkm::Float32& b = rgb[2];
// The following performs a "gamma correction" specified by the sRGB color
// space. sRGB is defined by a canonical definition of a display monitor and
@ -215,7 +215,7 @@ inline vtkm::Vec<float, 3> LabToRGB(const vtkm::Vec<float, 3>& lab)
// several applications including Adobe Photoshop and Microsoft Windows color
// management. OpenGL is agnostic on its RGB color space, but it is reasonable
// to assume it is close to this one.
constexpr float one_twopointfour = ( 1.0f / 2.4f );
constexpr vtkm::Float32 one_twopointfour = ( 1.0f / 2.4f );
if (r > 0.0031308f) r = 1.055f * (vtkm::Pow(r, one_twopointfour)) - 0.055f;
else r = 12.92f * r;
if (g > 0.0031308f) g = 1.055f * (vtkm::Pow(g ,one_twopointfour)) - 0.055f;
@ -226,7 +226,7 @@ inline vtkm::Vec<float, 3> LabToRGB(const vtkm::Vec<float, 3>& lab)
// Clip colors. ideally we would do something that is perceptually closest
// (since we can see colors outside of the display gamut), but this seems to
// work well enough.
const float maxVal = vtkm::Max(r, vtkm::Max(g,b));
const vtkm::Float32 maxVal = vtkm::Max(r, vtkm::Max(g,b));
if (maxVal > 1.0f)
{
r /= maxVal;
@ -243,14 +243,14 @@ inline vtkm::Vec<float, 3> LabToRGB(const vtkm::Vec<float, 3>& lab)
// Convert to a special polar version of CIELAB (useful for creating
// continuous diverging color maps).
VTKM_EXEC
inline void LabToMsh(const vtkm::Vec<float, 3>& lab, vtkm::Vec<float, 3>& msh)
inline void LabToMsh(const vtkm::Vec3f_32& lab, vtkm::Vec3f_32& msh)
{
const float& L = lab[0];
const float& a = lab[1];
const float& b = lab[2];
float& M = msh[0];
float& s = msh[1];
float& h = msh[2];
const vtkm::Float32& L = lab[0];
const vtkm::Float32& a = lab[1];
const vtkm::Float32& b = lab[2];
vtkm::Float32& M = msh[0];
vtkm::Float32& s = msh[1];
vtkm::Float32& h = msh[2];
M = vtkm::Sqrt(L * L + a * a + b * b);
s = (M > 0.001f) ? vtkm::ACos(L / M) : 0.0f;
@ -260,23 +260,23 @@ inline void LabToMsh(const vtkm::Vec<float, 3>& lab, vtkm::Vec<float, 3>& msh)
// Convert from a special polar version of CIELAB (useful for creating
// continuous diverging color maps).
VTKM_EXEC
inline vtkm::Vec<float, 3> MshToLab(const vtkm::Vec<float, 3>& msh)
inline vtkm::Vec3f_32 MshToLab(const vtkm::Vec3f_32& msh)
{
const float& M = msh[0];
const float& s = msh[1];
const float& h = msh[2];
vtkm::Vec<float, 3> r(
const vtkm::Float32& M = msh[0];
const vtkm::Float32& s = msh[1];
const vtkm::Float32& h = msh[2];
vtkm::Vec3f_32 r(
M * vtkm::Cos(s), M * vtkm::Sin(s) * vtkm::Cos(h), M * vtkm::Sin(s) * vtkm::Sin(h));
return r;
}
// Given two angular orientations, returns the smallest angle between the two.
VTKM_EXEC
inline float DivergingAngleDiff(float a1, float a2)
inline vtkm::Float32 DivergingAngleDiff(vtkm::Float32 a1, vtkm::Float32 a2)
{
constexpr float f_pi = vtkm::Pif();
constexpr float f_two_pi = vtkm::TwoPif();
float adiff = a1 - a2;
constexpr vtkm::Float32 f_pi = vtkm::Pif();
constexpr vtkm::Float32 f_two_pi = vtkm::TwoPif();
vtkm::Float32 adiff = a1 - a2;
if (adiff < 0.0f)
adiff = -adiff;
while (adiff >= f_two_pi)
@ -289,9 +289,9 @@ inline float DivergingAngleDiff(float a1, float a2)
// For the case when interpolating from a saturated color to an unsaturated
// color, find a hue for the unsaturated color that makes sense.
VTKM_EXEC
inline float DivergingAdjustHue(const vtkm::Vec<float, 3>& msh, float unsatM)
inline vtkm::Float32 DivergingAdjustHue(const vtkm::Vec3f_32& msh, vtkm::Float32 unsatM)
{
const float sinS = vtkm::Sin(msh[1]);
const vtkm::Float32 sinS = vtkm::Sin(msh[1]);
if (msh[0] >= unsatM - 0.1f)
{
@ -302,9 +302,10 @@ inline float DivergingAdjustHue(const vtkm::Vec<float, 3>& msh, float unsatM)
{
// This equation is designed to make the perceptual change of the
// interpolation to be close to constant.
float hueSpin = msh[1] * vtkm::Sqrt(unsatM * unsatM - msh[0] * msh[0]) / (msh[0] * sinS);
vtkm::Float32 hueSpin =
msh[1] * vtkm::Sqrt(unsatM * unsatM - msh[0] * msh[0]) / (msh[0] * sinS);
constexpr float one_third_pi = vtkm::Pi_3f();
constexpr vtkm::Float32 one_third_pi = vtkm::Pi_3f();
// Spin hue away from 0 except in purple hues.
if (msh[2] > -one_third_pi)
{
@ -322,10 +323,10 @@ inline float DivergingAdjustHue(const vtkm::Vec<float, 3>& msh, float unsatM)
//---------------------------------------------------------------------------
VTKM_EXEC
vtkm::Vec<float, 3> ColorTableBase::MapThroughColorSpace(double value) const
vtkm::Vec3f_32 ColorTable::MapThroughColorSpace(vtkm::Float64 value) const
{
vtkm::Vec<float, 3> rgb1, rgb2;
float weight = 0;
vtkm::Vec3f_32 rgb1, rgb2;
vtkm::Float32 weight = 0;
this->FindColors(value, rgb1, rgb2, weight);
if (weight == 0)
{
@ -343,10 +344,31 @@ vtkm::Vec<float, 3> ColorTableBase::MapThroughColorSpace(double value) const
//---------------------------------------------------------------------------
VTKM_EXEC
void ColorTableBase::FindColors(double value,
vtkm::Vec<float, 3>& rgb1,
vtkm::Vec<float, 3>& rgb2,
float& weight) const
vtkm::Vec3f_32 ColorTable::MapThroughColorSpace(const vtkm::Vec3f_32& rgb1,
const vtkm::Vec3f_32& rgb2,
vtkm::Float32 weight) const
{
switch (this->Space)
{
case vtkm::ColorSpace::RGB:
return this->MapThroughColorSpaceRGB(rgb1, rgb2, weight);
case vtkm::ColorSpace::HSV:
return this->MapThroughColorSpaceHSV(rgb1, rgb2, weight);
case vtkm::ColorSpace::HSVWrap:
return this->MapThroughColorSpaceHSVWrap(rgb1, rgb2, weight);
case vtkm::ColorSpace::Lab:
return this->MapThroughColorSpaceLab(rgb1, rgb2, weight);
case vtkm::ColorSpace::Diverging:
return this->MapThroughColorSpaceDiverging(rgb1, rgb2, weight);
}
}
//---------------------------------------------------------------------------
VTKM_EXEC
void ColorTable::FindColors(vtkm::Float64 value,
vtkm::Vec3f_32& rgb1,
vtkm::Vec3f_32& rgb2,
vtkm::Float32& weight) const
{
// All the special cases have equivalent rgb1 and rgb2 values so we
// set the weight to 0.0f as a default
@ -402,13 +424,13 @@ void ColorTableBase::FindColors(double value,
const auto w =
(value - this->ColorNodes[first]) / (this->ColorNodes[second] - this->ColorNodes[first]);
weight = static_cast<float>(w);
weight = static_cast<vtkm::Float32>(w);
}
}
//---------------------------------------------------------------------------
VTKM_EXEC
float ColorTableBase::MapThroughOpacitySpace(double value) const
vtkm::Float32 ColorTable::MapThroughOpacitySpace(vtkm::Float64 value) const
{
if (vtkm::IsNan(value))
{ //If we are trying to find the opacity of NaN use a constant of 1.0
@ -442,7 +464,7 @@ float ColorTableBase::MapThroughOpacitySpace(double value) const
}
}
const auto w = (value - this->ONodes[first]) / (this->ONodes[second] - this->ONodes[first]);
float weight = static_cast<float>(w);
vtkm::Float32 weight = static_cast<vtkm::Float32>(w);
//we only need the previous midpoint and sharpness as they control this region
const auto& alpha1 = this->Alpha[first];
@ -490,20 +512,20 @@ float ColorTableBase::MapThroughOpacitySpace(double value) const
}
// Compute some coefficients we will need for the hermite curve
const float ww = weight * weight;
const float www = weight * weight * weight;
const vtkm::Float32 ww = weight * weight;
const vtkm::Float32 www = weight * weight * weight;
const float h1 = 2.0f * www - 3.0f * ww + 1.0f;
const float h2 = -2.0f * www + 3.0f * ww;
const float h3 = www - 2.0f * ww + weight;
const float h4 = www - ww;
const vtkm::Float32 h1 = 2.0f * www - 3.0f * ww + 1.0f;
const vtkm::Float32 h2 = -2.0f * www + 3.0f * ww;
const vtkm::Float32 h3 = www - 2.0f * ww + weight;
const vtkm::Float32 h4 = www - ww;
// Use one slope for both end points
const float slope = alpha2 - alpha1;
const float t = (1.0f - midsharp[1]) * slope;
const vtkm::Float32 slope = alpha2 - alpha1;
const vtkm::Float32 t = (1.0f - midsharp[1]) * slope;
// Compute the value
float result = h1 * alpha1 + h2 * alpha2 + h3 * t + h4 * t;
vtkm::Float32 result = h1 * alpha1 + h2 * alpha2 + h3 * t + h4 * t;
// Final error check to make sure we don't go outside
// the Y range
@ -515,20 +537,20 @@ float ColorTableBase::MapThroughOpacitySpace(double value) const
}
//---------------------------------------------------------------------------
VTKM_EXEC
vtkm::Vec<float, 3> ColorTableRGB::MapThroughColorSpace(const vtkm::Vec<float, 3>& rgb1,
const vtkm::Vec<float, 3>& rgb2,
float weight) const
vtkm::Vec3f_32 ColorTable::MapThroughColorSpaceRGB(const vtkm::Vec3f_32& rgb1,
const vtkm::Vec3f_32& rgb2,
vtkm::Float32 weight) const
{
return vtkm::Lerp(rgb1, rgb2, weight);
}
//---------------------------------------------------------------------------
VTKM_EXEC
vtkm::Vec<float, 3> ColorTableHSV::MapThroughColorSpace(const vtkm::Vec<float, 3>& rgb1,
const vtkm::Vec<float, 3>& rgb2,
float weight) const
vtkm::Vec3f_32 ColorTable::MapThroughColorSpaceHSV(const vtkm::Vec3f_32& rgb1,
const vtkm::Vec3f_32& rgb2,
vtkm::Float32 weight) const
{
vtkm::Vec<float, 3> hsv1, hsv2;
vtkm::Vec3f_32 hsv1, hsv2;
detail::RGBToHSV(rgb1, hsv1);
detail::RGBToHSV(rgb2, hsv2);
@ -542,15 +564,15 @@ vtkm::Vec<float, 3> ColorTableHSV::MapThroughColorSpace(const vtkm::Vec<float, 3
//---------------------------------------------------------------------------
VTKM_EXEC
vtkm::Vec<float, 3> ColorTableHSVWrap::MapThroughColorSpace(const vtkm::Vec<float, 3>& rgb1,
const vtkm::Vec<float, 3>& rgb2,
float weight) const
vtkm::Vec3f_32 ColorTable::MapThroughColorSpaceHSVWrap(const vtkm::Vec3f_32& rgb1,
const vtkm::Vec3f_32& rgb2,
vtkm::Float32 weight) const
{
vtkm::Vec<float, 3> hsv1, hsv2;
vtkm::Vec3f_32 hsv1, hsv2;
detail::RGBToHSV(rgb1, hsv1);
detail::RGBToHSV(rgb2, hsv2);
const float diff = hsv1[0] - hsv2[0];
const vtkm::Float32 diff = hsv1[0] - hsv2[0];
if (diff > 0.5f)
{
hsv1[0] -= 1.0f;
@ -570,11 +592,11 @@ vtkm::Vec<float, 3> ColorTableHSVWrap::MapThroughColorSpace(const vtkm::Vec<floa
//---------------------------------------------------------------------------
VTKM_EXEC
vtkm::Vec<float, 3> ColorTableLab::MapThroughColorSpace(const vtkm::Vec<float, 3>& rgb1,
const vtkm::Vec<float, 3>& rgb2,
float weight) const
vtkm::Vec3f_32 ColorTable::MapThroughColorSpaceLab(const vtkm::Vec3f_32& rgb1,
const vtkm::Vec3f_32& rgb2,
vtkm::Float32 weight) const
{
vtkm::Vec<float, 3> lab1, lab2;
vtkm::Vec3f_32 lab1, lab2;
detail::RGBToLab(rgb1, lab1);
detail::RGBToLab(rgb2, lab2);
@ -585,27 +607,27 @@ vtkm::Vec<float, 3> ColorTableLab::MapThroughColorSpace(const vtkm::Vec<float, 3
//---------------------------------------------------------------------------
VTKM_EXEC
vtkm::Vec<float, 3> ColorTableDiverging::MapThroughColorSpace(const vtkm::Vec<float, 3>& rgb1,
const vtkm::Vec<float, 3>& rgb2,
float weight) const
vtkm::Vec3f_32 ColorTable::MapThroughColorSpaceDiverging(const vtkm::Vec3f_32& rgb1,
const vtkm::Vec3f_32& rgb2,
vtkm::Float32 weight) const
{
vtkm::Vec<float, 3> lab1, lab2;
vtkm::Vec3f_32 lab1, lab2;
detail::RGBToLab(rgb1, lab1);
detail::RGBToLab(rgb2, lab2);
vtkm::Vec<float, 3> msh1, msh2;
vtkm::Vec3f_32 msh1, msh2;
detail::LabToMsh(lab1, msh1);
detail::LabToMsh(lab2, msh2);
// If the endpoints are distinct saturated colors, then place white in between
// them.
constexpr float one_third_pi = vtkm::Pi_3f();
constexpr vtkm::Float32 one_third_pi = vtkm::Pi_3f();
if ((msh1[1] > 0.05f) && (msh2[1] > 0.05f) &&
(detail::DivergingAngleDiff(msh1[2], msh2[2]) > one_third_pi))
{
// Insert the white midpoint by setting one end to white and adjusting the
// scalar value.
float Mmid = vtkm::Max(msh1[0], msh2[0]);
vtkm::Float32 Mmid = vtkm::Max(msh1[0], msh2[0]);
Mmid = vtkm::Max(88.0f, Mmid);
if (weight < 0.5f)
{
@ -640,20 +662,6 @@ vtkm::Vec<float, 3> ColorTableDiverging::MapThroughColorSpace(const vtkm::Vec<fl
return detail::LabToRGB(tmp);
}
}
}
// Cuda seems to have a bug where it expects the template class VirtualObjectTransfer
// to be instantiated in a consistent order among all the translation units of an
// executable. Failing to do so results in random crashes and incorrect results.
// We workaroud this issue by explicitly instantiating VirtualObjectTransfer for
// all the portal types here.
#ifdef VTKM_CUDA
#include <vtkm/cont/internal/VirtualObjectTransferInstantiate.h>
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::exec::ColorTableRGB);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::exec::ColorTableHSV);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::exec::ColorTableHSVWrap);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::exec::ColorTableLab);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::exec::ColorTableDiverging);
#endif
} // namespace vtkm::exec
#endif

@ -22,7 +22,7 @@ void TestFieldToColors()
//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);
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::CoolToWarm);
table.RescaleToRange(range);
table.SetClampingOff();
table.SetAboveRangeColor(vtkm::Vec<float, 3>{ 1.0f, 0.0f, 0.0f }); //red

@ -44,7 +44,7 @@ struct Actor::InternalsType
InternalsType(const vtkm::cont::DynamicCellSet& cells,
const vtkm::cont::CoordinateSystem& coordinates,
const vtkm::cont::Field& scalarField,
const vtkm::cont::ColorTable& colorTable = vtkm::cont::ColorTable::Preset::DEFAULT)
const vtkm::cont::ColorTable& colorTable = vtkm::cont::ColorTable::Preset::Default)
: Cells(cells)
, Coordinates(coordinates)
, ScalarField(scalarField)

@ -17,7 +17,7 @@ namespace rendering
{
ColorBarAnnotation::ColorBarAnnotation()
: ColorTable(vtkm::cont::ColorSpace::LAB)
: ColorTable(vtkm::ColorSpace::Lab)
, Position(vtkm::Range(-0.88, +0.88), vtkm::Range(+0.87, +0.92), vtkm::Range(0, 0))
, Horizontal(true)
, FieldName("")

@ -23,7 +23,7 @@ namespace colorconversion
struct TransferFunction : public vtkm::worklet::WorkletMapField
{
TransferFunction(const vtkm::exec::ColorTableBase* table)
TransferFunction(const vtkm::exec::ColorTable table)
: ColorTable(table)
{
}
@ -34,7 +34,7 @@ struct TransferFunction : public vtkm::worklet::WorkletMapField
template <typename T>
VTKM_EXEC void operator()(const T& in, vtkm::Vec3ui_8& output) const
{
vtkm::Vec<float, 3> rgb = this->ColorTable->MapThroughColorSpace(static_cast<double>(in));
vtkm::Vec<float, 3> rgb = this->ColorTable.MapThroughColorSpace(static_cast<double>(in));
output[0] = colorconversion::ColorToUChar(rgb[0]);
output[1] = colorconversion::ColorToUChar(rgb[1]);
output[2] = colorconversion::ColorToUChar(rgb[2]);
@ -43,8 +43,8 @@ struct TransferFunction : public vtkm::worklet::WorkletMapField
template <typename T>
VTKM_EXEC void operator()(const T& in, vtkm::Vec4ui_8& output) const
{
vtkm::Vec<float, 3> rgb = this->ColorTable->MapThroughColorSpace(static_cast<double>(in));
float alpha = this->ColorTable->MapThroughOpacitySpace(static_cast<double>(in));
vtkm::Vec<float, 3> rgb = this->ColorTable.MapThroughColorSpace(static_cast<double>(in));
float alpha = this->ColorTable.MapThroughOpacitySpace(static_cast<double>(in));
output[0] = colorconversion::ColorToUChar(rgb[0]);
output[1] = colorconversion::ColorToUChar(rgb[1]);
output[2] = colorconversion::ColorToUChar(rgb[2]);
@ -54,21 +54,21 @@ struct TransferFunction : public vtkm::worklet::WorkletMapField
template <typename T>
VTKM_EXEC void operator()(const T& in, vtkm::Vec<float, 3>& output) const
{
output = this->ColorTable->MapThroughColorSpace(static_cast<double>(in));
output = this->ColorTable.MapThroughColorSpace(static_cast<double>(in));
}
template <typename T>
VTKM_EXEC void operator()(const T& in, vtkm::Vec<float, 4>& output) const
{
vtkm::Vec<float, 3> rgb = this->ColorTable->MapThroughColorSpace(static_cast<double>(in));
float alpha = this->ColorTable->MapThroughOpacitySpace(static_cast<double>(in));
vtkm::Vec<float, 3> rgb = this->ColorTable.MapThroughColorSpace(static_cast<double>(in));
float alpha = this->ColorTable.MapThroughOpacitySpace(static_cast<double>(in));
output[0] = rgb[0];
output[1] = rgb[1];
output[2] = rgb[2];
output[3] = alpha;
}
const vtkm::exec::ColorTableBase* ColorTable;
const vtkm::exec::ColorTable ColorTable;
};
}
}