From 11996f133fd96c76568574e950112472688418b9 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Mon, 14 Sep 2020 13:26:16 -0600 Subject: [PATCH] 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. --- CMake/testing/VTKmCheckSourceInInstall.cmake | 1 - vtkm/cont/ColorTable.cxx | 908 +++++++++++------- vtkm/cont/ColorTable.h | 308 +++--- vtkm/cont/ColorTable.hxx | 117 --- vtkm/cont/ColorTablePresets.cxx | 151 ++- vtkm/cont/ColorTablePrivate.hxx | 295 ------ vtkm/cont/testing/TestingColorTable.h | 76 +- vtkm/exec/ColorTable.h | 116 ++- vtkm/exec/ColorTable.hxx | 234 ++--- vtkm/filter/testing/UnitTestFieldToColors.cxx | 2 +- vtkm/rendering/Actor.cxx | 2 +- vtkm/rendering/ColorBarAnnotation.cxx | 2 +- .../colorconversion/TransferFunction.h | 16 +- 13 files changed, 1087 insertions(+), 1141 deletions(-) delete mode 100644 vtkm/cont/ColorTablePrivate.hxx diff --git a/CMake/testing/VTKmCheckSourceInInstall.cmake b/CMake/testing/VTKmCheckSourceInInstall.cmake index abf71d1f4..ccf303bd2 100644 --- a/CMake/testing/VTKmCheckSourceInInstall.cmake +++ b/CMake/testing/VTKmCheckSourceInInstall.cmake @@ -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 diff --git a/vtkm/cont/ColorTable.cxx b/vtkm/cont/ColorTable.cxx index b5cef2700..f7af39f2b 100644 --- a/vtkm/cont/ColorTable.cxx +++ b/vtkm/cont/ColorTable.cxx @@ -13,16 +13,282 @@ #include #include -#include #include #include +namespace +{ + +template +struct MinDelta +{ +}; +// This value seems to work well for float ranges we have tested +template <> +struct MinDelta +{ + static constexpr int value = 2048; +}; +template <> +struct MinDelta +{ + static constexpr vtkm::Int64 value = 2048L; +}; + +// Reperesents the following: +// T m = std::numeric_limits::min(); +// EquivSizeIntT im; +// std::memcpy(&im, &m, sizeof(T)); +// +template +struct MinRepresentable +{ +}; +template <> +struct MinRepresentable +{ + static constexpr int value = 8388608; +}; +template <> +struct MinRepresentable +{ + 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 +inline double expandRange(T r[2]) +{ + constexpr bool is_float32_type = std::is_same::value; + using IRange = typename std::conditional::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::value; + const IRange minDelta = denormal ? minInt + MinDelta::value : MinDelta::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(result); + } + return static_cast(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(std::numeric_limits::lowest()) && + r.Max < static_cast(std::numeric_limits::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(r.Min), static_cast(r.Max) }; + result.Max = expandRange(frange); + } + else + { + double drange[2] = { r.Min, r.Max }; + result.Max = expandRange(drange); + } + return result; +} + + +inline vtkm::Vec hsvTorgb(const vtkm::Vec& hsv) +{ + vtkm::Vec 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& 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& 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& 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& 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 +inline bool outside_range(T&& t) { return outside_vrange(t); } + +template +inline bool outside_range(T&& t, U&& u) { return outside_vrange(t) || outside_vrange(u); } + +template +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)...); +} +// clang-format on +} + namespace vtkm { namespace cont { +namespace detail +{ + +struct ColorTableInternals +{ + std::string Name; + + vtkm::ColorSpace Space = vtkm::ColorSpace::Lab; + vtkm::Range TableRange = { 1.0, 0.0 }; + + 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; + + std::vector ColorNodePos; + std::vector ColorRGB; + + std::vector OpacityNodePos; + std::vector OpacityAlpha; + std::vector OpacityMidSharp; + + vtkm::cont::ArrayHandle ColorPosHandle; + vtkm::cont::ArrayHandle ColorRGBHandle; + vtkm::cont::ArrayHandle OpacityPosHandle; + vtkm::cont::ArrayHandle OpacityAlphaHandle; + vtkm::cont::ArrayHandle OpacityMidSharpHandle; + bool ColorArraysChanged = true; + bool OpacityArraysChanged = true; + + vtkm::Id ModifiedCount = 1; + void Modified() { ++this->ModifiedCount; } + + 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 internal { std::set GetPresetNames(); @@ -32,7 +298,7 @@ bool LoadColorTablePreset(std::string name, vtkm::cont::ColorTable& table); //---------------------------------------------------------------------------- ColorTable::ColorTable(vtkm::cont::ColorTable::Preset preset) - : Impl(std::make_shared()) + : Internals(std::make_shared()) { const bool loaded = this->LoadPreset(preset); if (!loaded) @@ -40,14 +306,15 @@ ColorTable::ColorTable(vtkm::cont::ColorTable::Preset preset) //so that the internal host side cache is constructed and we leave //the constructor in a valid state. We use LAB as it is the default //when the no parameter constructor is called - this->SetColorSpace(ColorSpace::LAB); + this->SetColorSpace(vtkm::ColorSpace::Lab); } - this->AddSegmentAlpha(this->Impl->TableRange.Min, 1.0f, this->Impl->TableRange.Max, 1.0f); + this->AddSegmentAlpha( + this->Internals->TableRange.Min, 1.0f, this->Internals->TableRange.Max, 1.0f); } //---------------------------------------------------------------------------- ColorTable::ColorTable(const std::string& name) - : Impl(std::make_shared()) + : Internals(std::make_shared()) { const bool loaded = this->LoadPreset(name); if (!loaded) @@ -55,24 +322,25 @@ ColorTable::ColorTable(const std::string& name) //so that the internal host side cache is constructed and we leave //the constructor in a valid state. We use LAB as it is the default //when the no parameter constructor is called - this->SetColorSpace(ColorSpace::LAB); + this->SetColorSpace(vtkm::ColorSpace::Lab); } - this->AddSegmentAlpha(this->Impl->TableRange.Min, 1.0f, this->Impl->TableRange.Max, 1.0f); + this->AddSegmentAlpha( + this->Internals->TableRange.Min, 1.0f, this->Internals->TableRange.Max, 1.0f); } //---------------------------------------------------------------------------- -ColorTable::ColorTable(ColorSpace space) - : Impl(std::make_shared()) +ColorTable::ColorTable(vtkm::ColorSpace space) + : Internals(std::make_shared()) { this->SetColorSpace(space); } //---------------------------------------------------------------------------- ColorTable::ColorTable(const vtkm::Range& range, - const vtkm::Vec& rgb1, - const vtkm::Vec& rgb2, - ColorSpace space) - : Impl(std::make_shared()) + const vtkm::Vec3f_32& rgb1, + const vtkm::Vec3f_32& rgb2, + vtkm::ColorSpace space) + : Internals(std::make_shared()) { this->AddSegment(range.Min, rgb1, range.Max, rgb2); this->AddSegmentAlpha(range.Min, 1.0f, range.Max, 1.0f); @@ -81,13 +349,13 @@ ColorTable::ColorTable(const vtkm::Range& range, //---------------------------------------------------------------------------- ColorTable::ColorTable(const vtkm::Range& range, - const vtkm::Vec& rgba1, - const vtkm::Vec& rgba2, - ColorSpace space) - : Impl(std::make_shared()) + const vtkm::Vec4f_32& rgba1, + const vtkm::Vec4f_32& rgba2, + vtkm::ColorSpace space) + : Internals(std::make_shared()) { - vtkm::Vec rgb1(rgba1[0], rgba1[1], rgba1[2]); - vtkm::Vec rgb2(rgba2[0], rgba2[1], rgba2[2]); + vtkm::Vec3f_32 rgb1(rgba1[0], rgba1[1], rgba1[2]); + vtkm::Vec3f_32 rgb2(rgba2[0], rgba2[1], rgba2[2]); this->AddSegment(range.Min, rgb1, range.Max, rgb2); this->AddSegmentAlpha(range.Min, rgba1[3], range.Max, rgba2[3]); this->SetColorSpace(space); @@ -95,11 +363,11 @@ ColorTable::ColorTable(const vtkm::Range& range, //---------------------------------------------------------------------------- ColorTable::ColorTable(const std::string& name, - vtkm::cont::ColorSpace colorSpace, - const vtkm::Vec& nanColor, - const std::vector& rgbPoints, - const std::vector& alphaPoints) - : Impl(std::make_shared()) + vtkm::ColorSpace colorSpace, + const vtkm::Vec3f_64& nanColor, + const std::vector& rgbPoints, + const std::vector& alphaPoints) + : Internals(std::make_shared()) { this->SetName(name); this->SetColorSpace(colorSpace); @@ -115,13 +383,13 @@ ColorTable::~ColorTable() {} //---------------------------------------------------------------------------- const std::string& ColorTable::GetName() const { - return this->Impl->Name; + return this->Internals->Name; } //---------------------------------------------------------------------------- void ColorTable::SetName(const std::string& name) { - this->Impl->Name = name; + this->Internals->Name = name; } //---------------------------------------------------------------------------- @@ -145,129 +413,88 @@ bool ColorTable::LoadPreset(const std::string& name) //---------------------------------------------------------------------------- ColorTable ColorTable::MakeDeepCopy() { - ColorTable dcopy(this->Impl->CSpace); + ColorTable dcopy(this->Internals->Space); - dcopy.Impl->TableRange = this->Impl->TableRange; + dcopy.Internals->TableRange = this->Internals->TableRange; - dcopy.Impl->HostSideCache->NaNColor = this->Impl->HostSideCache->NaNColor; - dcopy.Impl->HostSideCache->BelowRangeColor = this->Impl->HostSideCache->BelowRangeColor; - dcopy.Impl->HostSideCache->AboveRangeColor = this->Impl->HostSideCache->AboveRangeColor; + dcopy.Internals->NaNColor = this->Internals->NaNColor; + dcopy.Internals->BelowRangeColor = this->Internals->BelowRangeColor; + dcopy.Internals->AboveRangeColor = this->Internals->AboveRangeColor; - dcopy.Impl->HostSideCache->UseClamping = this->Impl->HostSideCache->UseClamping; + dcopy.Internals->UseClamping = this->Internals->UseClamping; - dcopy.Impl->ColorNodePos = this->Impl->ColorNodePos; - dcopy.Impl->ColorRGB = this->Impl->ColorRGB; + dcopy.Internals->ColorNodePos = this->Internals->ColorNodePos; + dcopy.Internals->ColorRGB = this->Internals->ColorRGB; - dcopy.Impl->OpacityNodePos = this->Impl->OpacityNodePos; - dcopy.Impl->OpacityAlpha = this->Impl->OpacityAlpha; - dcopy.Impl->OpacityMidSharp = this->Impl->OpacityMidSharp; + dcopy.Internals->OpacityNodePos = this->Internals->OpacityNodePos; + dcopy.Internals->OpacityAlpha = this->Internals->OpacityAlpha; + dcopy.Internals->OpacityMidSharp = this->Internals->OpacityMidSharp; return dcopy; } //---------------------------------------------------------------------------- -ColorSpace ColorTable::GetColorSpace() const +vtkm::ColorSpace ColorTable::GetColorSpace() const { - return this->Impl->CSpace; + return this->Internals->Space; } //---------------------------------------------------------------------------- -void ColorTable::SetColorSpace(ColorSpace space) +void ColorTable::SetColorSpace(vtkm::ColorSpace space) { - - if (this->Impl->CSpace != space || this->Impl->HostSideCache.get() == nullptr) - { - this->Impl->HostSideCacheChanged = true; - this->Impl->CSpace = space; - //Remove any existing host information - - switch (space) - { - case vtkm::cont::ColorSpace::RGB: - { - auto* hostPortal = new vtkm::exec::ColorTableRGB(); - this->Impl->HostSideCache.reset(hostPortal); - break; - } - case vtkm::cont::ColorSpace::HSV: - { - auto* hostPortal = new vtkm::exec::ColorTableHSV(); - this->Impl->HostSideCache.reset(hostPortal); - break; - } - case vtkm::cont::ColorSpace::HSV_WRAP: - { - auto* hostPortal = new vtkm::exec::ColorTableHSVWrap(); - this->Impl->HostSideCache.reset(hostPortal); - break; - } - case vtkm::cont::ColorSpace::LAB: - { - auto* hostPortal = new vtkm::exec::ColorTableLab(); - this->Impl->HostSideCache.reset(hostPortal); - break; - } - case vtkm::cont::ColorSpace::DIVERGING: - { - auto* hostPortal = new vtkm::exec::ColorTableDiverging(); - this->Impl->HostSideCache.reset(hostPortal); - break; - } - default: - throw vtkm::cont::ErrorBadType("unknown vtkm::cont::ColorType requested"); - } - } + this->Internals->Space = space; + this->Internals->Modified(); } //---------------------------------------------------------------------------- void ColorTable::SetClamping(bool state) { - this->Impl->HostSideCache->UseClamping = state; - this->Impl->HostSideCache->Modified(); + this->Internals->UseClamping = state; + this->Internals->Modified(); } //---------------------------------------------------------------------------- bool ColorTable::GetClamping() const { - return this->Impl->HostSideCache->UseClamping; + return this->Internals->UseClamping; } //---------------------------------------------------------------------------- -void ColorTable::SetBelowRangeColor(const vtkm::Vec& c) +void ColorTable::SetBelowRangeColor(const vtkm::Vec3f_32& c) { - this->Impl->HostSideCache->BelowRangeColor = c; - this->Impl->HostSideCache->Modified(); + this->Internals->BelowRangeColor = c; + this->Internals->Modified(); } //---------------------------------------------------------------------------- -const vtkm::Vec& ColorTable::GetBelowRangeColor() const +const vtkm::Vec3f_32& ColorTable::GetBelowRangeColor() const { - return this->Impl->HostSideCache->BelowRangeColor; + return this->Internals->BelowRangeColor; } //---------------------------------------------------------------------------- -void ColorTable::SetAboveRangeColor(const vtkm::Vec& c) +void ColorTable::SetAboveRangeColor(const vtkm::Vec3f_32& c) { - this->Impl->HostSideCache->AboveRangeColor = c; - this->Impl->HostSideCache->Modified(); + this->Internals->AboveRangeColor = c; + this->Internals->Modified(); } //---------------------------------------------------------------------------- -const vtkm::Vec& ColorTable::GetAboveRangeColor() const +const vtkm::Vec3f_32& ColorTable::GetAboveRangeColor() const { - return this->Impl->HostSideCache->AboveRangeColor; + return this->Internals->AboveRangeColor; } //---------------------------------------------------------------------------- -void ColorTable::SetNaNColor(const vtkm::Vec& c) +void ColorTable::SetNaNColor(const vtkm::Vec3f_32& c) { - this->Impl->HostSideCache->NaNColor = c; - this->Impl->HostSideCache->Modified(); + this->Internals->NaNColor = c; + this->Internals->Modified(); } //---------------------------------------------------------------------------- -const vtkm::Vec& ColorTable::GetNaNColor() const +const vtkm::Vec3f_32& ColorTable::GetNaNColor() const { - return this->Impl->HostSideCache->NaNColor; + return this->Internals->NaNColor; } //---------------------------------------------------------------------------- @@ -280,40 +507,45 @@ void ColorTable::Clear() //--------------------------------------------------------------------------- void ColorTable::ClearColors() { - this->Impl->ColorNodePos.clear(); - this->Impl->ColorRGB.clear(); - this->Impl->ColorArraysChanged = true; + this->Internals->ColorNodePos.clear(); + this->Internals->ColorRGB.clear(); + this->Internals->ColorArraysChanged = true; + this->Internals->Modified(); } //--------------------------------------------------------------------------- void ColorTable::ClearAlpha() { - this->Impl->OpacityNodePos.clear(); - this->Impl->OpacityAlpha.clear(); - this->Impl->OpacityMidSharp.clear(); - this->Impl->OpacityArraysChanged = true; + this->Internals->OpacityNodePos.clear(); + this->Internals->OpacityAlpha.clear(); + this->Internals->OpacityMidSharp.clear(); + this->Internals->OpacityArraysChanged = true; + this->Internals->Modified(); } //--------------------------------------------------------------------------- void ColorTable::ReverseColors() { - std::reverse(this->Impl->ColorRGB.begin(), this->Impl->ColorRGB.end()); - this->Impl->ColorArraysChanged = true; + std::reverse(this->Internals->ColorRGB.begin(), this->Internals->ColorRGB.end()); + this->Internals->ColorArraysChanged = true; + this->Internals->Modified(); } //--------------------------------------------------------------------------- void ColorTable::ReverseAlpha() { - std::reverse(this->Impl->OpacityAlpha.begin(), this->Impl->OpacityAlpha.end()); + std::reverse(this->Internals->OpacityAlpha.begin(), this->Internals->OpacityAlpha.end()); //To keep the shape correct the mid and sharp values of the last node are not included in the reversal - std::reverse(this->Impl->OpacityMidSharp.begin(), this->Impl->OpacityMidSharp.end() - 1); - this->Impl->OpacityArraysChanged = true; + std::reverse(this->Internals->OpacityMidSharp.begin(), + this->Internals->OpacityMidSharp.end() - 1); + this->Internals->OpacityArraysChanged = true; + this->Internals->Modified(); } //--------------------------------------------------------------------------- const vtkm::Range& ColorTable::GetRange() const { - return this->Impl->TableRange; + return this->Internals->TableRange; } //--------------------------------------------------------------------------- @@ -327,29 +559,32 @@ void ColorTable::RescaleToRange(const vtkm::Range& r) auto newRange = adjustRange(r); //slam control points down to 0.0 - 1.0, and than rescale to new range - const double minv = this->GetRange().Min; - const double oldScale = this->GetRange().Length(); - const double newScale = newRange.Length(); + const vtkm::Float64 minv = this->GetRange().Min; + const vtkm::Float64 oldScale = this->GetRange().Length(); + const vtkm::Float64 newScale = newRange.Length(); VTKM_ASSERT(oldScale > 0); VTKM_ASSERT(newScale > 0); - for (auto i = this->Impl->ColorNodePos.begin(); i != this->Impl->ColorNodePos.end(); ++i) + for (auto i = this->Internals->ColorNodePos.begin(); i != this->Internals->ColorNodePos.end(); + ++i) { const auto t = (*i - minv) / oldScale; *i = (t * newScale) + newRange.Min; } - for (auto i = this->Impl->OpacityNodePos.begin(); i != this->Impl->OpacityNodePos.end(); ++i) + for (auto i = this->Internals->OpacityNodePos.begin(); i != this->Internals->OpacityNodePos.end(); + ++i) { const auto t = (*i - minv) / oldScale; *i = (t * newScale) + newRange.Min; } - this->Impl->ColorArraysChanged = true; - this->Impl->OpacityArraysChanged = true; - this->Impl->TableRange = newRange; + this->Internals->ColorArraysChanged = true; + this->Internals->OpacityArraysChanged = true; + this->Internals->TableRange = newRange; + this->Internals->Modified(); } //--------------------------------------------------------------------------- -vtkm::Int32 ColorTable::AddPoint(double x, const vtkm::Vec& rgb) +vtkm::Int32 ColorTable::AddPoint(vtkm::Float64 x, const vtkm::Vec3f_32& rgb) { if (outside_range(rgb)) { @@ -357,50 +592,52 @@ vtkm::Int32 ColorTable::AddPoint(double x, const vtkm::Vec& rgb) } std::size_t index = 0; - if (this->Impl->ColorNodePos.size() == 0 || this->Impl->ColorNodePos.back() < x) + if (this->Internals->ColorNodePos.size() == 0 || this->Internals->ColorNodePos.back() < x) { - this->Impl->ColorNodePos.emplace_back(x); - this->Impl->ColorRGB.emplace_back(rgb); - index = this->Impl->ColorNodePos.size(); + this->Internals->ColorNodePos.emplace_back(x); + this->Internals->ColorRGB.emplace_back(rgb); + index = this->Internals->ColorNodePos.size(); } else { - auto begin = this->Impl->ColorNodePos.begin(); - auto pos = std::lower_bound(begin, this->Impl->ColorNodePos.end(), x); + auto begin = this->Internals->ColorNodePos.begin(); + auto pos = std::lower_bound(begin, this->Internals->ColorNodePos.end(), x); index = static_cast(std::distance(begin, pos)); if (*pos == x) { - this->Impl->ColorRGB[index] = rgb; + this->Internals->ColorRGB[index] = rgb; } else { - this->Impl->ColorRGB.emplace(this->Impl->ColorRGB.begin() + std::distance(begin, pos), rgb); - this->Impl->ColorNodePos.emplace(pos, x); + this->Internals->ColorRGB.emplace( + this->Internals->ColorRGB.begin() + std::distance(begin, pos), rgb); + this->Internals->ColorNodePos.emplace(pos, x); } } - this->Impl->TableRange.Include(x); //update range to include x - this->Impl->ColorArraysChanged = true; + this->Internals->TableRange.Include(x); //update range to include x + this->Internals->ColorArraysChanged = true; + this->Internals->Modified(); return static_cast(index); } //--------------------------------------------------------------------------- -vtkm::Int32 ColorTable::AddPointHSV(double x, const vtkm::Vec& hsv) +vtkm::Int32 ColorTable::AddPointHSV(vtkm::Float64 x, const vtkm::Vec3f_32& hsv) { return this->AddPoint(x, hsvTorgb(hsv)); } //--------------------------------------------------------------------------- -vtkm::Int32 ColorTable::AddSegment(double x1, - const vtkm::Vec& rgb1, - double x2, - const vtkm::Vec& rgb2) +vtkm::Int32 ColorTable::AddSegment(vtkm::Float64 x1, + const vtkm::Vec3f_32& rgb1, + vtkm::Float64 x2, + const vtkm::Vec3f_32& rgb2) { if (outside_range(rgb1, rgb2)) { return -1; } - if (this->Impl->ColorNodePos.size() > 0) + if (this->Internals->ColorNodePos.size() > 0) { //Todo: // - This could be optimized so we do 2 less lower_bound calls when @@ -408,10 +645,10 @@ vtkm::Int32 ColorTable::AddSegment(double x1, //When we add a segment we remove all points that are inside the line - auto nodeBegin = this->Impl->ColorNodePos.begin(); - auto nodeEnd = this->Impl->ColorNodePos.end(); + auto nodeBegin = this->Internals->ColorNodePos.begin(); + auto nodeEnd = this->Internals->ColorNodePos.end(); - auto rgbBegin = this->Impl->ColorRGB.begin(); + auto rgbBegin = this->Internals->ColorRGB.begin(); auto nodeStart = std::lower_bound(nodeBegin, nodeEnd, x1); auto nodeStop = std::lower_bound(nodeBegin, nodeEnd, x2); @@ -421,8 +658,8 @@ vtkm::Int32 ColorTable::AddSegment(double x1, //erase is exclusive so if end->x == x2 it will be kept around, and //than we will update it in AddPoint - this->Impl->ColorNodePos.erase(nodeStart, nodeStop); - this->Impl->ColorRGB.erase(rgbStart, rgbStop); + this->Internals->ColorNodePos.erase(nodeStart, nodeStop); + this->Internals->ColorRGB.erase(rgbStart, rgbStop); } vtkm::Int32 pos = this->AddPoint(x1, rgb1); this->AddPoint(x2, rgb2); @@ -430,26 +667,26 @@ vtkm::Int32 ColorTable::AddSegment(double x1, } //--------------------------------------------------------------------------- -vtkm::Int32 ColorTable::AddSegmentHSV(double x1, - const vtkm::Vec& hsv1, - double x2, - const vtkm::Vec& hsv2) +vtkm::Int32 ColorTable::AddSegmentHSV(vtkm::Float64 x1, + const vtkm::Vec3f_32& hsv1, + vtkm::Float64 x2, + const vtkm::Vec3f_32& hsv2) { return this->AddSegment(x1, hsvTorgb(hsv1), x2, hsvTorgb(hsv2)); } //--------------------------------------------------------------------------- -bool ColorTable::GetPoint(vtkm::Int32 index, vtkm::Vec& data) const +bool ColorTable::GetPoint(vtkm::Int32 index, vtkm::Vec4f_64& data) const { std::size_t i = static_cast(index); - const std::size_t size = this->Impl->ColorNodePos.size(); + const std::size_t size = this->Internals->ColorNodePos.size(); if (index < 0 || i >= size) { return false; } - const auto& pos = this->Impl->ColorNodePos[i]; - const auto& rgb = this->Impl->ColorRGB[i]; + const auto& pos = this->Internals->ColorNodePos[i]; + const auto& rgb = this->Internals->ColorRGB[i]; data[0] = pos; data[1] = rgb[0]; @@ -459,7 +696,7 @@ bool ColorTable::GetPoint(vtkm::Int32 index, vtkm::Vec& data) const } //--------------------------------------------------------------------------- -vtkm::Int32 ColorTable::UpdatePoint(vtkm::Int32 index, const vtkm::Vec& data) +vtkm::Int32 ColorTable::UpdatePoint(vtkm::Int32 index, const vtkm::Vec4f_64& data) { //skip data[0] as we don't care about position if (outside_range(data[1], data[2], data[3])) @@ -468,7 +705,7 @@ vtkm::Int32 ColorTable::UpdatePoint(vtkm::Int32 index, const vtkm::Vec(index); - const std::size_t size = this->Impl->ColorNodePos.size(); + const std::size_t size = this->Internals->ColorNodePos.size(); if (index < 0 || i >= size) { return -1; @@ -476,33 +713,35 @@ vtkm::Int32 ColorTable::UpdatePoint(vtkm::Int32 index, const vtkm::VecImpl->ColorNodePos.begin() + index; - auto newPos = - std::lower_bound(this->Impl->ColorNodePos.begin(), this->Impl->ColorNodePos.end(), data[0]); + auto oldPos = this->Internals->ColorNodePos.begin() + index; + auto newPos = std::lower_bound( + this->Internals->ColorNodePos.begin(), this->Internals->ColorNodePos.end(), data[0]); if (oldPos == newPos) { //node's relative location hasn't changed - this->Impl->ColorArraysChanged = true; - auto& rgb = this->Impl->ColorRGB[i]; + this->Internals->ColorArraysChanged = true; + auto& rgb = this->Internals->ColorRGB[i]; *newPos = data[0]; - rgb[0] = static_cast(data[1]); - rgb[1] = static_cast(data[2]); - rgb[2] = static_cast(data[3]); + rgb[0] = static_cast(data[1]); + rgb[1] = static_cast(data[2]); + rgb[2] = static_cast(data[3]); + this->Internals->Modified(); return index; } else { //remove the point, and add the new values as the relative location is different this->RemovePoint(index); - vtkm::Vec newrgb( - static_cast(data[1]), static_cast(data[2]), static_cast(data[3])); + vtkm::Vec3f_32 newrgb(static_cast(data[1]), + static_cast(data[2]), + static_cast(data[3])); return this->AddPoint(data[0], newrgb); } } //--------------------------------------------------------------------------- -bool ColorTable::RemovePoint(double x) +bool ColorTable::RemovePoint(vtkm::Float64 x) { - auto begin = this->Impl->ColorNodePos.begin(); - auto pos = std::lower_bound(begin, this->Impl->ColorNodePos.end(), x); + auto begin = this->Internals->ColorNodePos.begin(); + auto pos = std::lower_bound(begin, this->Internals->ColorNodePos.end(), x); return this->RemovePoint(static_cast(std::distance(begin, pos))); } @@ -510,80 +749,85 @@ bool ColorTable::RemovePoint(double x) bool ColorTable::RemovePoint(vtkm::Int32 index) { std::size_t i = static_cast(index); - const std::size_t size = this->Impl->ColorNodePos.size(); + const std::size_t size = this->Internals->ColorNodePos.size(); if (index < 0 || i >= size) { return false; } - this->Impl->ColorNodePos.erase(this->Impl->ColorNodePos.begin() + index); - this->Impl->ColorRGB.erase(this->Impl->ColorRGB.begin() + index); - this->Impl->ColorArraysChanged = true; - this->Impl->RecalculateRange(); + this->Internals->ColorNodePos.erase(this->Internals->ColorNodePos.begin() + index); + this->Internals->ColorRGB.erase(this->Internals->ColorRGB.begin() + index); + this->Internals->ColorArraysChanged = true; + this->Internals->RecalculateRange(); + this->Internals->Modified(); return true; } //--------------------------------------------------------------------------- vtkm::Int32 ColorTable::GetNumberOfPoints() const { - return static_cast(this->Impl->ColorNodePos.size()); + return static_cast(this->Internals->ColorNodePos.size()); } //--------------------------------------------------------------------------- -vtkm::Int32 ColorTable::AddPointAlpha(double x, float alpha, float midpoint, float sharpness) +vtkm::Int32 ColorTable::AddPointAlpha(vtkm::Float64 x, + vtkm::Float32 alpha, + vtkm::Float32 midpoint, + vtkm::Float32 sharpness) { if (outside_range(alpha, midpoint, sharpness)) { return -1; } - const vtkm::Vec midsharp(midpoint, sharpness); + const vtkm::Vec2f_32 midsharp(midpoint, sharpness); std::size_t index = 0; - if (this->Impl->OpacityNodePos.size() == 0 || this->Impl->OpacityNodePos.back() < x) + if (this->Internals->OpacityNodePos.size() == 0 || this->Internals->OpacityNodePos.back() < x) { - this->Impl->OpacityNodePos.emplace_back(x); - this->Impl->OpacityAlpha.emplace_back(alpha); - this->Impl->OpacityMidSharp.emplace_back(midsharp); - index = this->Impl->OpacityNodePos.size(); + this->Internals->OpacityNodePos.emplace_back(x); + this->Internals->OpacityAlpha.emplace_back(alpha); + this->Internals->OpacityMidSharp.emplace_back(midsharp); + index = this->Internals->OpacityNodePos.size(); } else { - auto begin = this->Impl->OpacityNodePos.begin(); - auto pos = std::lower_bound(begin, this->Impl->OpacityNodePos.end(), x); + auto begin = this->Internals->OpacityNodePos.begin(); + auto pos = std::lower_bound(begin, this->Internals->OpacityNodePos.end(), x); index = static_cast(std::distance(begin, pos)); if (*pos == x) { - this->Impl->OpacityAlpha[index] = alpha; - this->Impl->OpacityMidSharp[index] = midsharp; + this->Internals->OpacityAlpha[index] = alpha; + this->Internals->OpacityMidSharp[index] = midsharp; } else { - this->Impl->OpacityAlpha.emplace(this->Impl->OpacityAlpha.begin() + std::distance(begin, pos), - alpha); - this->Impl->OpacityMidSharp.emplace( - this->Impl->OpacityMidSharp.begin() + std::distance(begin, pos), midsharp); - this->Impl->OpacityNodePos.emplace(pos, x); + this->Internals->OpacityAlpha.emplace( + this->Internals->OpacityAlpha.begin() + std::distance(begin, pos), alpha); + this->Internals->OpacityMidSharp.emplace( + this->Internals->OpacityMidSharp.begin() + std::distance(begin, pos), midsharp); + this->Internals->OpacityNodePos.emplace(pos, x); } } - this->Impl->OpacityArraysChanged = true; - this->Impl->TableRange.Include(x); //update range to include x + this->Internals->OpacityArraysChanged = true; + this->Internals->TableRange.Include(x); //update range to include x + this->Internals->Modified(); return static_cast(index); } //--------------------------------------------------------------------------- -vtkm::Int32 ColorTable::AddSegmentAlpha(double x1, - float alpha1, - double x2, - float alpha2, - const vtkm::Vec& mid_sharp1, - const vtkm::Vec& mid_sharp2) +vtkm::Int32 ColorTable::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) { if (outside_range(alpha1, alpha2, mid_sharp1, mid_sharp2)) { return -1; } - if (this->Impl->OpacityNodePos.size() > 0) + if (this->Internals->OpacityNodePos.size() > 0) { //Todo: // - This could be optimized so we do 2 less lower_bound calls when @@ -591,11 +835,11 @@ vtkm::Int32 ColorTable::AddSegmentAlpha(double x1, //When we add a segment we remove all points that are inside the line - auto nodeBegin = this->Impl->OpacityNodePos.begin(); - auto nodeEnd = this->Impl->OpacityNodePos.end(); + auto nodeBegin = this->Internals->OpacityNodePos.begin(); + auto nodeEnd = this->Internals->OpacityNodePos.end(); - auto alphaBegin = this->Impl->OpacityAlpha.begin(); - auto midBegin = this->Impl->OpacityMidSharp.begin(); + auto alphaBegin = this->Internals->OpacityAlpha.begin(); + auto midBegin = this->Internals->OpacityMidSharp.begin(); auto nodeStart = std::lower_bound(nodeBegin, nodeEnd, x1); auto nodeStop = std::lower_bound(nodeBegin, nodeEnd, x2); @@ -607,9 +851,9 @@ vtkm::Int32 ColorTable::AddSegmentAlpha(double x1, //erase is exclusive so if end->x == x2 it will be kept around, and //than we will update it in AddPoint - this->Impl->OpacityNodePos.erase(nodeStart, nodeStop); - this->Impl->OpacityAlpha.erase(alphaStart, alphaStop); - this->Impl->OpacityMidSharp.erase(midStart, midStop); + this->Internals->OpacityNodePos.erase(nodeStart, nodeStop); + this->Internals->OpacityAlpha.erase(alphaStart, alphaStop); + this->Internals->OpacityMidSharp.erase(midStart, midStop); } vtkm::Int32 pos = this->AddPointAlpha(x1, alpha1, mid_sharp1[0], mid_sharp1[1]); @@ -618,18 +862,18 @@ vtkm::Int32 ColorTable::AddSegmentAlpha(double x1, } //--------------------------------------------------------------------------- -bool ColorTable::GetPointAlpha(vtkm::Int32 index, vtkm::Vec& data) const +bool ColorTable::GetPointAlpha(vtkm::Int32 index, vtkm::Vec4f_64& data) const { std::size_t i = static_cast(index); - const std::size_t size = this->Impl->OpacityNodePos.size(); + const std::size_t size = this->Internals->OpacityNodePos.size(); if (index < 0 || i >= size) { return false; } - const auto& pos = this->Impl->OpacityNodePos[i]; - const auto& alpha = this->Impl->OpacityAlpha[i]; - const auto& midsharp = this->Impl->OpacityMidSharp[i]; + const auto& pos = this->Internals->OpacityNodePos[i]; + const auto& alpha = this->Internals->OpacityAlpha[i]; + const auto& midsharp = this->Internals->OpacityMidSharp[i]; data[0] = pos; data[1] = alpha; @@ -639,7 +883,7 @@ bool ColorTable::GetPointAlpha(vtkm::Int32 index, vtkm::Vec& data) co } //--------------------------------------------------------------------------- -vtkm::Int32 ColorTable::UpdatePointAlpha(vtkm::Int32 index, const vtkm::Vec& data) +vtkm::Int32 ColorTable::UpdatePointAlpha(vtkm::Int32 index, const vtkm::Vec4f_64& data) { //skip data[0] as we don't care about position if (outside_range(data[1], data[2], data[3])) @@ -648,42 +892,43 @@ vtkm::Int32 ColorTable::UpdatePointAlpha(vtkm::Int32 index, const vtkm::Vec(index); - const std::size_t size = this->Impl->OpacityNodePos.size(); + const std::size_t size = this->Internals->OpacityNodePos.size(); if (index < 0 || i >= size) { return -1; } //When updating the first question is has the relative position of the point changed? //If it hasn't we can quickly just update the RGB value - auto oldPos = this->Impl->OpacityNodePos.begin() + index; - auto newPos = - std::lower_bound(this->Impl->OpacityNodePos.begin(), this->Impl->OpacityNodePos.end(), data[0]); + auto oldPos = this->Internals->OpacityNodePos.begin() + index; + auto newPos = std::lower_bound( + this->Internals->OpacityNodePos.begin(), this->Internals->OpacityNodePos.end(), data[0]); if (oldPos == newPos) { //node's relative location hasn't changed - this->Impl->OpacityArraysChanged = true; - auto& alpha = this->Impl->OpacityAlpha[i]; - auto& midsharp = this->Impl->OpacityMidSharp[i]; + this->Internals->OpacityArraysChanged = true; + auto& alpha = this->Internals->OpacityAlpha[i]; + auto& midsharp = this->Internals->OpacityMidSharp[i]; *newPos = data[0]; - alpha = static_cast(data[1]); - midsharp[0] = static_cast(data[2]); - midsharp[1] = static_cast(data[3]); + alpha = static_cast(data[1]); + midsharp[0] = static_cast(data[2]); + midsharp[1] = static_cast(data[3]); + this->Internals->Modified(); return index; } else { //remove the point, and add the new values as the relative location is different this->RemovePointAlpha(index); return this->AddPointAlpha(data[0], - static_cast(data[1]), - static_cast(data[2]), - static_cast(data[3])); + static_cast(data[1]), + static_cast(data[2]), + static_cast(data[3])); } } //--------------------------------------------------------------------------- -bool ColorTable::RemovePointAlpha(double x) +bool ColorTable::RemovePointAlpha(vtkm::Float64 x) { - auto begin = this->Impl->OpacityNodePos.begin(); - auto pos = std::lower_bound(begin, this->Impl->OpacityNodePos.end(), x); + auto begin = this->Internals->OpacityNodePos.begin(); + auto pos = std::lower_bound(begin, this->Internals->OpacityNodePos.end(), x); return this->RemovePointAlpha(static_cast(std::distance(begin, pos))); } @@ -691,28 +936,29 @@ bool ColorTable::RemovePointAlpha(double x) bool ColorTable::RemovePointAlpha(vtkm::Int32 index) { std::size_t i = static_cast(index); - const std::size_t size = this->Impl->OpacityNodePos.size(); + const std::size_t size = this->Internals->OpacityNodePos.size(); if (index < 0 || i >= size) { return false; } - this->Impl->OpacityNodePos.erase(this->Impl->OpacityNodePos.begin() + index); - this->Impl->OpacityAlpha.erase(this->Impl->OpacityAlpha.begin() + index); - this->Impl->OpacityMidSharp.erase(this->Impl->OpacityMidSharp.begin() + index); - this->Impl->OpacityArraysChanged = true; - this->Impl->RecalculateRange(); + this->Internals->OpacityNodePos.erase(this->Internals->OpacityNodePos.begin() + index); + this->Internals->OpacityAlpha.erase(this->Internals->OpacityAlpha.begin() + index); + this->Internals->OpacityMidSharp.erase(this->Internals->OpacityMidSharp.begin() + index); + this->Internals->OpacityArraysChanged = true; + this->Internals->RecalculateRange(); + this->Internals->Modified(); return true; } //--------------------------------------------------------------------------- vtkm::Int32 ColorTable::GetNumberOfPointsAlpha() const { - return static_cast(this->Impl->OpacityNodePos.size()); + return static_cast(this->Internals->OpacityNodePos.size()); } //--------------------------------------------------------------------------- -bool ColorTable::FillColorTableFromDataPointer(vtkm::Int32 n, const double* ptr) +bool ColorTable::FillColorTableFromDataPointer(vtkm::Int32 n, const vtkm::Float64* ptr) { if (n <= 0 || ptr == nullptr) { @@ -721,22 +967,24 @@ bool ColorTable::FillColorTableFromDataPointer(vtkm::Int32 n, const double* ptr) this->ClearColors(); std::size_t size = static_cast(n / 4); - this->Impl->ColorNodePos.reserve(size); - this->Impl->ColorRGB.reserve(size); + this->Internals->ColorNodePos.reserve(size); + this->Internals->ColorRGB.reserve(size); for (std::size_t i = 0; i < size; ++i) { //allows us to support unsorted arrays - vtkm::Vec rgb( - static_cast(ptr[1]), static_cast(ptr[2]), static_cast(ptr[3])); + vtkm::Vec3f_32 rgb(static_cast(ptr[1]), + static_cast(ptr[2]), + static_cast(ptr[3])); this->AddPoint(ptr[0], rgb); ptr += 4; } - this->Impl->ColorArraysChanged = true; + this->Internals->ColorArraysChanged = true; + this->Internals->Modified(); return true; } //--------------------------------------------------------------------------- -bool ColorTable::FillColorTableFromDataPointer(vtkm::Int32 n, const float* ptr) +bool ColorTable::FillColorTableFromDataPointer(vtkm::Int32 n, const vtkm::Float32* ptr) { if (n <= 0 || ptr == nullptr) { @@ -745,20 +993,21 @@ bool ColorTable::FillColorTableFromDataPointer(vtkm::Int32 n, const float* ptr) this->ClearColors(); std::size_t size = static_cast(n / 4); - this->Impl->ColorNodePos.reserve(size); - this->Impl->ColorRGB.reserve(size); + this->Internals->ColorNodePos.reserve(size); + this->Internals->ColorRGB.reserve(size); for (std::size_t i = 0; i < size; ++i) { //allows us to support unsorted arrays - vtkm::Vec rgb(ptr[1], ptr[2], ptr[3]); + vtkm::Vec3f_32 rgb(ptr[1], ptr[2], ptr[3]); this->AddPoint(ptr[0], rgb); ptr += 4; } - this->Impl->ColorArraysChanged = true; + this->Internals->ColorArraysChanged = true; + this->Internals->Modified(); return true; } //--------------------------------------------------------------------------- -bool ColorTable::FillOpacityTableFromDataPointer(vtkm::Int32 n, const double* ptr) +bool ColorTable::FillOpacityTableFromDataPointer(vtkm::Int32 n, const vtkm::Float64* ptr) { if (n <= 0 || ptr == nullptr) { @@ -767,22 +1016,25 @@ bool ColorTable::FillOpacityTableFromDataPointer(vtkm::Int32 n, const double* pt this->ClearAlpha(); std::size_t size = static_cast(n / 4); - this->Impl->OpacityNodePos.reserve(size); - this->Impl->OpacityAlpha.reserve(size); - this->Impl->OpacityMidSharp.reserve(size); + this->Internals->OpacityNodePos.reserve(size); + this->Internals->OpacityAlpha.reserve(size); + this->Internals->OpacityMidSharp.reserve(size); for (std::size_t i = 0; i < size; ++i) { //allows us to support unsorted arrays - this->AddPointAlpha( - ptr[0], static_cast(ptr[1]), static_cast(ptr[2]), static_cast(ptr[3])); + this->AddPointAlpha(ptr[0], + static_cast(ptr[1]), + static_cast(ptr[2]), + static_cast(ptr[3])); ptr += 4; } - this->Impl->OpacityArraysChanged = true; + this->Internals->OpacityArraysChanged = true; + this->Internals->Modified(); return true; } //--------------------------------------------------------------------------- -bool ColorTable::FillOpacityTableFromDataPointer(vtkm::Int32 n, const float* ptr) +bool ColorTable::FillOpacityTableFromDataPointer(vtkm::Int32 n, const vtkm::Float32* ptr) { if (n <= 0 || ptr == nullptr) { @@ -792,87 +1044,95 @@ bool ColorTable::FillOpacityTableFromDataPointer(vtkm::Int32 n, const float* ptr std::size_t size = static_cast(n / 4); - this->Impl->OpacityNodePos.reserve(size); - this->Impl->OpacityAlpha.reserve(size); - this->Impl->OpacityMidSharp.reserve(size); + this->Internals->OpacityNodePos.reserve(size); + this->Internals->OpacityAlpha.reserve(size); + this->Internals->OpacityMidSharp.reserve(size); for (std::size_t i = 0; i < size; ++i) { //allows us to support unsorted arrays this->AddPointAlpha(ptr[0], ptr[1], ptr[2], ptr[3]); ptr += 4; } - this->Impl->OpacityArraysChanged = true; + this->Internals->OpacityArraysChanged = true; + this->Internals->Modified(); return true; } +//---------------------------------------------------------------------------- +void ColorTable::UpdateArrayHandles() const +{ + //Only rebuild the array handles that have changed since the last time + //we have modified or color / opacity information + + if (this->Internals->ColorArraysChanged) + { + this->Internals->ColorPosHandle = + vtkm::cont::make_ArrayHandle(this->Internals->ColorNodePos, vtkm::CopyFlag::Off); + this->Internals->ColorRGBHandle = + vtkm::cont::make_ArrayHandle(this->Internals->ColorRGB, vtkm::CopyFlag::Off); + this->Internals->ColorArraysChanged = false; + } + + if (this->Internals->OpacityArraysChanged) + { + this->Internals->OpacityPosHandle = + vtkm::cont::make_ArrayHandle(this->Internals->OpacityNodePos, vtkm::CopyFlag::Off); + this->Internals->OpacityAlphaHandle = + vtkm::cont::make_ArrayHandle(this->Internals->OpacityAlpha, vtkm::CopyFlag::Off); + this->Internals->OpacityMidSharpHandle = + vtkm::cont::make_ArrayHandle(this->Internals->OpacityMidSharp, vtkm::CopyFlag::Off); + this->Internals->OpacityArraysChanged = false; + } +} + +//--------------------------------------------------------------------------- +vtkm::exec::ColorTable ColorTable::PrepareForExecution(vtkm::cont::DeviceAdapterId device, + vtkm::cont::Token& token) const +{ + this->UpdateArrayHandles(); + + vtkm::exec::ColorTable execTable; + + execTable.Space = this->Internals->Space; + execTable.NaNColor = this->Internals->NaNColor; + execTable.BelowRangeColor = this->Internals->BelowRangeColor; + execTable.AboveRangeColor = this->Internals->AboveRangeColor; + execTable.UseClamping = this->Internals->UseClamping; + + VTKM_ASSERT(static_cast(this->Internals->ColorNodePos.size()) == + this->Internals->ColorPosHandle.GetNumberOfValues()); + execTable.ColorSize = + static_cast(this->Internals->ColorPosHandle.GetNumberOfValues()); + VTKM_ASSERT(static_cast(execTable.ColorSize) == + this->Internals->ColorRGBHandle.GetNumberOfValues()); + execTable.ColorNodes = this->Internals->ColorPosHandle.PrepareForInput(device, token).GetArray(); + execTable.RGB = this->Internals->ColorRGBHandle.PrepareForInput(device, token).GetArray(); + + VTKM_ASSERT(static_cast(this->Internals->OpacityNodePos.size()) == + this->Internals->OpacityPosHandle.GetNumberOfValues()); + execTable.OpacitySize = + static_cast(this->Internals->OpacityPosHandle.GetNumberOfValues()); + VTKM_ASSERT(static_cast(execTable.OpacitySize) == + this->Internals->OpacityAlphaHandle.GetNumberOfValues()); + VTKM_ASSERT(static_cast(execTable.OpacitySize) == + this->Internals->OpacityMidSharpHandle.GetNumberOfValues()); + execTable.ONodes = this->Internals->OpacityPosHandle.PrepareForInput(device, token).GetArray(); + execTable.Alpha = this->Internals->OpacityAlphaHandle.PrepareForInput(device, token).GetArray(); + execTable.MidSharp = + this->Internals->OpacityMidSharpHandle.PrepareForInput(device, token).GetArray(); + + return execTable; +} + +vtkm::exec::ColorTable ColorTable::PrepareForExecution(vtkm::cont::DeviceAdapterId device) const +{ + vtkm::cont::Token token; + return this->PrepareForExecution(device, token); +} + //--------------------------------------------------------------------------- vtkm::Id ColorTable::GetModifiedCount() const { - return this->Impl->HostSideCache->GetModifiedCount(); -} - -//---------------------------------------------------------------------------- -bool ColorTable::NeedToCreateExecutionColorTable() const -{ - return this->Impl->HostSideCacheChanged; -} - -//---------------------------------------------------------------------------- -void ColorTable::UpdateExecutionColorTable( - vtkm::cont::VirtualObjectHandle* handle) const -{ - this->Impl->ExecHandle.reset(handle); -} - -//---------------------------------------------------------------------------- -ColorTable::TransferState ColorTable::GetExecutionDataForTransfer() const -{ - //Only rebuild the array handles that have changed since the last time - //we have modified or color / opacity information - - if (this->Impl->ColorArraysChanged) - { - this->Impl->ColorPosHandle = - vtkm::cont::make_ArrayHandle(this->Impl->ColorNodePos, vtkm::CopyFlag::Off); - this->Impl->ColorRGBHandle = - vtkm::cont::make_ArrayHandle(this->Impl->ColorRGB, vtkm::CopyFlag::Off); - } - - if (this->Impl->OpacityArraysChanged) - { - this->Impl->OpacityPosHandle = - vtkm::cont::make_ArrayHandle(this->Impl->OpacityNodePos, vtkm::CopyFlag::Off); - this->Impl->OpacityAlphaHandle = - vtkm::cont::make_ArrayHandle(this->Impl->OpacityAlpha, vtkm::CopyFlag::Off); - this->Impl->OpacityMidSharpHandle = - vtkm::cont::make_ArrayHandle(this->Impl->OpacityMidSharp, vtkm::CopyFlag::Off); - } - - TransferState state = { (this->Impl->ColorArraysChanged || this->Impl->OpacityArraysChanged || - this->Impl->HostSideCacheChanged), - this->Impl->HostSideCache.get(), - this->Impl->ColorPosHandle, - this->Impl->ColorRGBHandle, - this->Impl->OpacityPosHandle, - this->Impl->OpacityAlphaHandle, - this->Impl->OpacityMidSharpHandle }; - - this->Impl->ColorArraysChanged = false; - this->Impl->OpacityArraysChanged = false; - this->Impl->HostSideCacheChanged = false; - return state; -} - -//---------------------------------------------------------------------------- -vtkm::exec::ColorTableBase* ColorTable::GetControlRepresentation() const -{ - return this->Impl->HostSideCache.get(); -} - -//---------------------------------------------------------------------------- -vtkm::cont::VirtualObjectHandle const* ColorTable::GetExecutionHandle() - const -{ - return this->Impl->ExecHandle.get(); + return this->Internals->ModifiedCount; } } } //namespace vtkm::cont diff --git a/vtkm/cont/ColorTable.h b/vtkm/cont/ColorTable.h index fd839954c..37cca608b 100644 --- a/vtkm/cont/ColorTable.h +++ b/vtkm/cont/ColorTable.h @@ -17,43 +17,35 @@ #include #include +#include + +#include #include namespace vtkm { - -namespace exec -{ -//forward declare exec objects -class ColorTableBase; -} - namespace cont { -template -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 Impl; + std::shared_ptr 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& rgb1, - const vtkm::Vec& 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& rgba1, - const vtkm::Vec& 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& nanColor, - const std::vector& rgbPoints, - const std::vector& 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& rgbPoints, + const std::vector& 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& c); - const vtkm::Vec& 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& c); - const vtkm::Vec& GetAboveRangeColor() const; + void SetAboveRangeColor(const vtkm::Vec3f_32& c); + const vtkm::Vec3f_32& GetAboveRangeColor() const; /// - void SetNaNColor(const vtkm::Vec& c); - const vtkm::Vec& 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& 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& 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& rgb1, - double x2, - const vtkm::Vec& 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& hsv1, - double x2, - const vtkm::Vec& 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&) 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&); + 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 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& mid_sharp1, - const vtkm::Vec& 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&) 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&); + 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& 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& 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& ColorPosHandle; - const vtkm::cont::ArrayHandle>& ColorRGBHandle; - const vtkm::cont::ArrayHandle& OpacityPosHandle; - const vtkm::cont::ArrayHandle& OpacityAlphaHandle; - const vtkm::cont::ArrayHandle>& OpacityMidSharpHandle; - }; - private: - bool NeedToCreateExecutionColorTable() const; - - //takes ownership of the pointer passed in - void UpdateExecutionColorTable( - vtkm::cont::VirtualObjectHandle*) const; - - ColorTable::TransferState GetExecutionDataForTransfer() const; - - vtkm::exec::ColorTableBase* GetControlRepresentation() const; - - vtkm::cont::VirtualObjectHandle const* GetExecutionHandle() const; + void UpdateArrayHandles() const; }; } } //namespace vtkm::cont diff --git a/vtkm/cont/ColorTable.hxx b/vtkm/cont/ColorTable.hxx index 3d7790740..9a2b64db9 100644 --- a/vtkm/cont/ColorTable.hxx +++ b/vtkm/cont/ColorTable.hxx @@ -29,52 +29,6 @@ namespace cont namespace detail { -template -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 -inline T* get_ptr(stdext::checked_array_iterator t) -{ - return t.base(); -} -#endif - -struct transfer_color_table_to_device -{ - - template - 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(state.ColorPosHandle.GetNumberOfValues()); - state.Portal->OpacitySize = - static_cast(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 @@ -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; - switch (space) - { - case vtkm::cont::ColorSpace::RGB: - { - this->UpdateExecutionColorTable( - new HandleType(static_cast(hostPortal), false)); - break; - } - case vtkm::cont::ColorSpace::HSV: - { - this->UpdateExecutionColorTable( - new HandleType(static_cast(hostPortal), false)); - break; - } - case vtkm::cont::ColorSpace::HSV_WRAP: - { - this->UpdateExecutionColorTable( - new HandleType(static_cast(hostPortal), false)); - break; - } - case vtkm::cont::ColorSpace::LAB: - { - this->UpdateExecutionColorTable( - new HandleType(static_cast(hostPortal), false)); - break; - } - case vtkm::cont::ColorSpace::DIVERGING: - { - this->UpdateExecutionColorTable( - new HandleType(static_cast(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 diff --git a/vtkm/cont/ColorTablePresets.cxx b/vtkm/cont/ColorTablePresets.cxx index 84d384dc2..17096502f 100644 --- a/vtkm/cont/ColorTablePresets.cxx +++ b/vtkm/cont/ColorTablePresets.cxx @@ -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 NanColor; std::vector RGBPoints; std::vector 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&& nanColor, std::vector&& rgbPoints, std::vector&& 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& prese { // clang-format off presets = std::vector{ - { 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& 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 GetPresetNames() diff --git a/vtkm/cont/ColorTablePrivate.hxx b/vtkm/cont/ColorTablePrivate.hxx deleted file mode 100644 index 7f3e2bd9d..000000000 --- a/vtkm/cont/ColorTablePrivate.hxx +++ /dev/null @@ -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 -#include - -#include -#include - -#include -#include - -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 HostSideCache; - //Execution side version of the ColorTableBase. - std::unique_ptr> ExecHandle; - - std::vector ColorNodePos; - std::vector> ColorRGB; - - std::vector OpacityNodePos; - std::vector OpacityAlpha; - std::vector> OpacityMidSharp; - - vtkm::cont::ArrayHandle ColorPosHandle; - vtkm::cont::ArrayHandle> ColorRGBHandle; - vtkm::cont::ArrayHandle OpacityPosHandle; - vtkm::cont::ArrayHandle OpacityAlphaHandle; - vtkm::cont::ArrayHandle> 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 -struct MinDelta -{ -}; -// This value seems to work well for float ranges we have tested -template <> -struct MinDelta -{ - static constexpr int value = 2048; -}; -template <> -struct MinDelta -{ - static constexpr vtkm::Int64 value = 2048L; -}; - -// Reperesents the following: -// T m = std::numeric_limits::min(); -// EquivSizeIntT im; -// std::memcpy(&im, &m, sizeof(T)); -// -template -struct MinRepresentable -{ -}; -template <> -struct MinRepresentable -{ - static constexpr int value = 8388608; -}; -template <> -struct MinRepresentable -{ - 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 -inline double expandRange(T r[2]) -{ - constexpr bool is_float32_type = std::is_same::value; - using IRange = typename std::conditional::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::value; - const IRange minDelta = denormal ? minInt + MinDelta::value : MinDelta::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(result); - } - return static_cast(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(std::numeric_limits::lowest()) && - r.Max < static_cast(std::numeric_limits::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(r.Min), static_cast(r.Max) }; - result.Max = expandRange(frange); - } - else - { - double drange[2] = { r.Min, r.Max }; - result.Max = expandRange(drange); - } - return result; -} - - -inline vtkm::Vec hsvTorgb(const vtkm::Vec& hsv) -{ - vtkm::Vec 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& 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& 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& 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& 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 -inline bool outside_range(T&& t) { return outside_vrange(t); } - -template -inline bool outside_range(T&& t, U&& u) { return outside_vrange(t) || outside_vrange(u); } - -template -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)...); -} -// clang-format on -} - -} //namespace cont -} //namespace vtkm diff --git a/vtkm/cont/testing/TestingColorTable.h b/vtkm/cont/testing/TestingColorTable.h index c4a2fb3f8..63f254718 100644 --- a/vtkm/cont/testing/TestingColorTable.h +++ b/vtkm/cont/testing/TestingColorTable.h @@ -59,9 +59,9 @@ public: vtkm::Range range{ 0.0, 1.0 }; vtkm::Vec rgb1{ 0.0f, 0.0f, 0.0f }; vtkm::Vec 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 rgb1{ 0.0f, 1.0f, 0.0f }; vtkm::Vec 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 rgb1{ 0.0f, 1.0f, 0.0f }; vtkm::Vec 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 rgb1{ 0.0f, 0.0f, 1.0f }; vtkm::Vec 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{ 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{ 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 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{ 1.0f, 0.0f, 0.0f }); //red diff --git a/vtkm/exec/ColorTable.h b/vtkm/exec/ColorTable.h index 2f74b0286..92a689024 100644 --- a/vtkm/exec/ColorTable.h +++ b/vtkm/exec/ColorTable.h @@ -10,85 +10,121 @@ #ifndef vtk_m_exec_ColorTable_h #define vtk_m_exec_ColorTable_h -#include +#include +#include + +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 MapThroughColorSpace(double) const; + inline VTKM_EXEC vtkm::Vec3f_32 MapThroughColorSpace(vtkm::Float64) const; - VTKM_EXEC virtual vtkm::Vec MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& 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 const* RGB = nullptr; + vtkm::ColorSpace Space; - double const* ONodes = nullptr; - float const* Alpha = nullptr; - vtkm::Vec 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 NaNColor = { 0.5f, 0.0f, 0.0f }; - vtkm::Vec BelowRangeColor = { 0.0f, 0.0f, 0.0f }; - vtkm::Vec 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& first, - vtkm::Vec& 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 MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& 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 MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& 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 MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& 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 MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& 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 MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& 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; } }; } } diff --git a/vtkm/exec/ColorTable.hxx b/vtkm/exec/ColorTable.hxx index dde4bd219..29b91693c 100644 --- a/vtkm/exec/ColorTable.hxx +++ b/vtkm/exec/ColorTable.hxx @@ -21,14 +21,14 @@ namespace detail { VTKM_EXEC -inline void RGBToHSV(const vtkm::Vec& rgb, vtkm::Vec& 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& rgb, vtkm::Vec& hsv) } VTKM_EXEC -inline vtkm::Vec HSVToRGB(const vtkm::Vec& hsv) +inline vtkm::Vec3f_32 HSVToRGB(const vtkm::Vec3f_32& hsv) { - vtkm::Vec 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 HSVToRGB(const vtkm::Vec& hsv) } VTKM_EXEC -inline void RGBToLab(const vtkm::Vec& rgb, vtkm::Vec& 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& rgb, vtkm::Vec& 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& rgb, vtkm::Vec& 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& rgb, vtkm::Vec& lab) } VTKM_EXEC -inline vtkm::Vec LabToRGB(const vtkm::Vec& lab) +inline vtkm::Vec3f_32 LabToRGB(const vtkm::Vec3f_32& lab) { // clang-format off - vtkm::Vec 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 LabToRGB(const vtkm::Vec& 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( + 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 LabToRGB(const vtkm::Vec& 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 LabToRGB(const vtkm::Vec& 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 LabToRGB(const vtkm::Vec& lab) // Convert to a special polar version of CIELAB (useful for creating // continuous diverging color maps). VTKM_EXEC -inline void LabToMsh(const vtkm::Vec& lab, vtkm::Vec& 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& lab, vtkm::Vec& msh) // Convert from a special polar version of CIELAB (useful for creating // continuous diverging color maps). VTKM_EXEC -inline vtkm::Vec MshToLab(const vtkm::Vec& 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 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& 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& 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& msh, float unsatM) //--------------------------------------------------------------------------- VTKM_EXEC -vtkm::Vec ColorTableBase::MapThroughColorSpace(double value) const +vtkm::Vec3f_32 ColorTable::MapThroughColorSpace(vtkm::Float64 value) const { - vtkm::Vec 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 ColorTableBase::MapThroughColorSpace(double value) const //--------------------------------------------------------------------------- VTKM_EXEC -void ColorTableBase::FindColors(double value, - vtkm::Vec& rgb1, - vtkm::Vec& 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(w); + weight = static_cast(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(w); + vtkm::Float32 weight = static_cast(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 ColorTableRGB::MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& 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 ColorTableHSV::MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& 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 hsv1, hsv2; + vtkm::Vec3f_32 hsv1, hsv2; detail::RGBToHSV(rgb1, hsv1); detail::RGBToHSV(rgb2, hsv2); @@ -542,15 +564,15 @@ vtkm::Vec ColorTableHSV::MapThroughColorSpace(const vtkm::Vec ColorTableHSVWrap::MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& 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 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 ColorTableHSVWrap::MapThroughColorSpace(const vtkm::Vec ColorTableLab::MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& 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 lab1, lab2; + vtkm::Vec3f_32 lab1, lab2; detail::RGBToLab(rgb1, lab1); detail::RGBToLab(rgb2, lab2); @@ -585,27 +607,27 @@ vtkm::Vec ColorTableLab::MapThroughColorSpace(const vtkm::Vec ColorTableDiverging::MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& 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 lab1, lab2; + vtkm::Vec3f_32 lab1, lab2; detail::RGBToLab(rgb1, lab1); detail::RGBToLab(rgb2, lab2); - vtkm::Vec 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 ColorTableDiverging::MapThroughColorSpace(const vtkm::Vec -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 diff --git a/vtkm/filter/testing/UnitTestFieldToColors.cxx b/vtkm/filter/testing/UnitTestFieldToColors.cxx index 38648abe1..96914ca80 100644 --- a/vtkm/filter/testing/UnitTestFieldToColors.cxx +++ b/vtkm/filter/testing/UnitTestFieldToColors.cxx @@ -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{ 1.0f, 0.0f, 0.0f }); //red diff --git a/vtkm/rendering/Actor.cxx b/vtkm/rendering/Actor.cxx index e60d07c69..92825d1fb 100644 --- a/vtkm/rendering/Actor.cxx +++ b/vtkm/rendering/Actor.cxx @@ -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) diff --git a/vtkm/rendering/ColorBarAnnotation.cxx b/vtkm/rendering/ColorBarAnnotation.cxx index 4df85de24..f184b4bf0 100644 --- a/vtkm/rendering/ColorBarAnnotation.cxx +++ b/vtkm/rendering/ColorBarAnnotation.cxx @@ -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("") diff --git a/vtkm/worklet/colorconversion/TransferFunction.h b/vtkm/worklet/colorconversion/TransferFunction.h index fa9d1deed..a08d485a2 100644 --- a/vtkm/worklet/colorconversion/TransferFunction.h +++ b/vtkm/worklet/colorconversion/TransferFunction.h @@ -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 VTKM_EXEC void operator()(const T& in, vtkm::Vec3ui_8& output) const { - vtkm::Vec rgb = this->ColorTable->MapThroughColorSpace(static_cast(in)); + vtkm::Vec rgb = this->ColorTable.MapThroughColorSpace(static_cast(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 VTKM_EXEC void operator()(const T& in, vtkm::Vec4ui_8& output) const { - vtkm::Vec rgb = this->ColorTable->MapThroughColorSpace(static_cast(in)); - float alpha = this->ColorTable->MapThroughOpacitySpace(static_cast(in)); + vtkm::Vec rgb = this->ColorTable.MapThroughColorSpace(static_cast(in)); + float alpha = this->ColorTable.MapThroughOpacitySpace(static_cast(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 VTKM_EXEC void operator()(const T& in, vtkm::Vec& output) const { - output = this->ColorTable->MapThroughColorSpace(static_cast(in)); + output = this->ColorTable.MapThroughColorSpace(static_cast(in)); } template VTKM_EXEC void operator()(const T& in, vtkm::Vec& output) const { - vtkm::Vec rgb = this->ColorTable->MapThroughColorSpace(static_cast(in)); - float alpha = this->ColorTable->MapThroughOpacitySpace(static_cast(in)); + vtkm::Vec rgb = this->ColorTable.MapThroughColorSpace(static_cast(in)); + float alpha = this->ColorTable.MapThroughOpacitySpace(static_cast(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; }; } }