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
This diff is collapsed.
This diff is collapsed.
......@@ -214,83 +214,6 @@ inline vtkm::Range adjustRange(const vtkm::Range& r)
}
template <typename T>
inline vtkm::cont::ArrayHandle<T> buildSampleHandle(std::vector<T>& samples,
vtkm::Int32 numSamples,
T start,
T end,
T inc,
bool appendNanAndRangeColors)
{
int extra_values = (appendNanAndRangeColors) ? 0 : 4;
samples.reserve(static_cast<std::size_t>(numSamples + extra_values));
//Insert the below range first
if (appendNanAndRangeColors)
{
samples.push_back(std::numeric_limits<T>::lowest()); //below
}
for (T i = start; i < end; i += inc)
{
samples.push_back(i);
}
samples.push_back(end);
if (appendNanAndRangeColors)
{
//push back the last value again so that when lookups near the max value
//occur we can
samples.push_back(end);
samples.push_back(std::numeric_limits<T>::max()); //above
samples.push_back(vtkm::Nan<T>()); //nan
}
return vtkm::cont::make_ArrayHandle(samples);
}
template <typename ColorTable, typename OutputColors>
inline bool sampleColorTable(const ColorTable* self,
vtkm::Int32 numSamples,
OutputColors& colors,
double tolerance,
bool appendNanAndRangeColors)
{
vtkm::Range r = self->GetRange();
//We want the samples to start at Min, and end at Max so that means
//we want actually to interpolate numSample - 1 values. For example
//for range 0 - 1, we want the values 0, 0.5, and 1.
const double d_samples = static_cast<double>(numSamples - 1);
const double d_delta = r.Length() / d_samples;
if (r.Min > static_cast<double>(std::numeric_limits<float>::lowest()) &&
r.Max < static_cast<double>(std::numeric_limits<float>::max()))
{
//we can try and see if float space has enough resolution
const float f_samples = static_cast<float>(numSamples - 1);
const float f_start = static_cast<float>(r.Min);
const float f_delta = static_cast<float>(r.Length()) / f_samples;
const float f_end = f_delta * f_samples;
if (vtkm::Abs(static_cast<double>(f_end) - r.Max) <= tolerance &&
vtkm::Abs(static_cast<double>(f_delta) - d_delta) <= tolerance)
{
std::vector<float> samples;
auto handle =
buildSampleHandle(samples, numSamples, f_start, f_end, f_delta, appendNanAndRangeColors);
return self->Map(handle, colors);
}
}
//otherwise we need to use double space
std::vector<double> samples;
auto handle =
buildSampleHandle(samples, numSamples, r.Min, r.Max, d_delta, appendNanAndRangeColors);
return self->Map(handle, colors);
}
inline vtkm::Vec<float, 3> hsvTorgb(const vtkm::Vec<float, 3>& hsv)
{
vtkm::Vec<float, 3> rgb;
......
......@@ -30,6 +30,8 @@
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/cont/ColorTable.hxx>
#include <fstream>
#include <iostream>
......
......@@ -29,6 +29,8 @@
#include <vtkm/rendering/WorldAnnotatorGL.h>
#include <vtkm/rendering/internal/OpenGLHeaders.h>
#include <vtkm/cont/ColorTable.hxx>
namespace vtkm
{
namespace rendering
......
......@@ -20,6 +20,8 @@
#include <vtkm/rendering/Mapper.h>
#include <vtkm/cont/ColorTable.hxx>
namespace vtkm
{
namespace rendering
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment