Commit 169ca722 authored by Robert Maynard's avatar Robert Maynard

Redesign vtkm::cont::ColorTable to work with separable compilation.

parent e549cea8
......@@ -35,6 +35,8 @@
#include <vtkm/exec/FunctorBase.h>
#include <vtkm/cont/ColorTable.hxx>
#include <sstream>
#include <string>
#include <vector>
......
......@@ -125,6 +125,7 @@ set(sources
BoundsGlobalCompute.cxx
CellSet.cxx
CellSetStructured.cxx
ColorTable.cxx
DataSet.cxx
DataSetBuilderExplicit.cxx
DataSetBuilderRectilinear.cxx
......@@ -154,7 +155,6 @@ set(sources
set(device_sources
ArrayRangeCompute.cxx
CellSetExplicit.cxx
ColorTable.cxx
CoordinateSystem.cxx
)
......
......@@ -23,6 +23,9 @@
#include <vtkm/cont/ColorTable.h>
#include <vtkm/cont/ColorTable.hxx>
#include <vtkm/cont/ColorTablePrivate.hxx>
#include <vtkm/cont/ErrorBadType.h>
#include <vtkm/cont/TryExecute.h>
namespace vtkm
{
......@@ -44,7 +47,7 @@ ColorTable::ColorTable(vtkm::cont::ColorTable::Preset preset)
if (!loaded)
{ //if we failed to load the requested color table, call SetColorSpace
//so that the internal host side cache is constructed and we leave
//the constructor in a valid state. We use RGB as it is the default
//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);
}
......@@ -59,7 +62,7 @@ ColorTable::ColorTable(const std::string& name)
if (!loaded)
{ //if we failed to load the requested color table, call SetColorSpace
//so that the internal host side cache is constructed and we leave
//the constructor in a valid state. We use RGB as it is the default
//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);
}
......@@ -153,47 +156,42 @@ ColorSpace ColorTable::GetColorSpace() const
//----------------------------------------------------------------------------
void ColorTable::SetColorSpace(ColorSpace space)
{
if (this->Impl->CSpace != space || this->Impl->HostSideCache.get() == nullptr)
{
this->Impl->HostSideCacheChanged = true;
this->Impl->CSpace = space;
//Remove any existing host and execution data
//Remove any existing host information
using HandleType = vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase>;
switch (space)
{
case vtkm::cont::ColorSpace::RGB:
{
auto* hostPortal = new vtkm::exec::ColorTableRGB();
this->Impl->ExecHandle.reset(new HandleType(hostPortal, false));
this->Impl->HostSideCache.reset(hostPortal);
break;
}
case vtkm::cont::ColorSpace::HSV:
{
auto* hostPortal = new vtkm::exec::ColorTableHSV();
this->Impl->ExecHandle.reset(new HandleType(hostPortal, false));
this->Impl->HostSideCache.reset(hostPortal);
break;
}
case vtkm::cont::ColorSpace::HSV_WRAP:
{
auto* hostPortal = new vtkm::exec::ColorTableHSVWrap();
this->Impl->ExecHandle.reset(new HandleType(hostPortal, false));
this->Impl->HostSideCache.reset(hostPortal);
break;
}
case vtkm::cont::ColorSpace::LAB:
{
auto* hostPortal = new vtkm::exec::ColorTableLab();
this->Impl->ExecHandle.reset(new HandleType(hostPortal, false));
this->Impl->HostSideCache.reset(hostPortal);
break;
}
case vtkm::cont::ColorSpace::DIVERGING:
{
auto* hostPortal = new vtkm::exec::ColorTableDiverging();
this->Impl->ExecHandle.reset(new HandleType(hostPortal, false));
this->Impl->HostSideCache.reset(hostPortal);
break;
}
......@@ -788,65 +786,32 @@ bool ColorTable::FillOpacityTableFromDataPointer(vtkm::Int32 n, const float* ptr
this->Impl->OpacityArraysChanged = true;
return true;
}
//---------------------------------------------------------------------------
bool ColorTable::Sample(vtkm::Int32 numSamples,
vtkm::cont::ColorTableSamplesRGBA& samples,
double tolerance) const
{
if (numSamples <= 1)
{
return false;
}
samples.NumberOfSamples = numSamples;
samples.SampleRange = this->GetRange();
return sampleColorTable(this, numSamples, samples.Samples, tolerance, true);
}
//---------------------------------------------------------------------------
bool ColorTable::Sample(vtkm::Int32 numSamples,
vtkm::cont::ColorTableSamplesRGB& samples,
double tolerance) const
vtkm::Id ColorTable::GetModifiedCount() const
{
if (numSamples <= 1)
{
return false;
}
samples.NumberOfSamples = numSamples;
samples.SampleRange = this->GetRange();
return sampleColorTable(this, numSamples, samples.Samples, tolerance, true);
return this->Impl->HostSideCache->GetModifiedCount();
}
//---------------------------------------------------------------------------
bool ColorTable::Sample(vtkm::Int32 numSamples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& colors,
double tolerance) const
//----------------------------------------------------------------------------
bool ColorTable::NeedToCreateExecutionColorTable() const
{
if (numSamples <= 1)
{
return false;
}
return sampleColorTable(this, numSamples, colors, tolerance, false);
return this->Impl->HostSideCacheChanged;
}
//---------------------------------------------------------------------------
bool ColorTable::Sample(vtkm::Int32 numSamples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& colors,
double tolerance) const
//----------------------------------------------------------------------------
void ColorTable::UpdateExecutionColorTable(
vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase>* handle) const
{
if (numSamples <= 1)
{
return false;
}
return sampleColorTable(this, numSamples, colors, tolerance, false);
this->Impl->ExecHandle.reset(handle);
}
//---------------------------------------------------------------------------
const vtkm::exec::ColorTableBase* ColorTable::PrepareForExecution(
vtkm::cont::DeviceAdapterId deviceId) const
//----------------------------------------------------------------------------
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);
......@@ -860,56 +825,32 @@ const vtkm::exec::ColorTableBase* ColorTable::PrepareForExecution(
this->Impl->OpacityMidSharpHandle = vtkm::cont::make_ArrayHandle(this->Impl->OpacityMidSharp);
}
bool transfered = true;
if (this->Impl->ColorArraysChanged || this->Impl->OpacityArraysChanged ||
this->Impl->HostSideCacheChanged)
{
transfered = vtkm::cont::TryExecuteOnDevice(deviceId,
detail::transfer_color_table_to_device{},
this->Impl->HostSideCache.get(),
this->Impl.get());
}
if (!transfered)
{
throwFailedRuntimeDeviceTransfer("ColorTable", deviceId);
}
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 this->Impl->ExecHandle->PrepareForExecution(deviceId);
return state;
}
//---------------------------------------------------------------------------
vtkm::Id ColorTable::GetModifiedCount() const
//----------------------------------------------------------------------------
vtkm::exec::ColorTableBase* ColorTable::GetControlRepresentation() const
{
return this->Impl->HostSideCache->GetModifiedCount();
return this->Impl->HostSideCache.get();
}
/*
#define ColorTableExportMapFunctions(T) \
template VTKM_CONT_EXPORT bool ColorTable::Map( \
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic>&, \
const vtkm::cont::ColorTableSamplesRGBA&, \
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>&) const; \
template VTKM_CONT_EXPORT bool ColorTable::Map( \
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic>&, \
const vtkm::cont::ColorTableSamplesRGB&, \
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>&) const; \
template VTKM_CONT_EXPORT bool ColorTable::Map( \
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic>&, \
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>&) const; \
template VTKM_CONT_EXPORT bool ColorTable::Map( \
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic>&, \
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>&) const;
ColorTableExportMapFunctions(char);
ColorTableExportMapFunctions(vtkm::UInt8);
ColorTableExportMapFunctions(vtkm::Int8);
ColorTableExportMapFunctions(vtkm::Float32);
ColorTableExportMapFunctions(vtkm::Float64);
#undef ColorTableExportMapFunctions
*/
//----------------------------------------------------------------------------
vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase> const* ColorTable::GetExecutionHandle()
const
{
return this->Impl->ExecHandle.get();
}
}
} //namespace vtkm::cont
......@@ -497,9 +497,9 @@ public:
///
/// \endcode
template <typename T, typename S>
bool Map(const vtkm::cont::ArrayHandle<T, S>& values,
const vtkm::cont::ColorTableSamplesRGBA& samples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& rgbaOut) const;
inline bool Map(const vtkm::cont::ArrayHandle<T, S>& values,
const vtkm::cont::ColorTableSamplesRGBA& samples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& rgbaOut) const;
/// \brief Sample each value through an intermediate lookup/sample table to generate RGB colors
///
......@@ -518,39 +518,39 @@ public:
///
/// \endcode
template <typename T, typename S>
bool Map(const vtkm::cont::ArrayHandle<T, S>& values,
const vtkm::cont::ColorTableSamplesRGB& samples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& rgbaOut) const;
inline bool Map(const vtkm::cont::ArrayHandle<T, S>& values,
const vtkm::cont::ColorTableSamplesRGB& samples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& rgbaOut) const;
/// \brief Use magnitude of a vector with a sample table to generate RGBA colors
///
template <typename T, int N, typename S>
bool MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
const vtkm::cont::ColorTableSamplesRGBA& samples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& rgbaOut) const;
inline bool MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
const vtkm::cont::ColorTableSamplesRGBA& samples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& rgbaOut) const;
/// \brief Use magnitude of a vector with a sample table to generate RGB colors
///
template <typename T, int N, typename S>
bool MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
const vtkm::cont::ColorTableSamplesRGB& samples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& rgbaOut) const;
inline bool MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
const vtkm::cont::ColorTableSamplesRGB& samples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& rgbaOut) const;
/// \brief Use a single component of a vector with a sample table to generate RGBA colors
///
template <typename T, int N, typename S>
bool MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
const vtkm::cont::ColorTableSamplesRGBA& samples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& rgbaOut) const;
inline bool MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
const vtkm::cont::ColorTableSamplesRGBA& samples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& rgbaOut) const;
/// \brief Use a single component of a vector with a sample table to generate RGB colors
///
template <typename T, int N, typename S>
bool MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
const vtkm::cont::ColorTableSamplesRGB& samples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& rgbOut) const;
inline bool MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
const vtkm::cont::ColorTableSamplesRGB& samples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& rgbOut) const;
/// \brief Interpolate each value through the color table to generate RGBA colors
......@@ -560,8 +560,8 @@ public:
///
/// Note: This is more costly than using Sample/Map with the generated intermediate lookup table
template <typename T, typename S>
bool Map(const vtkm::cont::ArrayHandle<T, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& rgbaOut) const;
inline bool Map(const vtkm::cont::ArrayHandle<T, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& rgbaOut) const;
/// \brief Interpolate each value through the color table to generate RGB colors
///
......@@ -570,34 +570,34 @@ public:
///
/// Note: This is more costly than using Sample/Map with the generated intermediate lookup table
template <typename T, typename S>
bool Map(const vtkm::cont::ArrayHandle<T, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& rgbOut) const;
inline bool Map(const vtkm::cont::ArrayHandle<T, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& rgbOut) const;
/// \brief Use magnitude of a vector to generate RGBA colors
///
template <typename T, int N, typename S>
bool MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& rgbaOut) const;
inline bool MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& rgbaOut) const;
/// \brief Use magnitude of a vector to generate RGB colors
///
template <typename T, int N, typename S>
bool MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& rgbOut) const;
inline bool MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& rgbOut) const;
/// \brief Use a single component of a vector to generate RGBA colors
///
template <typename T, int N, typename S>
bool MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& rgbaOut) const;
inline bool MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& rgbaOut) const;
/// \brief Use a single component of a vector to generate RGB colors
///
template <typename T, int N, typename S>
bool MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& rgbOut) const;
inline bool MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& rgbOut) const;
/// \brief generate RGB colors using regular spaced samples along the range.
......@@ -611,9 +611,9 @@ public:
/// - ((max-min) / numSamples) * numSamples
///
/// Note: This will return false if the number of samples is less than 2
bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ColorTableSamplesRGBA& samples,
double tolerance = 0.002) const;
inline bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ColorTableSamplesRGBA& samples,
double tolerance = 0.002) const;
/// \brief generate a sample lookup table using regular spaced samples along the range.
///
......@@ -626,9 +626,9 @@ public:
/// - ((max-min) / numSamples) * numSamples
///
/// Note: This will return false if the number of samples is less than 2
bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ColorTableSamplesRGB& samples,
double tolerance = 0.002) const;
inline bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ColorTableSamplesRGB& samples,
double tolerance = 0.002) const;
/// \brief generate RGBA colors using regular spaced samples along the range.
///
......@@ -641,9 +641,9 @@ public:
/// - ((max-min) / numSamples) * numSamples
///
/// Note: This will return false if the number of samples is less than 2
bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& colors,
double tolerance = 0.002) const;
inline bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& colors,
double tolerance = 0.002) const;
/// \brief generate RGB colors using regular spaced samples along the range.
///
......@@ -656,21 +656,46 @@ public:
/// - ((max-min) / numSamples) * numSamples
///
/// Note: This will return false if the number of samples is less than 2
bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& colors,
double tolerance = 0.002) const;
inline bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& colors,
double 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
const vtkm::exec::ColorTableBase* PrepareForExecution(vtkm::cont::DeviceAdapterId deviceId) const;
inline const vtkm::exec::ColorTableBase* PrepareForExecution(
vtkm::cont::DeviceAdapterId deviceId) const;
/// \brief returns the modified count for the virtual object handle of the exec 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.
vtkm::Id GetModifiedCount() const;
struct TransferState
{
bool NeedsTransfer;
vtkm::exec::ColorTableBase* Portal;
const vtkm::cont::ArrayHandle<double>& ColorPosHandle;
const vtkm::cont::ArrayHandle<vtkm::Vec<float, 3>>& ColorRGBHandle;
const vtkm::cont::ArrayHandle<double>& OpacityPosHandle;
const vtkm::cont::ArrayHandle<float>& OpacityAlphaHandle;
const vtkm::cont::ArrayHandle<vtkm::Vec<float, 2>>& OpacityMidSharpHandle;
};
private:
bool NeedToCreateExecutionColorTable() const;
//takes ownership of the pointer passed in
void UpdateExecutionColorTable(
vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase>*) const;
ColorTable::TransferState GetExecutionDataForTransfer() const;
vtkm::exec::ColorTableBase* GetControlRepresentation() const;
vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase> const* GetExecutionHandle() const;
};
}
} //namespace vtkm::cont
......
......@@ -17,6 +17,10 @@
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_ColorTable_hxx
#define vtk_m_cont_ColorTable_hxx
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandleTransform.h>
#include <vtkm/cont/TryExecute.h>
......@@ -50,44 +54,43 @@ inline T* get_ptr(stdext::checked_array_iterator<T*> t)
}
#endif
struct map_color_table
{
template <typename DeviceAdapter, typename ColorTable, typename... Args>
bool operator()(DeviceAdapter device, ColorTable&& colors, Args&&... args) const
{
vtkm::worklet::colorconversion::TransferFunction transfer(colors->PrepareForExecution(device));
vtkm::worklet::Invoker invoke(device);
invoke(transfer, std::forward<Args>(args)...);
return true;
}
};
struct transfer_color_table_to_device
{
template <typename DeviceAdapter, typename ColorTableInternals>
bool operator()(DeviceAdapter device,
vtkm::exec::ColorTableBase* portal,
ColorTableInternals* internals) const
template <typename DeviceAdapter>
inline bool operator()(DeviceAdapter device, vtkm::cont::ColorTable::TransferState&& state) const
{
auto p1 = internals->ColorPosHandle.PrepareForInput(device);
auto p2 = internals->ColorRGBHandle.PrepareForInput(device);
auto p3 = internals->OpacityPosHandle.PrepareForInput(device);
auto p4 = internals->OpacityAlphaHandle.PrepareForInput(device);
auto p5 = internals->OpacityMidSharpHandle.PrepareForInput(device);
auto p1 = state.ColorPosHandle.PrepareForInput(device);
auto p2 = state.ColorRGBHandle.PrepareForInput(device);
auto p3 = state.OpacityPosHandle.PrepareForInput(device);
auto p4 = state.OpacityAlphaHandle.PrepareForInput(device);
auto p5 = state.OpacityMidSharpHandle.PrepareForInput(device);
//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
portal->ColorSize = static_cast<vtkm::Int32>(internals->ColorPosHandle.GetNumberOfValues());
portal->OpacitySize = static_cast<vtkm::Int32>(internals->OpacityPosHandle.GetNumberOfValues());
state.Portal->ColorSize = static_cast<vtkm::Int32>(state.ColorPosHandle.GetNumberOfValues());
state.Portal->OpacitySize =
static_cast<vtkm::Int32>(state.OpacityPosHandle.GetNumberOfValues());
state.Portal->ColorNodes = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p1));
state.Portal->RGB = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p2));
state.Portal->ONodes = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p3));
state.Portal->Alpha = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p4));
state.Portal->MidSharp = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p5));
state.Portal->Modified();
return true;
}
};
portal->ColorNodes = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p1));
portal->RGB = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p2));
portal->ONodes = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p3));
portal->Alpha = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p4));
portal->MidSharp = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p5));
portal->Modified();
struct map_color_table
{
template <typename DeviceAdapter, typename ColorTable, typename... Args>
inline bool operator()(DeviceAdapter device, ColorTable&& colors, Args&&... args) const
{
vtkm::worklet::colorconversion::TransferFunction transfer(colors->PrepareForExecution(device));
vtkm::worklet::Invoker invoke(device);
invoke(transfer, std::forward<Args>(args)...);
return true;
}
};
......@@ -215,5 +218,206 @@ bool ColorTable::MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>&
using namespace vtkm::worklet::colorconversion;
return this->Map(vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), rgbOut);
}
namespace
{
template <typename T>
inline vtkm::cont::ArrayHandle<T> buildSampleHandle(vtkm::Int32 numSamples,
T start,
T end,
T inc,
bool appendNanAndRangeColors)
{
//number of samples + end + appendNanAndRangeColors
vtkm::Int32 allocationSize = (appendNanAndRangeColors) ? numSamples + 5 : numSamples + 1;
vtkm::cont::ArrayHandle<T> handle;
handle.Allocate(allocationSize);
auto portal = handle.GetPortalControl();
vtkm::Id index = 0;
//Insert the below range first
if (appendNanAndRangeColors)
{
portal.Set(index++, std::numeric_limits<T>::lowest()); //below
}
//add number of samples which doesn't account for the end
T value = start;
for (vtkm::Int32 i = 0; i < numSamples; ++i, ++index, value += inc)
{
portal.Set(index, value);
}
portal.Set(index++, end);
if (appendNanAndRangeColors)
{
//push back the last value again so that when lookups near the max value
//occur we don't need to clamp as if they are out-of-bounds they will
//land in the extra 'end' color
portal.Set(index++, end);
portal.Set(index++, std::numeric_limits<T>::max()); //above
portal.Set(index++, vtkm::Nan<T>()); //nan