Merge branch 'master' into vtk-m-cmake_refactor

This commit is contained in:
Robert Maynard 2018-03-29 17:25:36 -04:00
commit 8808b41fbd
318 changed files with 8758 additions and 4305 deletions

@ -21,6 +21,4 @@
list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
".*warning: ignoring loop annotation.*"
".*warning: Included by graph for.*not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES."
".*diy.include.*diy.mpi.io.hpp.*Wconversion.*"
".*diy.include.*diy.mpi.datatypes.hpp.*Wunused-parameter.*"
)

@ -61,7 +61,7 @@ VTK-m Requires:
+ GCC 4.8+
+ Clang 3.3+
+ XCode 5.0+
+ MSVC 2013+
+ MSVC 2015+
+ [CMake](http://www.cmake.org/download/)
+ CMake 3.3+ (for any build)
+ CMake 3.9+ (for CUDA build)
@ -153,7 +153,7 @@ camera.SetViewUp(vtkm::make_Vec(0.f, 1.f, 0.f));
camera.SetClippingRange(1.f, 100.f);
camera.SetFieldOfView(60.f);
camera.SetPosition(totalExtent*(mag * 2.f));
vtkm::rendering::ColorTable colorTable("thermal");
vtkm::cont::ColorTable colorTable("inferno");
// Create a mapper, canvas and view that will be used to render the scene
vtkm::rendering::Scene scene;

@ -161,7 +161,7 @@ struct ExtendedTypes : vtkm::ListTagBase<vtkm::UInt8,
{
};
const static std::string DIVIDER(40, '-');
static const std::string DIVIDER(40, '-');
/// This class runs a series of micro-benchmarks to measure
/// performance of the parallel primitives provided by each

@ -46,7 +46,7 @@ namespace benchmarking
#define ARRAY_SIZE (1 << 22)
#define CUBE_SIZE 256
const static std::string DIVIDER(40, '-');
static const std::string DIVIDER(40, '-');
enum BenchmarkName
{

@ -79,8 +79,24 @@ struct BenchRayTracing
Tracer.SetData(Coords.GetData(), Indices, field, NumberOfTriangles, range, bounds);
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>> temp;
vtkm::cont::ColorTable table("cool to warm");
table.Sample(100, temp);
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>> colors;
vtkm::rendering::ColorTable("cool2warm").Sample(100, colors);
colors.Allocate(100);
auto portal = colors.GetPortalControl();
auto colorPortal = temp.GetPortalConstControl();
constexpr vtkm::Float32 conversionToFloatSpace = (1.0f / 255.0f);
for (vtkm::Id i = 0; i < 100; ++i)
{
auto color = colorPortal.Get(i);
vtkm::Vec<vtkm::Float32, 4> t(color[0] * conversionToFloatSpace,
color[1] * conversionToFloatSpace,
color[2] * conversionToFloatSpace,
color[3] * conversionToFloatSpace);
portal.Set(i, t);
}
Tracer.SetColorMap(colors);
Tracer.Render(Rays);

@ -42,7 +42,7 @@ namespace benchmarking
{
#define CUBE_SIZE 256
const static std::string DIVIDER(40, '-');
static const std::string DIVIDER(40, '-');
enum BenchmarkName
{

@ -168,8 +168,7 @@ class ExposedClass;
namespace references are preferred).
+ All code must be valid by the C++11 specifications. It must also
compile correctly with Microsoft Visual Studio 2013, which implements a
subset of the C++11 standard.
compile with Microsoft Visual Studio 2015.
+ New code must include regression tests that will run on the dashboards.
Generally a new class will have an associated "UnitTest" that will test

@ -93,10 +93,12 @@ int main(int argc, char* argv[])
vtkm::cont::Timer<DeviceAdapter> total;
vtkm::cont::Timer<DeviceAdapter> timer;
bool invertClip = false;
vtkm::cont::CellSetExplicit<> outputCellSet =
clip.Run(input.GetCellSet(0),
scalarField.GetData().ResetTypeList(vtkm::TypeListTagScalarAll()),
clipValue,
invertClip,
DeviceAdapter());
vtkm::Float64 clipTime = timer.GetElapsedTime();

@ -115,14 +115,13 @@ int main(int argc, char* argv[])
vtkm::cont::DataSetFieldAdd dsf;
dsf.AddPointField(inDataSet, "values", values);
// Output data set is pairs of saddle and peak vertex IDs
vtkm::filter::Result result;
// Convert 2D mesh of values into contour tree, pairs of vertex ids
vtkm::filter::ContourTreeMesh2D filter;
result = filter.Execute(inDataSet, std::string("values"));
vtkm::cont::Field resultField = result.GetField();
filter.SetActiveField("values");
// Output data set is pairs of saddle and peak vertex IDs
vtkm::cont::DataSet output = filter.Execute(inDataSet);
vtkm::cont::Field resultField = output.GetField("saddlePeak");
;
vtkm::cont::ArrayHandle<vtkm::Pair<vtkm::Id, vtkm::Id>> saddlePeak;
resultField.GetData().CopyTo(saddlePeak);

@ -116,14 +116,13 @@ int main(int argc, char* argv[])
vtkm::cont::DataSetFieldAdd dsf;
dsf.AddPointField(inDataSet, "values", values);
// Output data set is pairs of saddle and peak vertex IDs
vtkm::filter::Result result;
// Convert 3D mesh of values into contour tree, pairs of vertex ids
vtkm::filter::ContourTreeMesh3D filter;
result = filter.Execute(inDataSet, std::string("values"));
filter.SetActiveField("values");
// Output data set is pairs of saddle and peak vertex IDs
vtkm::cont::DataSet output = filter.Execute(inDataSet);
vtkm::cont::Field resultField = result.GetField();
vtkm::cont::Field resultField = output.GetField("saddlePeak");
vtkm::cont::ArrayHandle<vtkm::Pair<vtkm::Id, vtkm::Id>> saddlePeak;
resultField.GetData().CopyTo(saddlePeak);

@ -35,7 +35,7 @@
#include <iostream>
void makeScene(const vtkm::cont::DataSet& inputData,
const vtkm::rendering::ColorTable& colorTable,
const vtkm::cont::ColorTable& colorTable,
const std::string& fieldName,
vtkm::rendering::Scene& scene)
{
@ -100,7 +100,7 @@ int main(int argc, char* argv[])
camera.SetClippingRange(1.f, 100.f);
camera.SetFieldOfView(60.f);
camera.SetPosition(totalExtent * (mag * 2.f));
vtkm::rendering::ColorTable colorTable("thermal");
vtkm::cont::ColorTable colorTable("inferno");
// Create a scene for rendering the input data
vtkm::rendering::Scene scene;

@ -168,6 +168,16 @@ public:
return vtkm::filter::Result(output);
}
template <typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
VTKM_CONT bool DoMapField(vtkm::filter::Result&,
const vtkm::cont::ArrayHandle<T, StorageType>&,
const vtkm::filter::FieldMetadata&,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
DeviceAdapter)
{
return false;
}
};
struct UploadData
@ -370,11 +380,11 @@ int main(int argc, char** argv)
glutDisplayFunc([]() {
const vtkm::Float32 c = static_cast<vtkm::Float32>(gTimer.GetElapsedTime());
vtkm::filter::Result rdata = gFilter->Execute(*gData, GameOfLifePolicy());
gRenderer->render(rdata.GetDataSet());
vtkm::cont::DataSet oData = gFilter->Execute(*gData, GameOfLifePolicy());
gRenderer->render(oData);
glutSwapBuffers();
*gData = rdata.GetDataSet();
*gData = oData;
if (c > 120)
{

@ -246,13 +246,12 @@ int main(int argc, char* argv[])
filter.SetGenerateNormals(true);
filter.SetMergeDuplicatePoints(false);
filter.SetIsoValue(0, 0.1);
vtkm::filter::Result result = filter.Execute(dataSet, dataSet.GetField("nodevar"));
filter.SetActiveField("nodevar");
filter.SetFieldsToPass({ "nodevar" });
filter.MapFieldOntoOutput(result, dataSet.GetField("nodevar"));
vtkm::cont::DataSet outputData = filter.Execute(dataSet);
//need to extract vertices, normals, and scalars
vtkm::cont::DataSet& outputData = result.GetDataSet();
using VertType = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>>;
vtkm::cont::CoordinateSystem coords = outputData.GetCoordinateSystem();

@ -42,8 +42,8 @@
#include <GL/glut.h>
#endif
#include <vtkm/cont/ColorTable.h>
#include <vtkm/rendering/CanvasGL.h>
#include <vtkm/rendering/ColorTable.h>
#include <vtkm/rendering/MapperGL.h>
#include <vtkm/rendering/View3D.h>
@ -141,7 +141,7 @@ int main(int argc, char* argv[])
scene.AddActor(vtkm::rendering::Actor(ds.GetCellSet(),
ds.GetCoordinateSystem(),
ds.GetField("pointvar"),
vtkm::rendering::ColorTable("thermal")));
vtkm::cont::ColorTable("inferno")));
//Create vtkm rendering stuff.
view = new vtkm::rendering::View3D(scene, mapper, canvas, bg);

@ -348,7 +348,7 @@ void RenderRTTest(const vtkm::cont::DataSet& ds, int N)
using V3 = vtkm::rendering::View3D;
//std::cout<<"Render: "<<i<<std::endl;
vtkm::rendering::ColorTable colorTable("thermal");
vtkm::cont::ColorTable colorTable("inferno");
vtkm::rendering::testing::Render<M, C, V3>(ds, "scalar", colorTable);
}
}
@ -366,7 +366,7 @@ void RenderVolTest(const vtkm::cont::DataSet& ds, int N)
using V3 = vtkm::rendering::View3D;
//std::cout<<"Render: "<<i<<std::endl;
vtkm::rendering::ColorTable colorTable("thermal");
vtkm::cont::ColorTable colorTable("inferno");
vtkm::rendering::testing::Render<M, C, V3>(ds, "scalar", colorTable);
}
}

@ -272,9 +272,7 @@ int main(int argc, char* argv[])
// Convert cells to tetrahedra
vtkm::filter::Tetrahedralize tetrahedralize;
vtkm::filter::Result result = tetrahedralize.Execute(inDataSet);
outDataSet = result.GetDataSet();
outDataSet = tetrahedralize.Execute(inDataSet);
// Render the output dataset of tets
lastx = lasty = 0;

@ -254,9 +254,7 @@ int main(int argc, char* argv[])
vtkm::cont::DataSet inDataSet = MakeTetrahedralizeTestDataSet(dims);
vtkm::filter::Tetrahedralize tetrahedralize;
vtkm::filter::Result result = tetrahedralize.Execute(inDataSet);
tetDataSet = result.GetDataSet();
tetDataSet = tetrahedralize.Execute(inDataSet);
// Render the output dataset of tets
lastx = lasty = 0;

@ -192,8 +192,7 @@ int main(int argc, char* argv[])
// Convert 2D explicit cells to triangles
vtkm::filter::Triangulate triangulate;
vtkm::filter::Result result = triangulate.Execute(inDataSet);
outDataSet = result.GetDataSet();
outDataSet = triangulate.Execute(inDataSet);
// Render the output dataset of tets
glutInit(&argc, argv);

@ -159,9 +159,7 @@ int main(int argc, char* argv[])
// Convert uniform quad to triangle
vtkm::filter::Triangulate triangulate;
vtkm::filter::Result result = triangulate.Execute(inDataSet);
triDataSet = result.GetDataSet();
triDataSet = triangulate.Execute(inDataSet);
// Render the output dataset of tets
glutInit(&argc, argv);

@ -38,7 +38,11 @@
///
/// The VTKM_NO_ASSERT cmake and preprocessor option allows debugging builds
/// to remove assertions for performance reasons.
#if !defined(NDEBUG) && !defined(VTKM_NO_ASSERT)
#if defined(VTKM_CUDA_VERSION_MAJOR) && (VTKM_CUDA_VERSION_MAJOR == 7)
//CUDA 7.5 doesn't support assert in device code
#define VTKM_ASSERT(condition) (void)(condition)
#elif !defined(NDEBUG) && !defined(VTKM_NO_ASSERT)
//Only assert if we are in debug mode and don't have VTKM_NO_ASSERT defined
#define VTKM_ASSERT(condition) assert(condition)
#else
#define VTKM_ASSERT(condition) (void)(condition)

@ -67,11 +67,7 @@ vtkm_declare_headers(${headers})
#-----------------------------------------------------------------------------
#first add all the components vtkm that are shared between control and exec
if(VTKm_ENABLE_MPI)
# This `if` is temporary and will be removed once `diy` supports building
# without MPI.
add_subdirectory(thirdparty/diy)
endif()
add_subdirectory(thirdparty/diy)
add_subdirectory(testing)
add_subdirectory(internal)

@ -96,7 +96,7 @@ struct CellShapeIdToTag
#define VTKM_DEFINE_CELL_TAG(name, idname) \
struct CellShapeTag##name \
{ \
static const vtkm::UInt8 Id = vtkm::idname; \
static constexpr vtkm::UInt8 Id = vtkm::idname; \
}; \
namespace internal \
{ \

@ -59,7 +59,7 @@ struct CellTraits
/// This defines the topological dimensions of the cell type. 3 for
/// polyhedra, 2 for polygons, 1 for lines, 0 for points.
///
const static vtkm::IdComponent TOPOLOGICAL_DIMENSIONS = 3;
static const vtkm::IdComponent TOPOLOGICAL_DIMENSIONS = 3;
/// This tag is typedef'ed to
/// vtkm::CellTopologicalDimensionsTag<TOPOLOGICAL_DIMENSIONS>. This provides
@ -81,7 +81,7 @@ struct CellTraits
/// This is only defined for cell shapes of a fixed number of points (i.e.
/// \c IsSizedFixed is set to \c CellTraitsTagSizeFixed.
///
static const vtkm::IdComponent NUM_POINTS = 3;
static constexpr vtkm::IdComponent NUM_POINTS = 3;
};
#else // VTKM_DOXYGEN_ONLY
;

@ -32,8 +32,8 @@ using HashType = vtkm::UInt32;
namespace detail
{
static const vtkm::HashType FNV1A_OFFSET = 2166136261;
static const vtkm::HashType FNV1A_PRIME = 16777619;
static constexpr vtkm::HashType FNV1A_OFFSET = 2166136261;
static constexpr vtkm::HashType FNV1A_PRIME = 16777619;
/// \brief Performs an FNV-1a hash on 32-bit integers returning a 32-bit hash
///

@ -36,7 +36,7 @@ namespace internal
template <typename ListTag>
struct ListTagCheck : std::is_base_of<vtkm::detail::ListRoot, ListTag>
{
static VTKM_CONSTEXPR bool Valid = std::is_base_of<vtkm::detail::ListRoot, ListTag>::value;
static constexpr bool Valid = std::is_base_of<vtkm::detail::ListRoot, ListTag>::value;
};
} // namespace internal
@ -111,7 +111,7 @@ template <typename ListTag, typename Type>
struct ListContains
{
VTKM_IS_LIST_TAG(ListTag);
static VTKM_CONSTEXPR bool value = detail::ListContainsImpl<Type, typename ListTag::list>::value;
static constexpr bool value = detail::ListContainsImpl<Type, typename ListTag::list>::value;
};
} // namespace vtkm

@ -46,8 +46,8 @@ class Matrix
{
public:
using ComponentType = T;
static const vtkm::IdComponent NUM_ROWS = NumRow;
static const vtkm::IdComponent NUM_COLUMNS = NumCol;
static constexpr vtkm::IdComponent NUM_ROWS = NumRow;
static constexpr vtkm::IdComponent NUM_COLUMNS = NumCol;
VTKM_EXEC_CONT
Matrix() {}
@ -547,7 +547,7 @@ private:
public:
using ComponentType = T;
static const vtkm::IdComponent NUM_COMPONENTS = NumRow * NumCol;
static constexpr vtkm::IdComponent NUM_COMPONENTS = NumRow * NumCol;
using HasMultipleComponents = vtkm::VecTraitsTagMultipleComponents;
using IsSizeStatic = vtkm::VecTraitsTagSizeStatic;

@ -207,7 +207,7 @@ struct TypeListTagCommon : vtkm::ListTagBase<vtkm::Int32,
template <typename Type>
struct ListContains<vtkm::TypeListTagAll, Type>
{
static const bool value = true;
static constexpr bool value = true;
};
} // namespace vtkm

@ -606,7 +606,7 @@ class VTKM_ALWAYS_EXPORT VecBase : public vtkm::detail::VecBaseCommon<T, Derived
{
public:
using ComponentType = T;
static const vtkm::IdComponent NUM_COMPONENTS = Size;
static constexpr vtkm::IdComponent NUM_COMPONENTS = Size;
protected:
VecBase() = default;
@ -764,7 +764,7 @@ class VTKM_ALWAYS_EXPORT Vec : public detail::VecBase<T, Size, Vec<T, Size>>
public:
#ifdef VTKM_DOXYGEN_ONLY
using ComponentType = T;
static const vtkm::IdComponent NUM_COMPONENTS = Size;
static constexpr vtkm::IdComponent NUM_COMPONENTS = Size;
#endif
Vec() = default;
@ -792,7 +792,7 @@ class VTKM_ALWAYS_EXPORT Vec<T, 0>
{
public:
using ComponentType = T;
static const vtkm::IdComponent NUM_COMPONENTS = 0;
static constexpr vtkm::IdComponent NUM_COMPONENTS = 0;
Vec() = default;
VTKM_EXEC_CONT explicit Vec(const ComponentType&) {}

@ -25,6 +25,7 @@
#include <vtkm/TypeTraits.h>
#include <vtkm/Types.h>
#include <vtkm/VecTraits.h>
#include <vtkm/internal/ExportMacros.h>
namespace vtkm
{
@ -41,19 +42,31 @@ struct VecAxisAlignedPointCoordinatesNumComponents;
template <>
struct VecAxisAlignedPointCoordinatesNumComponents<1>
{
static const vtkm::IdComponent NUM_COMPONENTS = 2;
static constexpr vtkm::IdComponent NUM_COMPONENTS = 2;
};
template <>
struct VecAxisAlignedPointCoordinatesNumComponents<2>
{
static const vtkm::IdComponent NUM_COMPONENTS = 4;
static constexpr vtkm::IdComponent NUM_COMPONENTS = 4;
};
template <>
struct VecAxisAlignedPointCoordinatesNumComponents<3>
{
static const vtkm::IdComponent NUM_COMPONENTS = 8;
static constexpr vtkm::IdComponent NUM_COMPONENTS = 8;
};
struct VecAxisAlignedPointCoordinatesOffsetTable
{
VTKM_EXEC_CONT vtkm::FloatDefault Get(vtkm::Int32 i, vtkm::Int32 j) const
{
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::FloatDefault offsetTable[8][3] = {
{ 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }
};
return offsetTable[i][j];
}
};
} // namespace detail
@ -77,7 +90,7 @@ class VecAxisAlignedPointCoordinates
public:
using ComponentType = vtkm::Vec<vtkm::FloatDefault, 3>;
static const vtkm::IdComponent NUM_COMPONENTS =
static constexpr vtkm::IdComponent NUM_COMPONENTS =
detail::VecAxisAlignedPointCoordinatesNumComponents<NumDimensions>::NUM_COMPONENTS;
VTKM_EXEC_CONT
@ -104,15 +117,10 @@ public:
VTKM_EXEC_CONT
ComponentType operator[](vtkm::IdComponent index) const
{
static const vtkm::FloatDefault VecAxisAlignedPointCoordinatesOffsetTable[8][3] = {
{ 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }
};
const auto& offset = VecAxisAlignedPointCoordinatesOffsetTable[index];
return ComponentType(this->Origin[0] + offset[0] * this->Spacing[0],
this->Origin[1] + offset[1] * this->Spacing[1],
this->Origin[2] + offset[2] * this->Spacing[2]);
detail::VecAxisAlignedPointCoordinatesOffsetTable table;
return ComponentType(this->Origin[0] + table.Get(index, 0) * this->Spacing[0],
this->Origin[1] + table.Get(index, 1) * this->Spacing[1],
this->Origin[2] + table.Get(index, 2) * this->Spacing[2]);
}
VTKM_EXEC_CONT
@ -152,7 +160,7 @@ struct VecTraits<vtkm::VecAxisAlignedPointCoordinates<NumDimensions>>
using HasMultipleComponents = vtkm::VecTraitsTagMultipleComponents;
using IsSizeStatic = vtkm::VecTraitsTagSizeStatic;
static const vtkm::IdComponent NUM_COMPONENTS = VecType::NUM_COMPONENTS;
static constexpr vtkm::IdComponent NUM_COMPONENTS = VecType::NUM_COMPONENTS;
VTKM_EXEC_CONT
static vtkm::IdComponent GetNumberOfComponents(const VecType&) { return NUM_COMPONENTS; }

@ -84,7 +84,7 @@ struct VecTraits
///
/// This is only defined for vectors of a static size.
///
static const vtkm::IdComponent NUM_COMPONENTS = VecType::NUM_COMPONENTS;
static constexpr vtkm::IdComponent NUM_COMPONENTS = VecType::NUM_COMPONENTS;
/// Number of components in the given vector.
///
@ -149,7 +149,7 @@ struct VecTraits<vtkm::Vec<T, Size>>
/// Number of components in the vector.
///
static const vtkm::IdComponent NUM_COMPONENTS = VecType::NUM_COMPONENTS;
static constexpr vtkm::IdComponent NUM_COMPONENTS = VecType::NUM_COMPONENTS;
/// Number of components in the given vector.
///
@ -335,7 +335,7 @@ template <typename ScalarType>
struct VecTraitsBasic
{
using ComponentType = ScalarType;
static const vtkm::IdComponent NUM_COMPONENTS = 1;
static constexpr vtkm::IdComponent NUM_COMPONENTS = 1;
using HasMultipleComponents = vtkm::VecTraitsTagSingleComponent;
using IsSizeStatic = vtkm::VecTraitsTagSizeStatic;

@ -59,7 +59,7 @@ VTKM_EXEC_CONT vtkm::Vec<ValueType, N> Lerp(const vtkm::Vec<ValueType, N>& value
const vtkm::Vec<ValueType, N>& value1,
const vtkm::Vec<ValueType, N>& weight)
{
static const vtkm::Vec<ValueType, N> One(ValueType(1));
const vtkm::Vec<ValueType, N> One(ValueType(1));
return (One - weight) * value0 + weight * value1;
}

@ -58,20 +58,28 @@ class VTKM_CONT_EXPORT ArrayHandleBase
{
};
/// Checks to see if the given type and storage can form a valid array handle
/// Checks to see if the given type and storage forms a valid array handle
/// (some storage objects cannot support all types). This check is compatible
/// with C++11 type_traits. It contains a
/// typedef named type that is either std::true_type or std::false_type.
/// Both of these have a typedef named value with the respective boolean value.
/// with C++11 type_traits.
///
template <typename T, typename StorageTag>
struct IsValidArrayHandle
{
//need to add the not
using type =
std::integral_constant<bool,
: std::integral_constant<bool,
!(std::is_base_of<vtkm::cont::internal::UndefinedStorage,
vtkm::cont::internal::Storage<T, StorageTag>>::value)>;
vtkm::cont::internal::Storage<T, StorageTag>>::value)>
{
};
/// Checks to see if the given type and storage forms a invalid array handle
/// (some storage objects cannot support all types). This check is compatible
/// with C++11 type_traits.
///
template <typename T, typename StorageTag>
struct IsInValidArrayHandle
: std::integral_constant<bool,
(std::is_base_of<vtkm::cont::internal::UndefinedStorage,
vtkm::cont::internal::Storage<T, StorageTag>>::value)>
{
};
/// Checks to see if the ArrayHandle for the given DeviceAdatper allows
@ -97,6 +105,7 @@ private:
public:
using type = std::integral_constant<bool, !IsVoidType::value>;
static constexpr bool value = !IsVoidType::value;
};
/// Checks to see if the given object is an array handle. This check is

@ -45,7 +45,7 @@ namespace detail
template <typename ValueType>
struct VTKM_ALWAYS_EXPORT CompositeVectorSwizzleFunctor
{
static const vtkm::IdComponent NUM_COMPONENTS = vtkm::VecTraits<ValueType>::NUM_COMPONENTS;
static constexpr vtkm::IdComponent NUM_COMPONENTS = vtkm::VecTraits<ValueType>::NUM_COMPONENTS;
using ComponentMapType = vtkm::Vec<vtkm::IdComponent, NUM_COMPONENTS>;
// Caution! This is a reference.
@ -183,7 +183,7 @@ class VTKM_ALWAYS_EXPORT ArrayPortalCompositeVector
public:
using ValueType = typename PortalTypes::ResultType;
static const vtkm::IdComponent NUM_COMPONENTS = vtkm::VecTraits<ValueType>::NUM_COMPONENTS;
static constexpr vtkm::IdComponent NUM_COMPONENTS = vtkm::VecTraits<ValueType>::NUM_COMPONENTS;
// Used internally.
using ComponentMapType = vtkm::Vec<vtkm::IdComponent, NUM_COMPONENTS>;
@ -262,7 +262,7 @@ class Storage<typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::Va
vtkm::cont::internal::StorageTagCompositeVector<SignatureWithArrays>>
{
using FunctionInterfaceWithArrays = vtkm::internal::FunctionInterface<SignatureWithArrays>;
static const vtkm::IdComponent NUM_COMPONENTS = FunctionInterfaceWithArrays::ARITY;
static constexpr vtkm::IdComponent NUM_COMPONENTS = FunctionInterfaceWithArrays::ARITY;
using ComponentMapType = vtkm::Vec<vtkm::IdComponent, NUM_COMPONENTS>;
using FunctionInterfaceWithPortals =

@ -229,18 +229,13 @@ public:
/// Helper to determine if an ArrayHandle type is an ArrayHandleDiscard.
template <typename T>
struct IsArrayHandleDiscard;
struct IsArrayHandleDiscard : std::false_type
{
};
template <typename T>
struct IsArrayHandleDiscard<ArrayHandle<T, internal::StorageTagDiscard>> : std::true_type
{
static const bool Value = true;
};
template <typename T, typename U>
struct IsArrayHandleDiscard<ArrayHandle<T, U>> : std::false_type
{
static const bool Value = false;
};
} // end namespace cont

@ -40,7 +40,7 @@ public:
using Traits = vtkm::VecTraits<VectorType>;
using ValueType = typename Traits::ComponentType;
static const vtkm::IdComponent COMPONENT = Component;
static constexpr vtkm::IdComponent COMPONENT = Component;
VTKM_EXEC_CONT
ArrayPortalExtractComponent()
@ -90,7 +90,7 @@ private:
template <typename ArrayHandleType, vtkm::IdComponent Component>
class StorageTagExtractComponent
{
static const vtkm::IdComponent COMPONENT = Component;
static constexpr vtkm::IdComponent COMPONENT = Component;
};
namespace internal
@ -270,7 +270,7 @@ class ArrayHandleExtractComponent
StorageTagExtractComponent<ArrayHandleType, Component>>
{
public:
static const vtkm::IdComponent COMPONENT = Component;
static constexpr vtkm::IdComponent COMPONENT = Component;
VTKM_ARRAY_HANDLE_SUBCLASS(
ArrayHandleExtractComponent,

@ -36,7 +36,7 @@ template <typename _SourcePortalType, vtkm::IdComponent _NUM_COMPONENTS>
class VTKM_ALWAYS_EXPORT ArrayPortalGroupVec
{
public:
static const vtkm::IdComponent NUM_COMPONENTS = _NUM_COMPONENTS;
static constexpr vtkm::IdComponent NUM_COMPONENTS = _NUM_COMPONENTS;
using SourcePortalType = _SourcePortalType;
using ComponentType = typename std::remove_const<typename SourcePortalType::ValueType>::type;

@ -43,7 +43,7 @@ struct ComponentIsUnique;
template <vtkm::IdComponent TestValue, vtkm::IdComponent Head>
struct ComponentIsUnique<TestValue, Head>
{
const static bool IsUnique = TestValue != Head;
static const bool IsUnique = TestValue != Head;
};
// Recursive case:
@ -51,7 +51,7 @@ template <vtkm::IdComponent TestValue, vtkm::IdComponent Head, vtkm::IdComponent
struct ComponentIsUnique<TestValue, Head, Tail...>
{
using Next = ComponentIsUnique<TestValue, Tail...>;
const static bool IsUnique = TestValue != Head && Next::IsUnique;
static const bool IsUnique = TestValue != Head && Next::IsUnique;
};
// Validate the component map.
@ -63,7 +63,7 @@ struct ValidateComponentMap;
template <vtkm::IdComponent InputSize, vtkm::IdComponent Head>
struct ValidateComponentMap<InputSize, Head>
{
static const bool Valid = Head >= 0 && Head < InputSize;
static constexpr bool Valid = Head >= 0 && Head < InputSize;
};
// Recursive impl:
@ -71,8 +71,8 @@ template <vtkm::IdComponent InputSize, vtkm::IdComponent Head, vtkm::IdComponent
struct ValidateComponentMap<InputSize, Head, Tail...>
{
using Next = ValidateComponentMap<InputSize, Tail...>;
static const bool IsUnique = ComponentIsUnique<Head, Tail...>::IsUnique;
static const bool Valid = Head >= 0 && Head < InputSize && IsUnique && Next::Valid;
static constexpr bool IsUnique = ComponentIsUnique<Head, Tail...>::IsUnique;
static constexpr bool Valid = Head >= 0 && Head < InputSize && IsUnique && Next::Valid;
};
} // end namespace internal
@ -82,12 +82,13 @@ template <typename InputValueType, vtkm::IdComponent... ComponentMap>
struct ArrayHandleSwizzleTraits
{
/// The number of elements in the ComponentMap.
static const vtkm::IdComponent COUNT = static_cast<vtkm::IdComponent>(sizeof...(ComponentMap));
static constexpr vtkm::IdComponent COUNT =
static_cast<vtkm::IdComponent>(sizeof...(ComponentMap));
VTKM_STATIC_ASSERT_MSG(COUNT > 0, "Invalid ComponentMap: Cannot swizzle zero components.");
/// A std::array containing the ComponentMap for runtime querying.
using RuntimeComponentMapType = std::array<vtkm::IdComponent, COUNT>;
static VTKM_CONSTEXPR RuntimeComponentMapType GenerateRuntimeComponentMap()
static constexpr RuntimeComponentMapType GenerateRuntimeComponentMap()
{
return RuntimeComponentMapType{ { ComponentMap... } };
}
@ -114,7 +115,7 @@ struct ArrayHandleSwizzleTraits
/// If true, we use all components in the input vector. If false, we'll need
/// to make sure to preserve existing values on write.
static const bool ALL_COMPS_USED = InputTraits::NUM_COMPONENTS == COUNT;
static constexpr bool ALL_COMPS_USED = InputTraits::NUM_COMPONENTS == COUNT;
private:
template <vtkm::IdComponent OutputIndex, vtkm::IdComponent... Map>
@ -124,7 +125,7 @@ private:
template <vtkm::IdComponent OutputIndex, vtkm::IdComponent Head>
struct GetImpl<OutputIndex, Head>
{
VTKM_CONSTEXPR vtkm::IdComponent operator()() const { return OutputIndex == 0 ? Head : -1; }
constexpr vtkm::IdComponent operator()() const { return OutputIndex == 0 ? Head : -1; }
};
// Recursive case:
@ -133,17 +134,14 @@ private:
{
using Next = GetImpl<OutputIndex - 1, Tail...>;
VTKM_CONSTEXPR vtkm::IdComponent operator()() const
{
return OutputIndex == 0 ? Head : Next()();
}
constexpr vtkm::IdComponent operator()() const { return OutputIndex == 0 ? Head : Next()(); }
};
public:
/// Get the component from ComponentMap at the specified index as a
/// compile-time constant:
template <vtkm::IdComponent OutputIndex>
static VTKM_CONSTEXPR vtkm::IdComponent Get()
static constexpr vtkm::IdComponent Get()
{
return GetImpl<OutputIndex, ComponentMap...>()();
}
@ -156,7 +154,7 @@ private:
template <vtkm::IdComponent OutputIndex, vtkm::IdComponent Head>
struct SwizzleImpl<OutputIndex, Head>
{
static const vtkm::IdComponent InputIndex = Head;
static constexpr vtkm::IdComponent InputIndex = Head;
void operator()(const InputType& in, OutputType& out) const
{
@ -169,7 +167,7 @@ private:
struct SwizzleImpl<OutputIndex, Head, Tail...>
{
using Next = SwizzleImpl<OutputIndex + 1, Tail...>;
static const vtkm::IdComponent InputIndex = Head;
static constexpr vtkm::IdComponent InputIndex = Head;
void operator()(const InputType& in, OutputType& out) const
{
@ -194,7 +192,7 @@ private:
template <vtkm::IdComponent OutputIndex, vtkm::IdComponent Head>
struct UnSwizzleImpl<OutputIndex, Head>
{
static const vtkm::IdComponent InputIndex = Head;
static constexpr vtkm::IdComponent InputIndex = Head;
void operator()(const OutputType& out, InputType& in) const
{
@ -207,7 +205,7 @@ private:
struct UnSwizzleImpl<OutputIndex, Head, Tail...>
{
using Next = UnSwizzleImpl<OutputIndex + 1, Tail...>;
static const vtkm::IdComponent InputIndex = Head;
static constexpr vtkm::IdComponent InputIndex = Head;
void operator()(const OutputType& out, InputType& in) const
{

@ -183,15 +183,7 @@ template <typename ArrayHandleType,
typename InverseFunctorType = NullFunctorType>
struct VTKM_ALWAYS_EXPORT StorageTagTransform
{
#if defined(VTKM_MSVC) && (_MSC_VER == 1800) // workaround for VS2013
private:
using ArrayHandleValueType = typename ArrayHandleType::ValueType;
public:
using ValueType = decltype(FunctorType{}(ArrayHandleValueType{}));
#else
using ValueType = decltype(FunctorType{}(typename ArrayHandleType::ValueType{}));
#endif
};
template <typename ArrayHandleType, typename FunctorType>

@ -19,11 +19,13 @@
//============================================================================
#include <vtkm/cont/AssignerMultiBlock.h>
#if defined(VTKM_ENABLE_MPI)
#include <vtkm/cont/EnvironmentTracker.h>
#include <vtkm/cont/MultiBlock.h>
// clang-format off
#include <vtkm/cont/EnvironmentTracker.h>
VTKM_THIRDPARTY_PRE_INCLUDE
#include VTKM_DIY(diy/mpi.hpp)
VTKM_THIRDPARTY_POST_INCLUDE
// clang-format on
#include <algorithm> // std::lower_bound
@ -40,28 +42,30 @@ AssignerMultiBlock::AssignerMultiBlock(const vtkm::cont::MultiBlock& mb)
, IScanBlockCounts()
{
auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
const auto nblocks = mb.GetNumberOfBlocks();
const auto num_blocks = mb.GetNumberOfBlocks();
vtkm::Id iscan;
diy::mpi::scan(comm, nblocks, iscan, std::plus<vtkm::Id>());
diy::mpi::scan(comm, num_blocks, iscan, std::plus<vtkm::Id>());
diy::mpi::all_gather(comm, iscan, this->IScanBlockCounts);
this->set_nblocks(static_cast<int>(this->IScanBlockCounts.back()));
}
VTKM_CONT
void AssignerMultiBlock::local_gids(int rank, std::vector<int>& gids) const
void AssignerMultiBlock::local_gids(int my_rank, std::vector<int>& gids) const
{
if (rank == 0)
const size_t s_rank = static_cast<size_t>(my_rank);
if (my_rank == 0)
{
assert(this->IScanBlockCounts.size() > 0);
gids.resize(this->IScanBlockCounts[rank]);
gids.resize(static_cast<size_t>(this->IScanBlockCounts[s_rank]));
std::iota(gids.begin(), gids.end(), 0);
}
else if (rank > 0 && rank < static_cast<int>(this->IScanBlockCounts.size()))
else if (my_rank > 0 && s_rank < this->IScanBlockCounts.size())
{
gids.resize(this->IScanBlockCounts[rank] - this->IScanBlockCounts[rank - 1]);
std::iota(gids.begin(), gids.end(), this->IScanBlockCounts[rank - 1]);
gids.resize(
static_cast<size_t>(this->IScanBlockCounts[s_rank] - this->IScanBlockCounts[s_rank - 1]));
std::iota(gids.begin(), gids.end(), static_cast<int>(this->IScanBlockCounts[s_rank - 1]));
}
}
@ -76,5 +80,3 @@ int AssignerMultiBlock::rank(int gid) const
} // vtkm::cont
} // vtkm
#endif // defined(VTKM_ENABLE_MPI)

@ -20,21 +20,33 @@
#ifndef vtk_m_cont_AssignerMultiBlock_h
#define vtk_m_cont_AssignerMultiBlock_h
#include <vtkm/internal/Configure.h>
#include <vtkm/cont/vtkm_cont_export.h>
#if defined(VTKM_ENABLE_MPI)
#include <vtkm/cont/MultiBlock.h>
#include <vtkm/Types.h>
#include <vtkm/internal/ExportMacros.h>
#include <vtkm/thirdparty/diy/Configure.h>
#include <vector>
// clang-format off
#include <vtkm/thirdparty/diy/Configure.h>
VTKM_THIRDPARTY_PRE_INCLUDE
#include VTKM_DIY(diy/assigner.hpp)
VTKM_THIRDPARTY_POST_INCLUDE
// clang-format on
#ifdef VTKM_MSVC
#pragma warning(push)
// disable C4275: non-dll interface base class warnings
#pragma warning(disable : 4275)
#endif
namespace vtkm
{
namespace cont
{
class MultiBlock;
/// \brief Assigner for `MultiBlock` blocks.
///
/// `AssignerMultiBlock` is a `diy::Assigner` implementation that uses
@ -70,5 +82,8 @@ private:
}
}
#endif // defined(VTKM_ENABLE_MPI)
#ifdef VTKM_MSVC
#pragma warning(pop)
#endif
#endif

@ -54,6 +54,8 @@ set(headers
CellSetSingleType.h
CellSetStructured.h
CellSetPermutation.h
ColorTable.h
ColorTableSamples.h
CoordinateSystem.h
DataSet.h
DataSetBuilderExplicit.h
@ -94,6 +96,7 @@ set(template_sources
ArrayRangeCompute.hxx
CellSetExplicit.hxx
CellSetStructured.hxx
CoordinateSystem.hxx
StorageBasic.hxx
)
@ -108,6 +111,7 @@ set(sources
internal/SimplePolymorphicContainer.cxx
internal/ArrayManagerExecutionShareWithControl.cxx
internal/ArrayHandleBasicImpl.cxx
PresetColorTables.cxx
StorageBasic.cxx
)
@ -116,6 +120,7 @@ set(sources
set(device_sources
ArrayRangeCompute.cxx
CellSetExplicit.cxx
ColorTable.cxx
CoordinateSystem.cxx
DataSet.cxx
MultiBlock.cxx

880
vtkm/cont/ColorTable.cxx Normal file

@ -0,0 +1,880 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <algorithm>
#include <memory>
#include <vtkm/cont/ColorTable.h>
#include <vtkm/cont/ColorTable.hxx>
#include <vtkm/cont/ColorTablePrivate.hxx>
namespace vtkm
{
namespace cont
{
namespace detail
{
std::set<std::string> GetPresetNames();
bool loadColorTablePreset(std::string name, vtkm::cont::ColorTable& table);
}
//----------------------------------------------------------------------------
ColorTable::ColorTable(const std::string& name)
: Impl(std::make_shared<detail::ColorTableInternals>())
{
const bool loaded = this->LoadPreset(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
//when the no parameter constructor is called
this->SetColorSpace(ColorSpace::RGB);
}
this->AddSegmentAlpha(this->Impl->TableRange.Min, 1.0f, this->Impl->TableRange.Max, 1.0f);
}
//----------------------------------------------------------------------------
ColorTable::ColorTable(ColorSpace space)
: Impl(std::make_shared<detail::ColorTableInternals>())
{
this->SetColorSpace(space);
}
//----------------------------------------------------------------------------
ColorTable::ColorTable(const vtkm::Range& range,
const vtkm::Vec<float, 3>& rgb1,
const vtkm::Vec<float, 3>& rgb2,
ColorSpace space)
: Impl(std::make_shared<detail::ColorTableInternals>())
{
this->AddSegment(range.Min, rgb1, range.Max, rgb2);
this->AddSegmentAlpha(range.Min, 1.0f, range.Max, 1.0f);
this->SetColorSpace(space);
}
//----------------------------------------------------------------------------
ColorTable::ColorTable(const vtkm::Range& range,
const vtkm::Vec<float, 4>& rgba1,
const vtkm::Vec<float, 4>& rgba2,
ColorSpace space)
: Impl(std::make_shared<detail::ColorTableInternals>())
{
vtkm::Vec<float, 3> rgb1(rgba1[0], rgba1[1], rgba1[2]);
vtkm::Vec<float, 3> 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);
}
//----------------------------------------------------------------------------
ColorTable::~ColorTable()
{
}
//----------------------------------------------------------------------------
std::set<std::string> ColorTable::GetPresets() const
{
return detail::GetPresetNames();
}
//----------------------------------------------------------------------------
bool ColorTable::LoadPreset(const std::string& name)
{
return detail::loadColorTablePreset(name, *this);
}
//----------------------------------------------------------------------------
ColorTable ColorTable::MakeDeepCopy()
{
ColorTable dcopy(this->Impl->CSpace);
dcopy.Impl->TableRange = this->Impl->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.Impl->HostSideCache->UseClamping = this->Impl->HostSideCache->UseClamping;
dcopy.Impl->ColorNodePos = this->Impl->ColorNodePos;
dcopy.Impl->ColorRGB = this->Impl->ColorRGB;
dcopy.Impl->OpacityNodePos = this->Impl->OpacityNodePos;
dcopy.Impl->OpacityAlpha = this->Impl->OpacityAlpha;
dcopy.Impl->OpacityMidSharp = this->Impl->OpacityMidSharp;
return dcopy;
}
//----------------------------------------------------------------------------
ColorSpace ColorTable::GetColorSpace() const
{
return this->Impl->CSpace;
}
//----------------------------------------------------------------------------
void ColorTable::SetColorSpace(ColorSpace space)
{
if (this->Impl->CSpace != space || this->Impl->HostSideCache == nullptr)
{
this->Impl->CSpace = space;
//Remove any existing host and execution data
delete this->Impl->HostSideCache;
delete this->Impl->ExecHandle;
using HandleType = vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase>;
switch (space)
{
case vtkm::cont::ColorSpace::RGB:
{
auto* hostPortal = new vtkm::exec::ColorTableRGB();
this->Impl->ExecHandle = new HandleType(hostPortal, false);
this->Impl->HostSideCache = hostPortal;
break;
}
case vtkm::cont::ColorSpace::HSV:
{
auto* hostPortal = new vtkm::exec::ColorTableHSV();
this->Impl->ExecHandle = new HandleType(hostPortal, false);
this->Impl->HostSideCache = hostPortal;
break;
}
case vtkm::cont::ColorSpace::HSV_WRAP:
{
auto* hostPortal = new vtkm::exec::ColorTableHSVWrap();
this->Impl->ExecHandle = new HandleType(hostPortal, false);
this->Impl->HostSideCache = hostPortal;
break;
}
case vtkm::cont::ColorSpace::LAB:
{
auto* hostPortal = new vtkm::exec::ColorTableLab();
this->Impl->ExecHandle = new HandleType(hostPortal, false);
this->Impl->HostSideCache = hostPortal;
break;
}
case vtkm::cont::ColorSpace::DIVERGING:
{
auto* hostPortal = new vtkm::exec::ColorTableDiverging();
this->Impl->ExecHandle = new HandleType(hostPortal, false);
this->Impl->HostSideCache = hostPortal;
break;
}
default:
throw vtkm::cont::ErrorBadType("unkown vtkm::cont::ColorType requested");
}
}
}
//----------------------------------------------------------------------------
void ColorTable::SetClamping(bool state)
{
this->Impl->HostSideCache->UseClamping = state;
this->Impl->HostSideCache->Modified();
}
//----------------------------------------------------------------------------
bool ColorTable::GetClamping() const
{
return this->Impl->HostSideCache->UseClamping;
}
//----------------------------------------------------------------------------
void ColorTable::SetBelowRangeColor(const vtkm::Vec<float, 3>& c)
{
this->Impl->HostSideCache->BelowRangeColor = c;
this->Impl->HostSideCache->Modified();
}
//----------------------------------------------------------------------------
const vtkm::Vec<float, 3>& ColorTable::GetBelowRangeColor() const
{
return this->Impl->HostSideCache->BelowRangeColor;
}
//----------------------------------------------------------------------------
void ColorTable::SetAboveRangeColor(const vtkm::Vec<float, 3>& c)
{
this->Impl->HostSideCache->AboveRangeColor = c;
this->Impl->HostSideCache->Modified();
}
//----------------------------------------------------------------------------
const vtkm::Vec<float, 3>& ColorTable::GetAboveRangeColor() const
{
return this->Impl->HostSideCache->AboveRangeColor;
}
//----------------------------------------------------------------------------
void ColorTable::SetNaNColor(const vtkm::Vec<float, 3>& c)
{
this->Impl->HostSideCache->NaNColor = c;
this->Impl->HostSideCache->Modified();
}
//----------------------------------------------------------------------------
const vtkm::Vec<float, 3>& ColorTable::GetNaNColor() const
{
return this->Impl->HostSideCache->NaNColor;
}
//----------------------------------------------------------------------------
void ColorTable::Clear()
{
this->ClearColors();
this->ClearAlpha();
}
//---------------------------------------------------------------------------
void ColorTable::ClearColors()
{
this->Impl->ColorNodePos.clear();
this->Impl->ColorRGB.clear();
this->Impl->ColorArraysChanged = true;
}
//---------------------------------------------------------------------------
void ColorTable::ClearAlpha()
{
this->Impl->OpacityNodePos.clear();
this->Impl->OpacityAlpha.clear();
this->Impl->OpacityMidSharp.clear();
this->Impl->OpacityArraysChanged = true;
}
//---------------------------------------------------------------------------
void ColorTable::ReverseColors()
{
std::reverse(this->Impl->ColorRGB.begin(), this->Impl->ColorRGB.end());
this->Impl->ColorArraysChanged = true;
}
//---------------------------------------------------------------------------
void ColorTable::ReverseAlpha()
{
std::reverse(this->Impl->OpacityAlpha.begin(), this->Impl->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;
}
//---------------------------------------------------------------------------
const vtkm::Range& ColorTable::GetRange() const
{
return this->Impl->TableRange;
}
//---------------------------------------------------------------------------
void ColorTable::RescaleToRange(const vtkm::Range& r)
{
if (r == this->GetRange())
{
return;
}
//make sure range has space.
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();
VTKM_ASSERT(oldScale > 0);
VTKM_ASSERT(newScale > 0);
for (auto i = this->Impl->ColorNodePos.begin(); i != this->Impl->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)
{
const auto t = (*i - minv) / oldScale;
*i = (t * newScale) + newRange.Min;
}
this->Impl->ColorArraysChanged = true;
this->Impl->OpacityArraysChanged = true;
this->Impl->TableRange = newRange;
}
//---------------------------------------------------------------------------
vtkm::Int32 ColorTable::AddPoint(double x, const vtkm::Vec<float, 3>& rgb)
{
if (outside_range(rgb))
{
return -1;
}
std::size_t index = 0;
if (this->Impl->ColorNodePos.size() == 0 || this->Impl->ColorNodePos.back() < x)
{
this->Impl->ColorNodePos.emplace_back(x);
this->Impl->ColorRGB.emplace_back(rgb);
index = this->Impl->ColorNodePos.size();
}
else
{
auto begin = this->Impl->ColorNodePos.begin();
auto pos = std::lower_bound(begin, this->Impl->ColorNodePos.end(), x);
index = static_cast<std::size_t>(std::distance(begin, pos));
if (*pos == x)
{
this->Impl->ColorRGB[index] = rgb;
}
else
{
this->Impl->ColorNodePos.emplace(pos, x);
this->Impl->ColorRGB.emplace(this->Impl->ColorRGB.begin() + std::distance(begin, pos), rgb);
}
}
this->Impl->TableRange.Include(x); //update range to include x
this->Impl->ColorArraysChanged = true;
return static_cast<vtkm::Int32>(index);
}
//---------------------------------------------------------------------------
vtkm::Int32 ColorTable::AddPointHSV(double x, const vtkm::Vec<float, 3>& hsv)
{
return this->AddPoint(x, hsvTorgb(hsv));
}
//---------------------------------------------------------------------------
vtkm::Int32 ColorTable::AddSegment(double x1,
const vtkm::Vec<float, 3>& rgb1,
double x2,
const vtkm::Vec<float, 3>& rgb2)
{
if (outside_range(rgb1, rgb2))
{
return -1;
}
if (this->Impl->ColorNodePos.size() > 0)
{
//Todo:
// - This could be optimized so we do 2 less lower_bound calls when
// the table already exists
//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 rgbBegin = this->Impl->ColorRGB.begin();
auto nodeStart = std::lower_bound(nodeBegin, nodeEnd, x1);
auto nodeStop = std::lower_bound(nodeBegin, nodeEnd, x2);
auto rgbStart = rgbBegin + std::distance(nodeBegin, nodeStart);
auto rgbStop = rgbBegin + std::distance(nodeBegin, nodeStop);
//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);
}
vtkm::Int32 pos = this->AddPoint(x1, rgb1);
this->AddPoint(x2, rgb2);
return pos;
}
//---------------------------------------------------------------------------
vtkm::Int32 ColorTable::AddSegmentHSV(double x1,
const vtkm::Vec<float, 3>& hsv1,
double x2,
const vtkm::Vec<float, 3>& hsv2)
{
return this->AddSegment(x1, hsvTorgb(hsv1), x2, hsvTorgb(hsv2));
}
//---------------------------------------------------------------------------
bool ColorTable::GetPoint(vtkm::Int32 index, vtkm::Vec<double, 4>& data) const
{
std::size_t i = static_cast<std::size_t>(index);
const std::size_t size = this->Impl->ColorNodePos.size();
if (index < 0 || i >= size)
{
return false;
}
const auto& pos = this->Impl->ColorNodePos[i];
const auto& rgb = this->Impl->ColorRGB[i];
data[0] = pos;
data[1] = rgb[0];
data[2] = rgb[1];
data[3] = rgb[2];
return true;
}
//---------------------------------------------------------------------------
vtkm::Int32 ColorTable::UpdatePoint(vtkm::Int32 index, const vtkm::Vec<double, 4>& data)
{
//skip data[0] as we don't care about position
if (outside_range(data[1], data[2], data[3]))
{
return -1;
}
std::size_t i = static_cast<std::size_t>(index);
const std::size_t size = this->Impl->ColorNodePos.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->ColorNodePos.begin() + index;
auto newPos =
std::lower_bound(this->Impl->ColorNodePos.begin(), this->Impl->ColorNodePos.end(), data[0]);
if (oldPos == newPos)
{ //node's relative location hasn't changed
this->Impl->ColorArraysChanged = true;
auto& rgb = this->Impl->ColorRGB[i];
*newPos = data[0];
rgb[0] = static_cast<float>(data[1]);
rgb[1] = static_cast<float>(data[2]);
rgb[2] = static_cast<float>(data[3]);
return index;
}
else
{ //remove the point, and add the new values as the relative location is different
this->RemovePoint(index);
vtkm::Vec<float, 3> newrgb(
static_cast<float>(data[1]), static_cast<float>(data[2]), static_cast<float>(data[3]));
return this->AddPoint(data[0], newrgb);
}
}
//---------------------------------------------------------------------------
bool ColorTable::RemovePoint(double x)
{
auto begin = this->Impl->ColorNodePos.begin();
auto pos = std::lower_bound(begin, this->Impl->ColorNodePos.end(), x);
return this->RemovePoint(static_cast<vtkm::Int32>(std::distance(begin, pos)));
}
//---------------------------------------------------------------------------
bool ColorTable::RemovePoint(vtkm::Int32 index)
{
std::size_t i = static_cast<std::size_t>(index);
const std::size_t size = this->Impl->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();
return true;
}
//---------------------------------------------------------------------------
vtkm::Int32 ColorTable::GetNumberOfPoints() const
{
return static_cast<vtkm::Int32>(this->Impl->ColorNodePos.size());
}
//---------------------------------------------------------------------------
vtkm::Int32 ColorTable::AddPointAlpha(double x, float alpha, float midpoint, float sharpness)
{
if (outside_range(alpha, midpoint, sharpness))
{
return -1;
}
const vtkm::Vec<float, 2> midsharp(midpoint, sharpness);
std::size_t index = 0;
if (this->Impl->OpacityNodePos.size() == 0 || this->Impl->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();
}
else
{
auto begin = this->Impl->OpacityNodePos.begin();
auto pos = std::lower_bound(begin, this->Impl->OpacityNodePos.end(), x);
index = static_cast<std::size_t>(std::distance(begin, pos));
if (*pos == x)
{
this->Impl->OpacityAlpha[index] = alpha;
this->Impl->OpacityMidSharp[index] = midsharp;
}
else
{
this->Impl->OpacityNodePos.emplace(pos, x);
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->OpacityArraysChanged = true;
this->Impl->TableRange.Include(x); //update range to include x
return static_cast<vtkm::Int32>(index);
}
//---------------------------------------------------------------------------
vtkm::Int32 ColorTable::AddSegmentAlpha(double x1,
float alpha1,
double x2,
float alpha2,
const vtkm::Vec<float, 2>& mid_sharp1,
const vtkm::Vec<float, 2>& mid_sharp2)
{
if (outside_range(alpha1, alpha2, mid_sharp1, mid_sharp2))
{
return -1;
}
if (this->Impl->OpacityNodePos.size() > 0)
{
//Todo:
// - This could be optimized so we do 2 less lower_bound calls when
// the table already exists
//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 alphaBegin = this->Impl->OpacityAlpha.begin();
auto midBegin = this->Impl->OpacityMidSharp.begin();
auto nodeStart = std::lower_bound(nodeBegin, nodeEnd, x1);
auto nodeStop = std::lower_bound(nodeBegin, nodeEnd, x2);
auto alphaStart = alphaBegin + std::distance(nodeBegin, nodeStart);
auto alphaStop = alphaBegin + std::distance(nodeBegin, nodeStop);
auto midStart = midBegin + std::distance(nodeBegin, nodeStart);
auto midStop = midBegin + std::distance(nodeBegin, nodeStop);
//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);
}
vtkm::Int32 pos = this->AddPointAlpha(x1, alpha1, mid_sharp1[0], mid_sharp1[1]);
this->AddPointAlpha(x2, alpha2, mid_sharp2[0], mid_sharp2[1]);
return pos;
}
//---------------------------------------------------------------------------
bool ColorTable::GetPointAlpha(vtkm::Int32 index, vtkm::Vec<double, 4>& data) const
{
std::size_t i = static_cast<std::size_t>(index);
const std::size_t size = this->Impl->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];
data[0] = pos;
data[1] = alpha;
data[2] = midsharp[0];
data[3] = midsharp[1];
return true;
}
//---------------------------------------------------------------------------
vtkm::Int32 ColorTable::UpdatePointAlpha(vtkm::Int32 index, const vtkm::Vec<double, 4>& data)
{
//skip data[0] as we don't care about position
if (outside_range(data[1], data[2], data[3]))
{
return -1;
}
std::size_t i = static_cast<std::size_t>(index);
const std::size_t size = this->Impl->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]);
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];
*newPos = data[0];
alpha = static_cast<float>(data[1]);
midsharp[0] = static_cast<float>(data[2]);
midsharp[1] = static_cast<float>(data[3]);
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<float>(data[1]),
static_cast<float>(data[2]),
static_cast<float>(data[3]));
}
}
//---------------------------------------------------------------------------
bool ColorTable::RemovePointAlpha(double x)
{
auto begin = this->Impl->OpacityNodePos.begin();
auto pos = std::lower_bound(begin, this->Impl->OpacityNodePos.end(), x);
return this->RemovePointAlpha(static_cast<vtkm::Int32>(std::distance(begin, pos)));
}
//---------------------------------------------------------------------------
bool ColorTable::RemovePointAlpha(vtkm::Int32 index)
{
std::size_t i = static_cast<std::size_t>(index);
const std::size_t size = this->Impl->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();
return true;
}
//---------------------------------------------------------------------------
vtkm::Int32 ColorTable::GetNumberOfPointsAlpha() const
{
return static_cast<vtkm::Int32>(this->Impl->OpacityNodePos.size());
}
//---------------------------------------------------------------------------
bool ColorTable::FillColorTableFromDataPointer(vtkm::Int32 n, const double* ptr)
{
if (n <= 0 || ptr == nullptr)
{
return false;
}
this->ClearColors();
std::size_t size = static_cast<std::size_t>(n / 4);
this->Impl->ColorNodePos.reserve(size);
this->Impl->ColorRGB.reserve(size);
for (std::size_t i = 0; i < size; ++i)
{ //allows us to support unsorted arrays
vtkm::Vec<float, 3> rgb(
static_cast<float>(ptr[1]), static_cast<float>(ptr[2]), static_cast<float>(ptr[3]));
this->AddPoint(ptr[0], rgb);
ptr += 4;
}
this->Impl->ColorArraysChanged = true;
return true;
}
//---------------------------------------------------------------------------
bool ColorTable::FillColorTableFromDataPointer(vtkm::Int32 n, const float* ptr)
{
if (n <= 0 || ptr == nullptr)
{
return false;
}
this->ClearColors();
std::size_t size = static_cast<std::size_t>(n / 4);
this->Impl->ColorNodePos.reserve(size);
this->Impl->ColorRGB.reserve(size);
for (std::size_t i = 0; i < size; ++i)
{ //allows us to support unsorted arrays
vtkm::Vec<float, 3> rgb(ptr[1], ptr[2], ptr[3]);
this->AddPoint(ptr[0], rgb);
ptr += 4;
}
this->Impl->ColorArraysChanged = true;
return true;
}
//---------------------------------------------------------------------------
bool ColorTable::FillOpacityTableFromDataPointer(vtkm::Int32 n, const double* ptr)
{
if (n <= 0 || ptr == nullptr)
{
return false;
}
this->ClearAlpha();
std::size_t size = static_cast<std::size_t>(n / 2);
this->Impl->OpacityNodePos.reserve(size);
this->Impl->OpacityAlpha.reserve(size);
this->Impl->OpacityMidSharp.reserve(size);
for (std::size_t i = 0; i < size; ++i)
{ //allows us to support unsorted arrays
this->AddPointAlpha(
ptr[0], static_cast<float>(ptr[1]), static_cast<float>(ptr[2]), static_cast<float>(ptr[3]));
ptr += 4;
}
this->Impl->OpacityArraysChanged = true;
return true;
}
//---------------------------------------------------------------------------
bool ColorTable::FillOpacityTableFromDataPointer(vtkm::Int32 n, const float* ptr)
{
if (n <= 0 || ptr == nullptr)
{
return false;
}
this->ClearAlpha();
std::size_t size = static_cast<std::size_t>(n / 2);
this->Impl->OpacityNodePos.reserve(size);
this->Impl->OpacityAlpha.reserve(size);
this->Impl->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;
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
{
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::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& colors,
double tolerance) const
{
if (numSamples <= 1)
{
return false;
}
return sampleColorTable(this, numSamples, colors, tolerance, false);
}
//---------------------------------------------------------------------------
bool ColorTable::Sample(vtkm::Int32 numSamples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& colors,
double tolerance) const
{
if (numSamples <= 1)
{
return false;
}
return sampleColorTable(this, numSamples, colors, tolerance, false);
}
//---------------------------------------------------------------------------
vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase>* ColorTable::GetHandleForExecution()
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);
this->Impl->ColorRGBHandle = vtkm::cont::make_ArrayHandle(this->Impl->ColorRGB);
}
if (this->Impl->OpacityArraysChanged)
{
this->Impl->OpacityPosHandle = vtkm::cont::make_ArrayHandle(this->Impl->OpacityNodePos);
this->Impl->OpacityAlphaHandle = vtkm::cont::make_ArrayHandle(this->Impl->OpacityAlpha);
this->Impl->OpacityMidSharpHandle = vtkm::cont::make_ArrayHandle(this->Impl->OpacityMidSharp);
}
if (this->Impl->ColorArraysChanged || this->Impl->OpacityArraysChanged)
{
vtkm::cont::TryExecute(
detail::transfer_color_table_to_device{}, this->Impl->HostSideCache, this->Impl.get());
this->Impl->HostSideCache->Modified();
}
this->Impl->ColorArraysChanged = false;
this->Impl->OpacityArraysChanged = false;
return this->Impl->ExecHandle;
}
/*
#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
*/
}
} //namespace vtkm::cont

644
vtkm/cont/ColorTable.h Normal file

@ -0,0 +1,644 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_ColorTable_h
#define vtk_m_cont_ColorTable_h
#include <vtkm/Range.h>
#include <vtkm/Types.h>
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ColorTableSamples.h>
#include <vtkm/cont/VirtualObjectHandle.h>
#include <set>
namespace vtkm
{
namespace exec
{
//forward declare exec objects
class ColorTableBase;
}
namespace cont
{
namespace detail
{
struct ColorTableInternals;
}
enum struct ColorSpace
{
RGB,
HSV,
HSV_WRAP,
LAB,
DIVERGING
};
/// \brief Color Table for coloring arbitrary fields
///
///
/// 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
/// according to a sharpness parameter).
///
/// For colors interpolation is handled using a piecewise linear function.
///
/// For opacity we define a piecewise function mapping. This mapping allows the addition
/// of control points, and allows the user to control the function between
/// the control points. A piecewise hermite curve is used between control
/// points, based on the sharpness and midpoint parameters. A sharpness of
/// 0 yields a piecewise linear function and a sharpness of 1 yields a
/// piecewise constant function. The midpoint is the normalized distance
/// between control points at which the curve reaches the median Y value.
/// The midpoint and sharpness values specified when adding a node are used
/// to control the transition to the next node with the last node's values being
/// ignored.
///
/// When adding opacity nodes without an explicit midpoint and sharpness we
/// 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
/// Currently the valid ColorSpaces are:
/// - RGB
/// - HSV
/// - HSV_WRAP
/// - LAB
/// - Diverging
///
/// In HSV_WRAP 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,
/// 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
/// mode where colors will pass through white when interpolating between two
/// saturated colors.
///
/// To map an vtkm::cont::ArrayHandle through the color and opacity transfer
/// functions and into a RGB or RGBA array you will need to use
/// vtkm::worklet::ColorTransferFunction. ColorTransferFunction has
/// controls if you want to modify which ColorSpace (RGB, HSV, LAB, Diverging) you want to
/// interpolate through.
///
class VTKM_CONT_EXPORT ColorTable
{
std::shared_ptr<detail::ColorTableInternals> Impl;
public:
/// Construct a color table from a preset color table
///
/// Constructs a color table from a given preset, which might include a NaN color.
/// The alpha table will have 2 entries of alpha = 1.0 with linear interpolation
///
/// Note: Names are case insensitive
/// Currently supports the following color tables:
///
/// "Cool to Warm"
/// "Black-Body Radiation"
/// "Samsel Fire" [ known previously as "Black, Orange and White"]
/// "Inferno"
/// "Linear YGB"
/// "Cold and Hot"
/// "Rainbow Desaturated"
/// "Cool to Warm (Extended)"
/// "X Ray"
/// "Black, Blue and White"
/// "Virdis"
/// "Linear Green"
/// "Jet"
/// "Rainbow"
///
ColorTable(const std::string& name);
/// Construct a color table with a zero positions, and an invalid range
///
/// Note: The color table will have 0 entries
/// Note: The alpha table will have 0 entries
ColorTable(ColorSpace space = ColorSpace::RGB);
/// 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::RGB);
/// Construct a color table with 2 positions
//
/// Note: The alpha table will have 2 entries of alpha = 1.0 with linear
/// interpolation
ColorTable(const vtkm::Range& range,
const vtkm::Vec<float, 3>& rgb1,
const vtkm::Vec<float, 3>& rgb2,
ColorSpace space = ColorSpace::RGB);
/// Construct color and alpha and table with 2 positions
///
/// Note: The alpha table will use linear interpolation
ColorTable(const vtkm::Range& range,
const vtkm::Vec<float, 4>& rgba1,
const vtkm::Vec<float, 4>& rgba2,
ColorSpace space = ColorSpace::RGB);
~ColorTable();
/// Returns the name of all preset color tables
///
std::set<std::string> GetPresets() const;
/// Load a preset color table
///
/// Removes all existing all values in both color and alpha tables,
/// and will reset the NaN Color if the color table has that information.
/// Will not modify clamping, below, and above range state.
///
/// Note: Names are case insensitive
///
/// Currently supports the following color tables:
/// "Cool to Warm"
/// "Black-Body Radiation"
/// "Samsel Fire" [ known previously as "Black, Orange and White"]
/// "Inferno"
/// "Linear YGB"
/// "Cold and Hot"
/// "Rainbow Desaturated"
/// "Cool to Warm (Extended)"
/// "X Ray"
/// "Black, Blue and White"
/// "Virdis"
/// "Linear Green"
/// "Jet"
/// "Rainbow"
bool LoadPreset(const std::string& name);
/// Make a deep copy of the current color table
///
/// The ColorTable is implemented so that all stack based copies are 'shallow'
/// copies. This means that they all alter the same internal instance. But
/// sometimes you need to make an actual fully independent copy.
ColorTable MakeDeepCopy();
///
ColorSpace GetColorSpace() const;
void SetColorSpace(ColorSpace space);
/// If clamping is disabled values that lay out side
/// the color table range are colored based on Below
/// and Above settings.
///
/// By default clamping is enabled
void SetClampingOn() { this->SetClamping(true); }
void SetClampingOff() { this->SetClamping(false); }
void SetClamping(bool state);
bool GetClamping() const;
/// Color to use when clamping is disabled for any value
/// that is below the given range
///
/// Default value is {0,0,0}
void SetBelowRangeColor(const vtkm::Vec<float, 3>& c);
const vtkm::Vec<float, 3>& GetBelowRangeColor() const;
/// Color to use when clamping is disabled for any value
/// that is above the given range
///
/// Default value is {0,0,0}
void SetAboveRangeColor(const vtkm::Vec<float, 3>& c);
const vtkm::Vec<float, 3>& GetAboveRangeColor() const;
///
void SetNaNColor(const vtkm::Vec<float, 3>& c);
const vtkm::Vec<float, 3>& GetNaNColor() const;
/// Remove all existing all values in both color and alpha tables
/// doesn't remove the clamping, below, and above range state or colors
void Clear();
/// Remove only color table values
void ClearColors();
/// Remove only alpha table values
void ClearAlpha();
/// Reverse the rgb values inside the color table
void ReverseColors();
/// Reverse the alpha, mid, and sharp values inside the opacity table.
///
/// Note: To keep the shape correct the mid and sharp values of the last
/// node are not included in the reversal
void ReverseAlpha();
/// Returns min and max position of all function points
const vtkm::Range& GetRange() const;
/// Rescale the color and opacity transfer functions to match the
/// input range.
void RescaleToRange(const vtkm::Range& range);
// Functions for Colors
/// Adds a point to the color function. If the point already exists, it
/// will be updated to the new value.
///
/// Note: rgb values need to be between 0 and 1.0 (inclusive).
/// Return the index of the point (0 based), or -1 osn error.
vtkm::Int32 AddPoint(double x, const vtkm::Vec<float, 3>& rgb);
/// Adds a point to the color function. If the point already exists, it
/// will be updated to the new value.
///
/// Note: hsv values need to be between 0 and 1.0 (inclusive).
/// Return the index of the point (0 based), or -1 on error.
vtkm::Int32 AddPointHSV(double x, const vtkm::Vec<float, 3>& hsv);
/// Add a line segment to the color function. All points which lay between x1 and x2
/// (inclusive) are removed from the function.
///
/// Note: rgb1, and rgb2 values need to be between 0 and 1.0 (inclusive).
/// Return the index of the point x1 (0 based), or -1 on error.
vtkm::Int32 AddSegment(double x1,
const vtkm::Vec<float, 3>& rgb1,
double x2,
const vtkm::Vec<float, 3>& rgb2);
/// Add a line segment to the color function. All points which lay between x1 and x2
/// (inclusive) are removed from the function.
///
/// Note: hsv1, and hsv2 values need to be between 0 and 1.0 (inclusive)
/// Return the index of the point x1 (0 based), or -1 on error
vtkm::Int32 AddSegmentHSV(double x1,
const vtkm::Vec<float, 3>& hsv1,
double x2,
const vtkm::Vec<float, 3>& hsv2);
/// Get the location, and rgb information for an existing point in the opacity function.
///
/// Note: components 1-3 are rgb and will have values between 0 and 1.0 (inclusive)
/// Return the index of the point (0 based), or -1 on error.
bool GetPoint(vtkm::Int32 index, vtkm::Vec<double, 4>&) const;
/// 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
/// the function and re-inserted in the proper sorted location.
///
/// Note: components 1-3 are rgb and must have values between 0 and 1.0 (inclusive).
/// Return the new index of the updated point (0 based), or -1 on error.
vtkm::Int32 UpdatePoint(vtkm::Int32 index, const vtkm::Vec<double, 4>&);
/// 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);
/// Remove the Color function point n
///
/// Return true if n >= 0 && n < GetNumberOfPoints
bool RemovePoint(vtkm::Int32 index);
/// Returns the number of points in the color function
vtkm::Int32 GetNumberOfPoints() const;
// Functions for Opacity
/// Adds a point to the opacity function. If the point already exists, it
/// will be updated to the new value. Uses a midpoint of 0.5 (halfway between the control points)
/// and sharpness of 0.0 (linear).
///
/// 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); }
/// 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);
/// 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
/// 0.5 (halfway between the control points) and sharpness of 0.0 (linear).
///
/// 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::Vec<float, 2> mid_sharp(0.5f, 0.0f);
return AddSegmentAlpha(x1, alpha1, x2, alpha2, mid_sharp, mid_sharp);
}
/// Add a line segment to the opacity function. All points which lay between x1 and x2
/// (inclusive) are removed from the function.
///
/// Note: alpha, midpoint, and sharpness values need to be between 0 and 1.0 (inclusive)
/// Return the index of the point x1 (0 based), or -1 on error
vtkm::Int32 AddSegmentAlpha(double x1,
float alpha1,
double x2,
float alpha2,
const vtkm::Vec<float, 2>& mid_sharp1,
const vtkm::Vec<float, 2>& mid_sharp2);
/// Get the location, alpha, midpoint and sharpness information for an existing
/// point in the opacity function.
///
/// Note: alpha, midpoint, and sharpness values all will be between 0 and 1.0 (inclusive)
/// Return the index of the point (0 based), or -1 on error.
bool GetPointAlpha(vtkm::Int32 index, vtkm::Vec<double, 4>&) const;
/// Update the location, alpha, midpoint and sharpness information for an existing
/// point in the opacity function.
/// If the location value for the index is modified the point is removed from
/// the function and re-inserted in the proper sorted location
///
/// Note: alpha, midpoint, and sharpness values need to be between 0 and 1.0 (inclusive)
/// Return the new index of the updated point (0 based), or -1 on error.
vtkm::Int32 UpdatePointAlpha(vtkm::Int32 index, const vtkm::Vec<double, 4>&);
/// 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);
/// Remove the Opacity function point n
///
/// Return true if n >= 0 && n < GetNumberOfPointsAlpha
bool RemovePointAlpha(vtkm::Int32 index);
/// Returns the number of points in the alpha function
vtkm::Int32 GetNumberOfPointsAlpha() const;
/// Fill the Color table from a double pointer
///
/// The double 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.
///
/// Note: n represents the length of the array, so ( n/4 == number of control points )
///
/// 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);
/// Fill the Color table from a float pointer
///
/// The double 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.
///
/// Note: n represents the length of the array, so ( n/4 == number of control points )
///
/// 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);
/// Fill the Opacity table from a double pointer
///
/// The double pointer is required to have the layout out of [X1, A1,
/// X2, A2, ..., Xn, An] where n is the number of nodes. The midpoint
/// of each node will be set to 0.5 and the sharpness to 0.0 (linear).
/// This will remove any existing opacity control points.
///
/// Note: n represents the length of the array, so ( n/2 == number of control points )
///
/// 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 FillOpacityTableFromDataPointer(vtkm::Int32 n, const double* ptr);
/// Fill the Opacity table from a float pointer
///
/// The double pointer is required to have the layout out of [X1, A1,
/// X2, A2, ..., Xn, An] where n is the number of nodes. The midpoint
/// of each node will be set to 0.5 and the sharpness to 0.0 (linear).
/// This will remove any existing opacity control points.
///
/// Note: n represents the length of the array, so ( n/2 == number of control points )
///
/// 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 FillOpacityTableFromDataPointer(vtkm::Int32 n, const float* ptr);
/// \brief Sample each value through an intermediate lookup/sample table to generate RGBA colors
///
/// Each value in \c values is binned based on its value in relationship to the range
/// of the color table and will use the color value at that bin from the \c samples.
/// To generate the lookup table use \c Sample .
///
/// Here is a simple example.
/// \code{.cpp}
///
/// vtkm::cont::ColorTableSamplesRGBA samples;
/// vtkm::cont::ColorTable table("black-body radiation");
/// table.Sample(256, samples);
/// vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>> colors;
/// table.Map(input, samples, colors);
///
/// \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;
/// \brief Sample each value through an intermediate lookup/sample table to generate RGB colors
///
/// Each value in \c values is binned based on its value in relationship to the range
/// of the color table and will use the color value at that bin from the \c samples.
/// To generate the lookup table use \c Sample .
///
/// Here is a simple example.
/// \code{.cpp}
///
/// vtkm::cont::ColorTableSamplesRGB samples;
/// vtkm::cont::ColorTable table("black-body radiation");
/// table.Sample(256, samples);
/// vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>> colors;
/// table.Map(input, samples, colors);
///
/// \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;
/// \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;
/// \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;
/// \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;
/// \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;
/// \brief Interpolate each value through the color table to generate RGBA colors
///
/// Each value in \c values will be sampled through the entire color table
/// to determine a color.
///
/// 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;
/// \brief Interpolate each value through the color table to generate RGB colors
///
/// Each value in \c values will be sampled through the entire color table
/// to determine a color.
///
/// 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;
/// \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;
/// \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;
/// \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;
/// \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;
/// \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 withing float space and the following are within a tolerance:
///
/// - (max-min) / numSamples
/// - ((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;
/// \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 withing float space and the following are within a tolerance:
///
/// - (max-min) / numSamples
/// - ((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;
/// \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 withing float space and the following are within a tolerance:
///
/// - (max-min) / numSamples
/// - ((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;
/// \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 withing float space and the following are within a tolerance:
///
/// - (max-min) / numSamples
/// - ((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;
/// \brief returns a virtual object handle of the exec color table
///
/// This object is only valid as long as the ColorTable is unmodified
vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase>* GetHandleForExecution() const;
//Todo:
//
// 1. Implement Preset Methods
};
}
} //namespace vtkm::cont
#endif //vtk_m_cont_ColorTable_h

229
vtkm/cont/ColorTable.hxx Normal file

@ -0,0 +1,229 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandleTransform.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/colorconversion/LookupTable.h>
#include <vtkm/worklet/colorconversion/Portals.h>
#include <vtkm/worklet/colorconversion/TransferFunction.h>
#include <vtkm/exec/ColorTable.h>
namespace vtkm
{
namespace cont
{
namespace detail
{
struct map_color_table
{
template <typename DeviceAdapter, typename ColorTable, typename... Args>
bool operator()(DeviceAdapter device, ColorTable&& colors, Args&&... args) const
{
using namespace vtkm::worklet::colorconversion;
TransferFunction transfer(colors->PrepareForExecution(device));
vtkm::worklet::DispatcherMapField<TransferFunction, DeviceAdapter> dispatcher(transfer);
dispatcher.Invoke(std::forward<Args>(args)...);
return true;
}
};
struct map_color_table_with_samples
{
template <typename DeviceAdapter, typename... Args>
bool operator()(DeviceAdapter,
const vtkm::worklet::colorconversion::LookupTable& lookupTable,
Args&&... args) const
{
using namespace vtkm::worklet::colorconversion;
vtkm::worklet::DispatcherMapField<LookupTable, DeviceAdapter> dispatcher(lookupTable);
dispatcher.Invoke(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)
{
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);
//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());
#if !defined(VTKM_MSVC) || (defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL == 0)
portal->ColorNodes = vtkm::cont::ArrayPortalToIteratorBegin(p1);
portal->RGB = vtkm::cont::ArrayPortalToIteratorBegin(p2);
portal->ONodes = vtkm::cont::ArrayPortalToIteratorBegin(p3);
portal->Alpha = vtkm::cont::ArrayPortalToIteratorBegin(p4);
portal->MidSharp = vtkm::cont::ArrayPortalToIteratorBegin(p5);
#else
//ArrayPortalToIteratorBegin is returning a checked_array_iterator so
//we need to grab the underlying pointer
portal->ColorNodes = vtkm::cont::ArrayPortalToIteratorBegin(p1).base();
portal->RGB = vtkm::cont::ArrayPortalToIteratorBegin(p2).base();
portal->ONodes = vtkm::cont::ArrayPortalToIteratorBegin(p3).base();
portal->Alpha = vtkm::cont::ArrayPortalToIteratorBegin(p4).base();
portal->MidSharp = vtkm::cont::ArrayPortalToIteratorBegin(p5).base();
#endif
return true;
}
};
}
//---------------------------------------------------------------------------
template <typename T, typename S>
bool ColorTable::Map(const vtkm::cont::ArrayHandle<T, S>& values,
const vtkm::cont::ColorTableSamplesRGBA& samples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& rgbaOut) const
{
if (samples.NumberOfSamples <= 0)
{
return false;
}
vtkm::worklet::colorconversion::LookupTable lookupTable(samples);
return vtkm::cont::TryExecute(
detail::map_color_table_with_samples{}, lookupTable, values, samples.Samples, rgbaOut);
}
//---------------------------------------------------------------------------
template <typename T, typename S>
bool ColorTable::Map(const vtkm::cont::ArrayHandle<T, S>& values,
const vtkm::cont::ColorTableSamplesRGB& samples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& rgbOut) const
{
if (samples.NumberOfSamples <= 0)
{
return false;
}
vtkm::worklet::colorconversion::LookupTable lookupTable(samples);
return vtkm::cont::TryExecute(
detail::map_color_table_with_samples{}, lookupTable, values, samples.Samples, rgbOut);
}
//---------------------------------------------------------------------------
template <typename T, int N, typename S>
bool ColorTable::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
{
using namespace vtkm::worklet::colorconversion;
return this->Map(
vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), samples, rgbaOut);
}
//---------------------------------------------------------------------------
template <typename T, int N, typename S>
bool ColorTable::MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
const vtkm::cont::ColorTableSamplesRGB& samples,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& rgbOut) const
{
using namespace vtkm::worklet::colorconversion;
return this->Map(
vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), samples, rgbOut);
}
//---------------------------------------------------------------------------
template <typename T, int N, typename S>
bool ColorTable::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
{
using namespace vtkm::worklet::colorconversion;
return this->Map(
vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), samples, rgbaOut);
}
//---------------------------------------------------------------------------
template <typename T, int N, typename S>
bool ColorTable::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
{
using namespace vtkm::worklet::colorconversion;
return this->Map(
vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), samples, rgbOut);
}
//---------------------------------------------------------------------------
template <typename T, typename S>
bool ColorTable::Map(const vtkm::cont::ArrayHandle<T, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& rgbaOut) const
{
return vtkm::cont::TryExecute(
detail::map_color_table{}, this->GetHandleForExecution(), values, rgbaOut);
}
//---------------------------------------------------------------------------
template <typename T, typename S>
bool ColorTable::Map(const vtkm::cont::ArrayHandle<T, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& rgbOut) const
{
return vtkm::cont::TryExecute(
detail::map_color_table{}, this->GetHandleForExecution(), values, rgbOut);
}
//---------------------------------------------------------------------------
template <typename T, int N, typename S>
bool ColorTable::MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& rgbaOut) const
{
using namespace vtkm::worklet::colorconversion;
return this->Map(vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), rgbaOut);
}
//---------------------------------------------------------------------------
template <typename T, int N, typename S>
bool ColorTable::MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& rgbOut) const
{
using namespace vtkm::worklet::colorconversion;
return this->Map(vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), rgbOut);
}
//---------------------------------------------------------------------------
template <typename T, int N, typename S>
bool ColorTable::MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>>& rgbaOut) const
{
using namespace vtkm::worklet::colorconversion;
return this->Map(vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), rgbaOut);
}
//---------------------------------------------------------------------------
template <typename T, int N, typename S>
bool ColorTable::MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>>& rgbOut) const
{
using namespace vtkm::worklet::colorconversion;
return this->Map(vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), rgbOut);
}
}
}

@ -0,0 +1,375 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/Range.h>
#include <vtkm/Types.h>
#include <vtkm/cont/VirtualObjectHandle.h>
#include <vtkm/exec/ColorTable.h>
#include <limits>
#include <vector>
namespace vtkm
{
namespace cont
{
namespace detail
{
struct ColorTableInternals
{
ColorSpace CSpace = ColorSpace::RGB;
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
vtkm::exec::ColorTableBase* HostSideCache = nullptr;
//Execution side version of the ColorTableBase.
vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase>* ExecHandle = nullptr;
std::vector<double> ColorNodePos;
std::vector<vtkm::Vec<float, 3>> ColorRGB;
std::vector<double> OpacityNodePos;
std::vector<float> OpacityAlpha;
std::vector<vtkm::Vec<float, 2>> OpacityMidSharp;
vtkm::cont::ArrayHandle<double> ColorPosHandle;
vtkm::cont::ArrayHandle<vtkm::Vec<float, 3>> ColorRGBHandle;
vtkm::cont::ArrayHandle<double> OpacityPosHandle;
vtkm::cont::ArrayHandle<float> OpacityAlphaHandle;
vtkm::cont::ArrayHandle<vtkm::Vec<float, 2>> OpacityMidSharpHandle;
bool ColorArraysChanged = true;
bool OpacityArraysChanged = true;
void RecalculateRange()
{
vtkm::Range r;
if (this->ColorNodePos.size() > 0)
{
r.Include(this->ColorNodePos.front());
r.Include(this->ColorNodePos.back());
}
if (this->OpacityNodePos.size() > 0)
{
r.Include(this->OpacityNodePos.front());
r.Include(this->OpacityNodePos.back());
}
this->TableRange = r;
}
};
} //namespace detail
namespace
{
template <typename T>
struct MinDelta
{
};
// This value seems to work well for float ranges we have tested
template <>
struct MinDelta<float>
{
static constexpr int value = 2048;
};
template <>
struct MinDelta<double>
{
static constexpr vtkm::Int64 value = 2048L;
};
// Reperesents the following:
// T m = std::numeric_limits<T>::min();
// EquivSizeIntT im;
// std::memcpy(&im, &m, sizeof(T));
//
template <typename EquivSizeIntT>
struct MinRepresentable
{
};
template <>
struct MinRepresentable<float>
{
static constexpr int value = 8388608;
};
template <>
struct MinRepresentable<double>
{
static constexpr vtkm::Int64 value = 4503599627370496L;
};
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, &r.Max, sizeof(vtkm::Int64));
// determine the absolute delta between these two numbers.
const vtkm::Int64 delta = std::abs(irange[1] - irange[0]);
// If the numbers are not nearly equal, we don't touch them. This avoids running into
// pitfalls like BUG PV #17152.
return (delta < 1024) ? true : false;
}
template <typename T>
double expandRange(T r[2])
{
constexpr bool is_float32_type = std::is_same<T, vtkm::Float32>::value;
using IRange = typename std::conditional<is_float32_type, vtkm::Int32, vtkm::Int64>::type;
IRange irange[2];
// needs to be a memcpy to avoid strict aliasing issues, doing a count
// of 2*sizeof(T) to couple both values at the same time
std::memcpy(irange, r, sizeof(T) * 2);
const bool denormal = !std::isnormal(r[0]);
const IRange minInt = MinRepresentable<T>::value;
const IRange minDelta = denormal ? minInt + MinDelta<T>::value : MinDelta<T>::value;
// determine the absolute delta between these two numbers.
const vtkm::Int64 delta = std::abs(irange[1] - irange[0]);
// if our delta is smaller than the min delta push out the max value
// so that it is equal to minRange + minDelta. When our range is entirely
// negative we should instead subtract from our max, to max a larger negative
// value
if (delta < minDelta)
{
if (irange[0] < 0)
{
irange[1] = irange[0] - minDelta;
}
else
{
irange[1] = irange[0] + minDelta;
}
T result;
std::memcpy(&result, irange + 1, sizeof(T));
return static_cast<double>(result);
}
return static_cast<double>(r[1]);
}
vtkm::Range adjustRange(const vtkm::Range& r)
{
const bool spans_zero_boundary = r.Min < 0 && r.Max > 0;
if (spans_zero_boundary)
{ // nothing needs to be done, but this check is required.
// if we convert into integer space the delta difference will overflow
// an integer
return r;
}
if (rangeAlmostEqual(r))
{
return r;
}
// range should be left untouched as much as possible to
// to avoid loss of precision whenever possible. That is why
// we only modify the Max value
vtkm::Range result = r;
if (r.Min > static_cast<double>(std::numeric_limits<float>::lowest()) &&
r.Max < static_cast<double>(std::numeric_limits<float>::max()))
{ //We've found it best to offset it in float space if the numbers
//lay inside that representable range
float frange[2] = { static_cast<float>(r.Min), static_cast<float>(r.Max) };
result.Max = expandRange(frange);
}
else
{
double drange[2] = { r.Min, r.Max };
result.Max = expandRange(drange);
}
return result;
}
template <typename T>
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>
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);
}
vtkm::Vec<double, 3> hsvTorgb(const vtkm::Vec<double, 3>& hsv)
{
vtkm::Vec<double, 3> rgb;
constexpr double onethird = 1.0 / 3.0;
constexpr double onesixth = 1.0 / 6.0;
constexpr double twothird = 2.0 / 3.0;
constexpr double fivesixth = 5.0 / 6.0;
// compute RGB from HSV
if (hsv[0] > onesixth && hsv[0] <= onethird) // green/red
{
rgb[1] = 1.0;
rgb[0] = (onethird - hsv[0]) * 6;
rgb[2] = 0.0;
}
else if (hsv[0] > onethird && hsv[0] <= 0.5) // green/blue
{
rgb[1] = 1.0;
rgb[2] = (hsv[0] - onethird) * 6;
rgb[0] = 0.0;
}
else if (hsv[0] > 0.5 && hsv[0] <= twothird) // blue/green
{
rgb[2] = 1.0;
rgb[1] = (twothird - hsv[0]) * 6;
rgb[0] = 0.0;
}
else if (hsv[0] > twothird && hsv[0] <= fivesixth) // blue/red
{
rgb[2] = 1.0;
rgb[0] = (hsv[0] - twothird) * 6;
rgb[1] = 0.0;
}
else if (hsv[0] > fivesixth && hsv[0] <= 1.0) // red/blue
{
rgb[0] = 1.0;
rgb[2] = (1.0 - hsv[0]) * 6;
rgb[1] = 0.0;
}
else // red/green
{
rgb[0] = 1.0;
rgb[1] = hsv[0] * 6;
rgb[2] = 0.0;
}
// add Saturation to the equation.
rgb[0] = (hsv[1] * rgb[0] + (1.0 - hsv[1]));
rgb[1] = (hsv[1] * rgb[1] + (1.0 - hsv[1]));
rgb[2] = (hsv[1] * rgb[2] + (1.0 - hsv[1]));
rgb[0] *= hsv[2];
rgb[1] *= hsv[2];
rgb[2] *= hsv[2];
return rgb;
}
// clang-format off
bool outside_vrange(double x) { return x < 0.0 || x > 1.0; }
bool outside_vrange(const vtkm::Vec<double, 2>& x)
{ return x[0] < 0.0 || x[0] > 1.0 || x[1] < 0.0 || x[1] > 1.0; }
bool outside_vrange(const vtkm::Vec<double, 3>& x)
{ return x[0] < 0.0 || x[0] > 1.0 || x[1] < 0.0 || x[1] > 1.0 || x[2] < 0.0 || x[2] > 1.0; }
bool outside_range() { return false; }
template <typename T>
bool outside_range(T&& t) { return outside_vrange(t); }
template <typename T, typename U>
bool outside_range(T&& t, U&& u) { return outside_vrange(t) || outside_vrange(u); }
template <typename T, typename U, typename V, typename... Args>
bool outside_range(T&& t, U&& u, V&& v, Args&&... args)
{
return outside_vrange(t) || outside_vrange(u) || outside_vrange(v) ||
outside_range(std::forward<Args>(args)...);
}
// clang-format on
}
} //namespace cont
} //namespace vtkm

@ -0,0 +1,71 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_ColorTableSamples_h
#define vtk_m_cont_ColorTableSamples_h
#include <vtkm/Range.h>
#include <vtkm/cont/ArrayHandle.h>
namespace vtkm
{
namespace cont
{
/// \brief Color Sample Table used with vtkm::cont::ColorTable for fast coloring
///
/// Holds a special layout of sampled values with the pattern of
/// [Below Color, samples, last sample value again, Above Color, Nan Color ]
///
/// This layout has been chosen as it allows for efficient access for values
/// inside the range, and values outside the range. The last value being duplicated
/// a second time is an optimization for fast interpolation of values that are
/// very near to the Max value of the range.
///
///
class ColorTableSamplesRGBA
{
public:
vtkm::Range SampleRange = { 1.0, 0.0 };
vtkm::Int32 NumberOfSamples = 0; // this will not include end padding, NaN, Below or Above Range
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>> Samples;
};
/// \brief Color Sample Table used with vtkm::cont::ColorTable for fast coloring
///
/// Holds a special layout of sampled values with the pattern of
/// [Below Color, samples, last sample value again, Above Color ]
///
/// This layout has been chosen as it allows for efficient access for values
/// inside the range, and values outside the range. The last value being duplicated
/// a second time is an optimization for fast interpolation of values that are
/// very near to the Max value of the range.
///
///
class ColorTableSamplesRGB
{
public:
vtkm::Range SampleRange = { 1.0, 0.0 };
vtkm::Int32 NumberOfSamples = 0; // this will not include end padding, NaN, Below or Above Range
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>> Samples;
};
}
}
#endif

@ -18,7 +18,9 @@
// this software.
//============================================================================
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/CoordinateSystem.hxx>
namespace vtkm
{
@ -29,6 +31,44 @@ using CoordinatesTypeList = vtkm::ListTagBase<vtkm::cont::ArrayHandleVirtualCoor
using CoordinatesStorageList =
vtkm::ListTagBase<vtkm::cont::ArrayHandleVirtualCoordinates::StorageTag>;
VTKM_CONT CoordinateSystem::CoordinateSystem()
: Superclass()
{
}
VTKM_CONT CoordinateSystem::CoordinateSystem(
std::string name,
const vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& data)
: Superclass(name, ASSOC_POINTS, data)
{
}
/// This constructor of coordinate system sets up a regular grid of points.
///
VTKM_CONT
CoordinateSystem::CoordinateSystem(std::string name,
vtkm::Id3 dimensions,
vtkm::Vec<vtkm::FloatDefault, 3> origin,
vtkm::Vec<vtkm::FloatDefault, 3> spacing)
: Superclass(name,
ASSOC_POINTS,
vtkm::cont::ArrayHandleVirtualCoordinates(
vtkm::cont::ArrayHandleUniformPointCoordinates(dimensions, origin, spacing)))
{
}
VTKM_CONT
vtkm::cont::ArrayHandleVirtualCoordinates CoordinateSystem::GetData() const
{
return this->Superclass::GetData().Cast<vtkm::cont::ArrayHandleVirtualCoordinates>();
}
VTKM_CONT
void CoordinateSystem::SetData(const vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& newdata)
{
this->Superclass::SetData(newdata);
}
VTKM_CONT
void CoordinateSystem::PrintSummary(std::ostream& out) const
{
@ -55,5 +95,42 @@ vtkm::Bounds CoordinateSystem::GetBounds() const
this->GetRange(ranges);
return vtkm::Bounds(ranges[0], ranges[1], ranges[2]);
}
template VTKM_CONT_EXPORT CoordinateSystem::CoordinateSystem(
std::string name,
const vtkm::cont::ArrayHandle<vtkm::Vec<float, 3>>&);
template VTKM_CONT_EXPORT CoordinateSystem::CoordinateSystem(
std::string name,
const vtkm::cont::ArrayHandle<vtkm::Vec<double, 3>>&);
template VTKM_CONT_EXPORT CoordinateSystem::CoordinateSystem(
std::string name,
const vtkm::cont::ArrayHandle<
vtkm::Vec<vtkm::FloatDefault, 3>,
vtkm::cont::StorageTagImplicit<vtkm::internal::ArrayPortalUniformPointCoordinates>>&);
template VTKM_CONT_EXPORT CoordinateSystem::CoordinateSystem(
std::string name,
const vtkm::cont::ArrayHandle<
vtkm::Vec<vtkm::FloatDefault, 3>,
vtkm::cont::internal::StorageTagCartesianProduct<
vtkm::cont::ArrayHandle<vtkm::FloatDefault, vtkm::cont::StorageTagBasic>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault, vtkm::cont::StorageTagBasic>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault, vtkm::cont::StorageTagBasic>>>&);
template VTKM_CONT_EXPORT CoordinateSystem::CoordinateSystem(
std::string name,
const vtkm::cont::ArrayHandle<
vtkm::Vec<vtkm::FloatDefault, 3>,
vtkm::cont::internal::StorageTagCompositeVector<vtkm::Vec<vtkm::FloatDefault, 3>(
vtkm::cont::ArrayHandle<vtkm::FloatDefault, vtkm::cont::StorageTagBasic>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault, vtkm::cont::StorageTagBasic>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault, vtkm::cont::StorageTagBasic>)>>&);
template VTKM_CONT_EXPORT CoordinateSystem::CoordinateSystem(std::string name,
const vtkm::cont::DynamicArrayHandle&);
template VTKM_CONT_EXPORT void CoordinateSystem::SetData(
const vtkm::cont::ArrayHandle<vtkm::Vec<float, 3>>&);
template VTKM_CONT_EXPORT void CoordinateSystem::SetData(
const vtkm::cont::ArrayHandle<vtkm::Vec<double, 3>>&);
template VTKM_CONT_EXPORT void CoordinateSystem::SetData(const vtkm::cont::DynamicArrayHandle&);
}
} // namespace vtkm::cont

@ -23,7 +23,6 @@
#include <vtkm/Bounds.h>
#include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/ArrayHandleVirtualCoordinates.h>
#include <vtkm/cont/Field.h>
@ -31,82 +30,23 @@ namespace vtkm
{
namespace cont
{
namespace detail
{
struct MakeArrayHandleVirtualCoordinatesFunctor
{
VTKM_CONT explicit MakeArrayHandleVirtualCoordinatesFunctor(
vtkm::cont::ArrayHandleVirtualCoordinates& out)
: Out(&out)
{
}
template <typename StorageTag>
VTKM_CONT void operator()(
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>, StorageTag>& array) const
{
*this->Out = vtkm::cont::ArrayHandleVirtualCoordinates(array);
}
template <typename StorageTag>
VTKM_CONT void operator()(
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>, StorageTag>& array) const
{
*this->Out = vtkm::cont::ArrayHandleVirtualCoordinates(array);
}
template <typename T, typename StorageTag>
VTKM_CONT void operator()(const vtkm::cont::ArrayHandle<T, StorageTag>&) const
{
throw vtkm::cont::ErrorBadType("CoordinateSystem's value type should be a 3 component Vec "
"of either vtkm::Float32 or vtkm::Float64");
}
vtkm::cont::ArrayHandleVirtualCoordinates* Out;
};
template <typename TypeList, typename StorageList>
VTKM_CONT vtkm::cont::ArrayHandleVirtualCoordinates MakeArrayHandleVirtualCoordinates(
const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& array)
{
vtkm::cont::ArrayHandleVirtualCoordinates out;
array.CastAndCall(MakeArrayHandleVirtualCoordinatesFunctor(out));
return out;
}
} // namespace detail
class VTKM_CONT_EXPORT CoordinateSystem : public vtkm::cont::Field
{
using Superclass = vtkm::cont::Field;
public:
VTKM_CONT
CoordinateSystem()
: Superclass()
{
}
CoordinateSystem();
VTKM_CONT CoordinateSystem(std::string name,
const vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& data)
: Superclass(name, ASSOC_POINTS, data)
{
}
const vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& data);
template <typename TypeList, typename StorageList>
VTKM_CONT CoordinateSystem(std::string name,
const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& data)
: Superclass(name, ASSOC_POINTS, detail::MakeArrayHandleVirtualCoordinates(data))
{
}
const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& data);
template <typename T, typename Storage>
VTKM_CONT CoordinateSystem(std::string name, const ArrayHandle<T, Storage>& data)
: Superclass(name, ASSOC_POINTS, vtkm::cont::ArrayHandleVirtualCoordinates(data))
{
}
VTKM_CONT CoordinateSystem(std::string name, const ArrayHandle<T, Storage>& data);
/// This constructor of coordinate system sets up a regular grid of points.
///
@ -115,40 +55,22 @@ public:
std::string name,
vtkm::Id3 dimensions,
vtkm::Vec<vtkm::FloatDefault, 3> origin = vtkm::Vec<vtkm::FloatDefault, 3>(0.0f, 0.0f, 0.0f),
vtkm::Vec<vtkm::FloatDefault, 3> spacing = vtkm::Vec<vtkm::FloatDefault, 3>(1.0f, 1.0f, 1.0f))
: Superclass(name,
ASSOC_POINTS,
vtkm::cont::ArrayHandleVirtualCoordinates(
vtkm::cont::ArrayHandleUniformPointCoordinates(dimensions, origin, spacing)))
{
}
vtkm::Vec<vtkm::FloatDefault, 3> spacing = vtkm::Vec<vtkm::FloatDefault, 3>(1.0f, 1.0f, 1.0f));
VTKM_CONT
CoordinateSystem& operator=(const vtkm::cont::CoordinateSystem& src) = default;
VTKM_CONT
vtkm::cont::ArrayHandleVirtualCoordinates GetData() const
{
return this->Superclass::GetData().Cast<vtkm::cont::ArrayHandleVirtualCoordinates>();
}
vtkm::cont::ArrayHandleVirtualCoordinates GetData() const;
VTKM_CONT void SetData(const vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& newdata)
{
this->Superclass::SetData(newdata);
}
VTKM_CONT void SetData(const vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& newdata);
template <typename T, typename StorageTag>
VTKM_CONT void SetData(const vtkm::cont::ArrayHandle<T, StorageTag>& newdata)
{
this->Superclass::SetData(vtkm::cont::ArrayHandleVirtualCoordinates(newdata));
}
VTKM_CONT void SetData(const vtkm::cont::ArrayHandle<T, StorageTag>& newdata);
VTKM_CONT
template <typename TypeList, typename StorageList>
void SetData(const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& newdata)
{
this->Superclass::SetData(detail::MakeArrayHandleVirtualCoordinates(newdata));
}
void SetData(const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& newdata);
VTKM_CONT
void GetRange(vtkm::Range* range) const;

@ -0,0 +1,92 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_CoordinateSystem_hxx
#define vtk_m_cont_CoordinateSystem_hxx
#include <vtkm/cont/CoordinateSystem.h>
namespace vtkm
{
namespace cont
{
namespace detail
{
struct MakeArrayHandleVirtualCoordinatesFunctor
{
template <typename StorageTag>
VTKM_CONT void operator()(
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>, StorageTag>& array,
ArrayHandleVirtualCoordinates& output) const
{
output = vtkm::cont::ArrayHandleVirtualCoordinates(array);
}
template <typename StorageTag>
VTKM_CONT void operator()(
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>, StorageTag>& array,
ArrayHandleVirtualCoordinates& output) const
{
output = vtkm::cont::ArrayHandleVirtualCoordinates(array);
}
};
template <typename TypeList, typename StorageList>
VTKM_CONT vtkm::cont::ArrayHandleVirtualCoordinates MakeArrayHandleVirtualCoordinates(
const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& array)
{
vtkm::cont::ArrayHandleVirtualCoordinates output;
vtkm::cont::CastAndCall(array.ResetTypeList(vtkm::TypeListTagFieldVec3{}),
MakeArrayHandleVirtualCoordinatesFunctor{},
output);
return output;
}
} // namespace detail
template <typename TypeList, typename StorageList>
VTKM_CONT CoordinateSystem::CoordinateSystem(
std::string name,
const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& data)
: Superclass(name, ASSOC_POINTS, detail::MakeArrayHandleVirtualCoordinates(data))
{
}
template <typename T, typename Storage>
VTKM_CONT CoordinateSystem::CoordinateSystem(std::string name,
const vtkm::cont::ArrayHandle<T, Storage>& data)
: Superclass(name, ASSOC_POINTS, vtkm::cont::ArrayHandleVirtualCoordinates(data))
{
}
template <typename T, typename Storage>
VTKM_CONT void CoordinateSystem::SetData(const vtkm::cont::ArrayHandle<T, Storage>& newdata)
{
this->SetData(vtkm::cont::ArrayHandleVirtualCoordinates(newdata));
}
template <typename TypeList, typename StorageList>
VTKM_CONT void CoordinateSystem::SetData(
const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& newdata)
{
this->SetData(detail::MakeArrayHandleVirtualCoordinates(newdata));
}
}
}
#endif

@ -20,9 +20,16 @@
#ifndef vtk_m_cont_DecomposerMultiBlock_h
#define vtk_m_cont_DecomposerMultiBlock_h
#include <vtkm/internal/Configure.h>
#if defined(VTKM_ENABLE_MPI)
#include <vtkm/cont/AssignerMultiBlock.h>
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/internal/ExportMacros.h>
#include <vtkm/thirdparty/diy/Configure.h>
// clang-format off
VTKM_THIRDPARTY_PRE_INCLUDE
#include VTKM_DIY(diy/assigner.hpp)
VTKM_THIRDPARTY_POST_INCLUDE
// clang-format on
namespace vtkm
{
@ -52,6 +59,4 @@ public:
}
}
#endif // defined(VTKM_ENABLE_MPI)
#endif

@ -29,6 +29,7 @@
#include <vtkm/cont/ErrorBadType.h>
#include <vtkm/cont/StorageListTag.h>
#include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/internal/DynamicTransform.h>
namespace vtkm
@ -408,26 +409,17 @@ namespace detail
struct DynamicArrayHandleTry
{
DynamicArrayHandleTry(const PolymorphicArrayHandleContainerBase* const c)
: Container(c)
{
}
template <typename T, typename U, typename... Args>
void operator()(brigand::list<T, U>, Args&&... args) const
{
using storage = vtkm::cont::internal::Storage<T, U>;
using invalid = typename std::is_base_of<vtkm::cont::internal::UndefinedStorage, storage>::type;
this->run<T, U>(invalid{}, args...);
}
template <typename T, typename U, typename Functor, typename... Args>
void run(std::false_type, Functor&& f, bool& called, Args&&... args) const
void operator()(brigand::list<T, U>,
Functor&& f,
bool& called,
const PolymorphicArrayHandleContainerBase* const container,
Args&&... args) const
{
if (!called)
{
using downcastType = const vtkm::cont::detail::PolymorphicArrayHandleContainer<T, U>* const;
downcastType downcastContainer = dynamic_cast<downcastType>(this->Container);
downcastType downcastContainer = dynamic_cast<downcastType>(container);
if (downcastContainer)
{
f(downcastContainer->Array, std::forward<Args>(args)...);
@ -435,13 +427,6 @@ struct DynamicArrayHandleTry
}
}
}
template <typename T, typename U, typename... Args>
void run(std::true_type, Args&&...) const
{
}
const PolymorphicArrayHandleContainerBase* const Container;
};
VTKM_CONT_EXPORT void ThrowCastAndCallException(PolymorphicArrayHandleContainerBase*,
@ -449,6 +434,25 @@ VTKM_CONT_EXPORT void ThrowCastAndCallException(PolymorphicArrayHandleContainerB
const std::type_info*);
} // namespace detail
template <typename T>
struct IsUndefinedStorage
{
};
template <typename T, typename U>
struct IsUndefinedStorage<brigand::list<T, U>> : vtkm::cont::internal::IsInValidArrayHandle<T, U>
{
};
template <typename TypeList, typename StorageList>
struct ListTagDynamicTypes : vtkm::detail::ListRoot
{
using crossProduct = typename vtkm::ListCrossProduct<TypeList, StorageList>;
// using list = typename crossProduct::list;
using list = ::brigand::remove_if<typename crossProduct::list, IsUndefinedStorage<brigand::_1>>;
};
template <typename TypeList, typename StorageList>
template <typename Functor, typename... Args>
VTKM_CONT void DynamicArrayHandleBase<TypeList, StorageList>::CastAndCall(Functor&& f,
@ -456,14 +460,15 @@ VTKM_CONT void DynamicArrayHandleBase<TypeList, StorageList>::CastAndCall(Functo
{
//For optimizations we should compile once the cross product for the default types
//and make it extern
using crossProduct = typename vtkm::ListCrossProduct<TypeList, StorageList>;
using crossProduct = ListTagDynamicTypes<TypeList, StorageList>;
bool called = false;
auto* ptr = this->ArrayContainer.get();
vtkm::ListForEach(detail::DynamicArrayHandleTry(ptr),
vtkm::ListForEach(detail::DynamicArrayHandleTry{},
crossProduct{},
std::forward<Functor>(f),
called,
ptr,
std::forward<Args>(args)...);
if (!called)
{

@ -19,30 +19,16 @@
//============================================================================
#include <vtkm/cont/EnvironmentTracker.h>
#if defined(VTKM_ENABLE_MPI)
// clang-format off
#include <vtkm/thirdparty/diy/Configure.h>
VTKM_THIRDPARTY_PRE_INCLUDE
#include VTKM_DIY(diy/mpi.hpp)
VTKM_THIRDPARTY_POST_INCLUDE
// clang-format on
#else
namespace diy
{
namespace mpi
{
class communicator
{
};
}
}
#endif
namespace vtkm
{
namespace cont
{
#if defined(VTKM_ENABLE_MPI)
namespace internal
{
static diy::mpi::communicator GlobalCommuncator(MPI_COMM_NULL);
@ -57,16 +43,5 @@ const diy::mpi::communicator& EnvironmentTracker::GetCommunicator()
{
return vtkm::cont::internal::GlobalCommuncator;
}
#else
void EnvironmentTracker::SetCommunicator(const diy::mpi::communicator&)
{
}
const diy::mpi::communicator& EnvironmentTracker::GetCommunicator()
{
static diy::mpi::communicator tmp;
return tmp;
}
#endif
} // namespace vtkm::cont
} // namespace vtkm

@ -22,13 +22,8 @@
#include <vtkm/Types.h>
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/internal/Configure.h>
#include <vtkm/internal/ExportMacros.h>
#if defined(VTKM_ENABLE_MPI)
// needed for diy mangling.
#include <vtkm/thirdparty/diy/Configure.h>
#endif
namespace diy
{
@ -42,6 +37,11 @@ namespace vtkm
{
namespace cont
{
/// \brief Maintain MPI controller, if any, for distributed operation.
///
/// `EnvironmentTracker` is a class that provides static API to track the global
/// MPI controller to use for operating in a distributed environment.
class VTKM_CONT_EXPORT EnvironmentTracker
{
public:

@ -27,7 +27,7 @@
#include <exception>
#include <string>
#include <vtkm/internal/ExportMacros.h> // For VTKM_NOEXCEPT
#include <vtkm/internal/ExportMacros.h>
namespace vtkm
{
@ -55,7 +55,7 @@ public:
#endif
// For std::exception compatibility:
const char* what() const VTKM_NOEXCEPT override { return this->Message.c_str(); }
const char* what() const noexcept override { return this->Message.c_str(); }
protected:
Error() {}

@ -31,14 +31,15 @@
#include <vtkm/cont/Field.h>
#include <vtkm/cont/MultiBlock.h>
#if defined(VTKM_ENABLE_MPI)
// clang-format off
VTKM_THIRDPARTY_PRE_INCLUDE
#include <vtkm/thirdparty/diy/Configure.h>
#include VTKM_DIY(diy/decomposition.hpp)
#include VTKM_DIY(diy/master.hpp)
#include VTKM_DIY(diy/partners/all-reduce.hpp)
#include VTKM_DIY(diy/partners/swap.hpp)
#include VTKM_DIY(diy/reduce.hpp)
VTKM_THIRDPARTY_POST_INCLUDE
// clang-format on
namespace vtkm
@ -51,10 +52,15 @@ template <typename PortalType>
VTKM_CONT std::vector<typename PortalType::ValueType> CopyArrayPortalToVector(
const PortalType& portal)
{
const size_t count =
portal.GetNumberOfValues() > 0 ? static_cast<size_t>(portal.GetNumberOfValues()) : 0;
using ValueType = typename PortalType::ValueType;
std::vector<ValueType> result(portal.GetNumberOfValues());
vtkm::cont::ArrayPortalToIterators<PortalType> iterators(portal);
std::copy(iterators.GetBegin(), iterators.GetEnd(), result.begin());
std::vector<ValueType> result(count);
if (count > 0)
{
vtkm::cont::ArrayPortalToIterators<PortalType> iterators(portal);
std::copy(iterators.GetBegin(), iterators.GetEnd(), result.begin());
}
return result;
}
@ -72,8 +78,6 @@ const vtkm::cont::DataSet& GetBlock(const vtkm::cont::MultiBlock& mb,
}
}
#endif
namespace vtkm
{
namespace cont
@ -137,7 +141,6 @@ vtkm::Id MultiBlock::GetNumberOfBlocks() const
VTKM_CONT
vtkm::Id MultiBlock::GetGlobalNumberOfBlocks() const
{
#if defined(VTKM_ENABLE_MPI)
auto world = vtkm::cont::EnvironmentTracker::GetCommunicator();
const auto local_count = this->GetNumberOfBlocks();
@ -151,9 +154,6 @@ vtkm::Id MultiBlock::GetGlobalNumberOfBlocks() const
master.process_collectives();
vtkm::Id global_count = master.proxy(0).get<vtkm::Id>();
return global_count;
#else
return this->GetNumberOfBlocks();
#endif
}
VTKM_CONT
@ -169,20 +169,20 @@ const std::vector<vtkm::cont::DataSet>& MultiBlock::GetBlocks() const
}
VTKM_CONT
void MultiBlock::AddBlock(vtkm::cont::DataSet& ds)
void MultiBlock::AddBlock(const vtkm::cont::DataSet& ds)
{
this->Blocks.insert(this->Blocks.end(), ds);
return;
}
void MultiBlock::AddBlocks(std::vector<vtkm::cont::DataSet>& mblocks)
void MultiBlock::AddBlocks(const std::vector<vtkm::cont::DataSet>& mblocks)
{
this->Blocks.insert(this->Blocks.end(), mblocks.begin(), mblocks.end());
return;
}
VTKM_CONT
void MultiBlock::InsertBlock(vtkm::Id index, vtkm::cont::DataSet& ds)
void MultiBlock::InsertBlock(vtkm::Id index, const vtkm::cont::DataSet& ds)
{
if (index <= static_cast<vtkm::Id>(this->Blocks.size()))
this->Blocks.insert(this->Blocks.begin() + index, ds);
@ -194,7 +194,7 @@ void MultiBlock::InsertBlock(vtkm::Id index, vtkm::cont::DataSet& ds)
}
VTKM_CONT
void MultiBlock::ReplaceBlock(vtkm::Id index, vtkm::cont::DataSet& ds)
void MultiBlock::ReplaceBlock(vtkm::Id index, const vtkm::cont::DataSet& ds)
{
if (index < static_cast<vtkm::Id>(this->Blocks.size()))
this->Blocks.at(static_cast<std::size_t>(index)) = ds;
@ -207,7 +207,6 @@ void MultiBlock::ReplaceBlock(vtkm::Id index, vtkm::cont::DataSet& ds)
VTKM_CONT vtkm::Bounds MultiBlock::GetBounds(vtkm::Id coordinate_system_index) const
{
#if defined(VTKM_ENABLE_MPI)
auto world = vtkm::cont::EnvironmentTracker::GetCommunicator();
diy::Master master(world,
1,
@ -259,19 +258,6 @@ VTKM_CONT vtkm::Bounds MultiBlock::GetBounds(vtkm::Id coordinate_system_index) c
return (*master.block<vtkm::Bounds>(0));
}
return vtkm::Bounds();
#else
const vtkm::Id index = coordinate_system_index;
const size_t num_blocks = this->Blocks.size();
vtkm::Bounds bounds;
for (size_t i = 0; i < num_blocks; ++i)
{
vtkm::Bounds block_bounds = this->GetBlockBounds(i, index);
bounds.Include(block_bounds);
}
return bounds;
#endif
}
VTKM_CONT vtkm::Bounds MultiBlock::GetBlockBounds(const std::size_t& block_index,
@ -305,7 +291,6 @@ VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> MultiBlock::GetGlobalRange(const
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> MultiBlock::GetGlobalRange(
const std::string& field_name) const
{
#if defined(VTKM_ENABLE_MPI)
using BlockMetaData = std::vector<vtkm::Range>;
auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
@ -366,64 +351,6 @@ VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> MultiBlock::GetGlobalRange(
vtkm::cont::ArrayHandle<vtkm::Range> range;
vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandle(ranges), range);
return range;
#else
bool valid_field = true;
const size_t num_blocks = this->Blocks.size();
vtkm::cont::ArrayHandle<vtkm::Range> range;
vtkm::Id num_components = 0;
for (size_t i = 0; i < num_blocks; ++i)
{
if (!this->Blocks[i].HasField(field_name))
{
valid_field = false;
break;
}
const vtkm::cont::Field& field = this->Blocks[i].GetField(field_name);
vtkm::cont::ArrayHandle<vtkm::Range> sub_range = field.GetRange();
vtkm::cont::ArrayHandle<vtkm::Range>::PortalConstControl sub_range_control =
sub_range.GetPortalConstControl();
vtkm::cont::ArrayHandle<vtkm::Range>::PortalControl range_control = range.GetPortalControl();
if (i == 0)
{
num_components = sub_range_control.GetNumberOfValues();
range = sub_range;
continue;
}
vtkm::Id components = sub_range_control.GetNumberOfValues();
if (components != num_components)
{
std::stringstream msg;
msg << "GetRange call failed. The number of components (" << components << ") in field "
<< field_name << " from block " << i << " does not match the number of components "
<< "(" << num_components << ") in block 0";
throw ErrorExecution(msg.str());
}
for (vtkm::Id c = 0; c < components; ++c)
{
vtkm::Range s_range = sub_range_control.Get(c);
vtkm::Range c_range = range_control.Get(c);
c_range.Include(s_range);
range_control.Set(c, c_range);
}
}
if (!valid_field)
{
std::string msg = "GetRange call failed. ";
msg += " Field " + field_name + " did not exist in at least one block.";
throw ErrorExecution(msg);
}
return range;
#endif
}
VTKM_CONT

@ -78,16 +78,16 @@ public:
const std::vector<vtkm::cont::DataSet>& GetBlocks() const;
/// add DataSet "ds" to the end of the contained DataSet vector
VTKM_CONT
void AddBlock(vtkm::cont::DataSet& ds);
void AddBlock(const vtkm::cont::DataSet& ds);
/// add DataSet "ds" to position "index" of the contained DataSet vector
VTKM_CONT
void InsertBlock(vtkm::Id index, vtkm::cont::DataSet& ds);
void InsertBlock(vtkm::Id index, const vtkm::cont::DataSet& ds);
/// replace the "index" positioned element of the contained DataSet vector with "ds"
VTKM_CONT
void ReplaceBlock(vtkm::Id index, vtkm::cont::DataSet& ds);
void ReplaceBlock(vtkm::Id index, const vtkm::cont::DataSet& ds);
/// append the DataSet vector "mblocks" to the end of the contained one
VTKM_CONT
void AddBlocks(std::vector<vtkm::cont::DataSet>& mblocks);
void AddBlocks(const std::vector<vtkm::cont::DataSet>& mblocks);
/// get the unified bounds of the same indexed coordinate system within all contained DataSet
VTKM_CONT
vtkm::Bounds GetBounds(vtkm::Id coordinate_system_index = 0) const;
@ -111,6 +111,15 @@ public:
VTKM_CONT
void PrintSummary(std::ostream& stream) const;
//@{
/// API to support range-based for loops on blocks.
std::vector<DataSet>::iterator begin() noexcept { return this->Blocks.begin(); }
std::vector<DataSet>::iterator end() noexcept { return this->Blocks.end(); }
std::vector<DataSet>::const_iterator begin() const noexcept { return this->Blocks.begin(); }
std::vector<DataSet>::const_iterator end() const noexcept { return this->Blocks.end(); }
std::vector<DataSet>::const_iterator cbegin() const noexcept { return this->Blocks.begin(); }
std::vector<DataSet>::const_iterator cend() const noexcept { return this->Blocks.end(); }
//@}
private:
std::vector<vtkm::cont::DataSet> Blocks;
};

@ -0,0 +1,609 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/cont/ColorTable.h>
#include <vtkm/cont/vtkm_cont_export.h>
#include <algorithm>
#include <cctype>
#include <set>
namespace
{
template <int Points>
struct ColorTable
{
static constexpr int points = Points;
static constexpr int size = points * 4;
const vtkm::cont::ColorSpace space;
const double values[size];
};
// clang-format off
static constexpr ColorTable<3> CoolToWarm = {
vtkm::cont::ColorSpace::DIVERGING,
{ 0, 0.23137254902, 0.298039215686, 0.752941176471,
0.5, 0.865, 0.865, 0.865,
1, 0.705882352941, 0.0156862745098, 0.149019607843
}
};
static constexpr ColorTable<4> BlackBody = {
vtkm::cont::ColorSpace::RGB,
{ 0, 0, 0, 0,
0.4, 0.901960784314, 0, 0,
0.8, 0.901960784314, 0.901960784314, 0,
1, 1, 1, 1
}
};
static constexpr ColorTable<4> SamselFire = {
vtkm::cont::ColorSpace::RGB,
{ 0, 0, 0, 0,
0.333, 0.501960784314, 0, 0,
0.666, 1, 0.501960784314, 0,
1, 1, 1, 1
}
};
static constexpr ColorTable<256> Inferno = {
vtkm::cont::ColorSpace::LAB,
{ 0.000000, 0.001462, 0.000466, 0.013866, 0.003922, 0.002267, 0.001270, 0.018570, 0.007843,
0.003299, 0.002249, 0.024239, 0.011765, 0.004547, 0.003392, 0.030909, 0.015686, 0.006006,
0.004692, 0.038558, 0.019608, 0.007676, 0.006136, 0.046836, 0.023529, 0.009561, 0.007713,
0.055143, 0.027451, 0.011663, 0.009417, 0.063460, 0.031373, 0.013995, 0.011225, 0.071862,
0.035294, 0.016561, 0.013136, 0.080282, 0.039216, 0.019373, 0.015133, 0.088767, 0.043137,
0.022447, 0.017199, 0.097327, 0.047059, 0.025793, 0.019331, 0.105930, 0.050980, 0.029432,
0.021503, 0.114621, 0.054902, 0.033385, 0.023702, 0.123397, 0.058824, 0.037668, 0.025921,
0.132232, 0.062745, 0.042253, 0.028139, 0.141141, 0.066667, 0.046915, 0.030324, 0.150164,
0.070588, 0.051644, 0.032474, 0.159254, 0.074510, 0.056449, 0.034569, 0.168414, 0.078431,
0.061340, 0.036590, 0.177642, 0.082353, 0.066331, 0.038504, 0.186962, 0.086275, 0.071429,
0.040294, 0.196354, 0.090196, 0.076637, 0.041905, 0.205799, 0.094118, 0.081962, 0.043328,
0.215289, 0.098039, 0.087411, 0.044556, 0.224813, 0.101961, 0.092990, 0.045583, 0.234358,
0.105882, 0.098702, 0.046402, 0.243904, 0.109804, 0.104551, 0.047008, 0.253430, 0.113725,
0.110536, 0.047399, 0.262912, 0.117647, 0.116656, 0.047574, 0.272321, 0.121569, 0.122908,
0.047536, 0.281624, 0.125490, 0.129285, 0.047293, 0.290788, 0.129412, 0.135778, 0.046856,
0.299776, 0.133333, 0.142378, 0.046242, 0.308553, 0.137255, 0.149073, 0.045468, 0.317085,
0.141176, 0.155850, 0.044559, 0.325338, 0.145098, 0.162689, 0.043554, 0.333277, 0.149020,
0.169575, 0.042489, 0.340874, 0.152941, 0.176493, 0.041402, 0.348111, 0.156863, 0.183429,
0.040329, 0.354971, 0.160784, 0.190367, 0.039309, 0.361447, 0.164706, 0.197297, 0.038400,
0.367535, 0.168627, 0.204209, 0.037632, 0.373238, 0.172549, 0.211095, 0.037030, 0.378563,
0.176471, 0.217949, 0.036615, 0.383522, 0.180392, 0.224763, 0.036405, 0.388129, 0.184314,
0.231538, 0.036405, 0.392400, 0.188235, 0.238273, 0.036621, 0.396353, 0.192157, 0.244967,
0.037055, 0.400007, 0.196078, 0.251620, 0.037705, 0.403378, 0.200000, 0.258234, 0.038571,
0.406485, 0.203922, 0.264810, 0.039647, 0.409345, 0.207843, 0.271347, 0.040922, 0.411976,
0.211765, 0.277850, 0.042353, 0.414392, 0.215686, 0.284321, 0.043933, 0.416608, 0.219608,
0.290763, 0.045644, 0.418637, 0.223529, 0.297178, 0.047470, 0.420491, 0.227451, 0.303568,
0.049396, 0.422182, 0.231373, 0.309935, 0.051407, 0.423721, 0.235294, 0.316282, 0.053490,
0.425116, 0.239216, 0.322610, 0.055634, 0.426377, 0.243137, 0.328921, 0.057827, 0.427511,
0.247059, 0.335217, 0.060060, 0.428524, 0.250980, 0.341500, 0.062325, 0.429425, 0.254902,
0.347771, 0.064616, 0.430217, 0.258824, 0.354032, 0.066925, 0.430906, 0.262745, 0.360284,
0.069247, 0.431497, 0.266667, 0.366529, 0.071579, 0.431994, 0.270588, 0.372768, 0.073915,
0.432400, 0.274510, 0.379001, 0.076253, 0.432719, 0.278431, 0.385228, 0.078591, 0.432955,
0.282353, 0.391453, 0.080927, 0.433109, 0.286275, 0.397674, 0.083257, 0.433183, 0.290196,
0.403894, 0.085580, 0.433179, 0.294118, 0.410113, 0.087896, 0.433098, 0.298039, 0.416331,
0.090203, 0.432943, 0.301961, 0.422549, 0.092501, 0.432714, 0.305882, 0.428768, 0.094790,
0.432412, 0.309804, 0.434987, 0.097069, 0.432039, 0.313725, 0.441207, 0.099338, 0.431594,
0.317647, 0.447428, 0.101597, 0.431080, 0.321569, 0.453651, 0.103848, 0.430498, 0.325490,
0.459875, 0.106089, 0.429846, 0.329412, 0.466100, 0.108322, 0.429125, 0.333333, 0.472328,
0.110547, 0.428334, 0.337255, 0.478558, 0.112764, 0.427475, 0.341176, 0.484789, 0.114974,
0.426548, 0.345098, 0.491022, 0.117179, 0.425552, 0.349020, 0.497257, 0.119379, 0.424488,
0.352941, 0.503493, 0.121575, 0.423356, 0.356863, 0.509730, 0.123769, 0.422156, 0.360784,
0.515967, 0.125960, 0.420887, 0.364706, 0.522206, 0.128150, 0.419549, 0.368627, 0.528444,
0.130341, 0.418142, 0.372549, 0.534683, 0.132534, 0.416667, 0.376471, 0.540920, 0.134729,
0.415123, 0.380392, 0.547157, 0.136929, 0.413511, 0.384314, 0.553392, 0.139134, 0.411829,
0.388235, 0.559624, 0.141346, 0.410078, 0.392157, 0.565854, 0.143567, 0.408258, 0.396078,
0.572081, 0.145797, 0.406369, 0.400000, 0.578304, 0.148039, 0.404411, 0.403922, 0.584521,
0.150294, 0.402385, 0.407843, 0.590734, 0.152563, 0.400290, 0.411765, 0.596940, 0.154848,
0.398125, 0.415686, 0.603139, 0.157151, 0.395891, 0.419608, 0.609330, 0.159474, 0.393589,
0.423529, 0.615513, 0.161817, 0.391219, 0.427451, 0.621685, 0.164184, 0.388781, 0.431373,
0.627847, 0.166575, 0.386276, 0.435294, 0.633998, 0.168992, 0.383704, 0.439216, 0.640135,
0.171438, 0.381065, 0.443137, 0.646260, 0.173914, 0.378359, 0.447059, 0.652369, 0.176421,
0.375586, 0.450980, 0.658463, 0.178962, 0.372748, 0.454902, 0.664540, 0.181539, 0.369846,
0.458824, 0.670599, 0.184153, 0.366879, 0.462745, 0.676638, 0.186807, 0.363849, 0.466667,
0.682656, 0.189501, 0.360757, 0.470588, 0.688653, 0.192239, 0.357603, 0.474510, 0.694627,
0.195021, 0.354388, 0.478431, 0.700576, 0.197851, 0.351113, 0.482353, 0.706500, 0.200728,
0.347777, 0.486275, 0.712396, 0.203656, 0.344383, 0.490196, 0.718264, 0.206636, 0.340931,
0.494118, 0.724103, 0.209670, 0.337424, 0.498039, 0.729909, 0.212759, 0.333861, 0.501961,
0.735683, 0.215906, 0.330245, 0.505882, 0.741423, 0.219112, 0.326576, 0.509804, 0.747127,
0.222378, 0.322856, 0.513725, 0.752794, 0.225706, 0.319085, 0.517647, 0.758422, 0.229097,
0.315266, 0.521569, 0.764010, 0.232554, 0.311399, 0.525490, 0.769556, 0.236077, 0.307485,
0.529412, 0.775059, 0.239667, 0.303526, 0.533333, 0.780517, 0.243327, 0.299523, 0.537255,
0.785929, 0.247056, 0.295477, 0.541176, 0.791293, 0.250856, 0.291390, 0.545098, 0.796607,
0.254728, 0.287264, 0.549020, 0.801871, 0.258674, 0.283099, 0.552941, 0.807082, 0.262692,
0.278898, 0.556863, 0.812239, 0.266786, 0.274661, 0.560784, 0.817341, 0.270954, 0.270390,
0.564706, 0.822386, 0.275197, 0.266085, 0.568627, 0.827372, 0.279517, 0.261750, 0.572549,
0.832299, 0.283913, 0.257383, 0.576471, 0.837165, 0.288385, 0.252988, 0.580392, 0.841969,
0.292933, 0.248564, 0.584314, 0.846709, 0.297559, 0.244113, 0.588235, 0.851384, 0.302260,
0.239636, 0.592157, 0.855992, 0.307038, 0.235133, 0.596078, 0.860533, 0.311892, 0.230606,
0.600000, 0.865006, 0.316822, 0.226055, 0.603922, 0.869409, 0.321827, 0.221482, 0.607843,
0.873741, 0.326906, 0.216886, 0.611765, 0.878001, 0.332060, 0.212268, 0.615686, 0.882188,
0.337287, 0.207628, 0.619608, 0.886302, 0.342586, 0.202968, 0.623529, 0.890341, 0.347957,
0.198286, 0.627451, 0.894305, 0.353399, 0.193584, 0.631373, 0.898192, 0.358911, 0.188860,
0.635294, 0.902003, 0.364492, 0.184116, 0.639216, 0.905735, 0.370140, 0.179350, 0.643137,
0.909390, 0.375856, 0.174563, 0.647059, 0.912966, 0.381636, 0.169755, 0.650980, 0.916462,
0.387481, 0.164924, 0.654902, 0.919879, 0.393389, 0.160070, 0.658824, 0.923215, 0.399359,
0.155193, 0.662745, 0.926470, 0.405389, 0.150292, 0.666667, 0.929644, 0.411479, 0.145367,
0.670588, 0.932737, 0.417627, 0.140417, 0.674510, 0.935747, 0.423831, 0.135440, 0.678431,
0.938675, 0.430091, 0.130438, 0.682353, 0.941521, 0.436405, 0.125409, 0.686275, 0.944285,
0.442772, 0.120354, 0.690196, 0.946965, 0.449191, 0.115272, 0.694118, 0.949562, 0.455660,
0.110164, 0.698039, 0.952075, 0.462178, 0.105031, 0.701961, 0.954506, 0.468744, 0.099874,
0.705882, 0.956852, 0.475356, 0.094695, 0.709804, 0.959114, 0.482014, 0.089499, 0.713725,
0.961293, 0.488716, 0.084289, 0.717647, 0.963387, 0.495462, 0.079073, 0.721569, 0.965397,
0.502249, 0.073859, 0.725490, 0.967322, 0.509078, 0.068659, 0.729412, 0.969163, 0.515946,
0.063488, 0.733333, 0.970919, 0.522853, 0.058367, 0.737255, 0.972590, 0.529798, 0.053324,
0.741176, 0.974176, 0.536780, 0.048392, 0.745098, 0.975677, 0.543798, 0.043618, 0.749020,
0.977092, 0.550850, 0.039050, 0.752941, 0.978422, 0.557937, 0.034931, 0.756863, 0.979666,
0.565057, 0.031409, 0.760784, 0.980824, 0.572209, 0.028508, 0.764706, 0.981895, 0.579392,
0.026250, 0.768627, 0.982881, 0.586606, 0.024661, 0.772549, 0.983779, 0.593849, 0.023770,
0.776471, 0.984591, 0.601122, 0.023606, 0.780392, 0.985315, 0.608422, 0.024202, 0.784314,
0.985952, 0.615750, 0.025592, 0.788235, 0.986502, 0.623105, 0.027814, 0.792157, 0.986964,
0.630485, 0.030908, 0.796078, 0.987337, 0.637890, 0.034916, 0.800000, 0.987622, 0.645320,
0.039886, 0.803922, 0.987819, 0.652773, 0.045581, 0.807843, 0.987926, 0.660250, 0.051750,
0.811765, 0.987945, 0.667748, 0.058329, 0.815686, 0.987874, 0.675267, 0.065257, 0.819608,
0.987714, 0.682807, 0.072489, 0.823529, 0.987464, 0.690366, 0.079990, 0.827451, 0.987124,
0.697944, 0.087731, 0.831373, 0.986694, 0.705540, 0.095694, 0.835294, 0.986175, 0.713153,
0.103863, 0.839216, 0.985566, 0.720782, 0.112229, 0.843137, 0.984865, 0.728427, 0.120785,
0.847059, 0.984075, 0.736087, 0.129527, 0.850980, 0.983196, 0.743758, 0.138453, 0.854902,
0.982228, 0.751442, 0.147565, 0.858824, 0.981173, 0.759135, 0.156863, 0.862745, 0.980032,
0.766837, 0.166353, 0.866667, 0.978806, 0.774545, 0.176037, 0.870588, 0.977497, 0.782258,
0.185923, 0.874510, 0.976108, 0.789974, 0.196018, 0.878431, 0.974638, 0.797692, 0.206332,
0.882353, 0.973088, 0.805409, 0.216877, 0.886275, 0.971468, 0.813122, 0.227658, 0.890196,
0.969783, 0.820825, 0.238686, 0.894118, 0.968041, 0.828515, 0.249972, 0.898039, 0.966243,
0.836191, 0.261534, 0.901961, 0.964394, 0.843848, 0.273391, 0.905882, 0.962517, 0.851476,
0.285546, 0.909804, 0.960626, 0.859069, 0.298010, 0.913725, 0.958720, 0.866624, 0.310820,
0.917647, 0.956834, 0.874129, 0.323974, 0.921569, 0.954997, 0.881569, 0.337475, 0.925490,
0.953215, 0.888942, 0.351369, 0.929412, 0.951546, 0.896226, 0.365627, 0.933333, 0.950018,
0.903409, 0.380271, 0.937255, 0.948683, 0.910473, 0.395289, 0.941176, 0.947594, 0.917399,
0.410665, 0.945098, 0.946809, 0.924168, 0.426373, 0.949020, 0.946392, 0.930761, 0.442367,
0.952941, 0.946403, 0.937159, 0.458592, 0.956863, 0.946903, 0.943348, 0.474970, 0.960784,
0.947937, 0.949318, 0.491426, 0.964706, 0.949545, 0.955063, 0.507860, 0.968627, 0.951740,
0.960587, 0.524203, 0.972549, 0.954529, 0.965896, 0.540361, 0.976471, 0.957896, 0.971003,
0.556275, 0.980392, 0.961812, 0.975924, 0.571925, 0.984314, 0.966249, 0.980678, 0.587206,
0.988235, 0.971162, 0.985282, 0.602154, 0.992157, 0.976511, 0.989753, 0.616760, 0.996078,
0.982257, 0.994109, 0.631017, 1.000000, 0.988362, 0.998364, 0.644924
}
};
static constexpr ColorTable<22> LinearYGB = {
vtkm::cont::ColorSpace::LAB,
{ 0, 1, 0.988235, 0.968627,
0.02, 1, 0.952941, 0.878431,
0.05, 0.968627, 0.905882, 0.776471,
0.1, 0.94902, 0.898039, 0.6470590000000001,
0.15, 0.901961, 0.878431, 0.556863,
0.2, 0.847059, 0.858824, 0.482353,
0.25, 0.690196, 0.819608, 0.435294,
0.3, 0.513725, 0.7686269999999999, 0.384314,
0.35, 0.337255, 0.721569, 0.337255,
0.4, 0.278431, 0.658824, 0.392157,
0.45, 0.231373, 0.639216, 0.435294,
0.5, 0.203922, 0.6, 0.486275,
0.55, 0.172549, 0.568627, 0.537255,
0.6, 0.141176, 0.517647, 0.54902,
0.65, 0.133333, 0.458824, 0.541176,
0.7, 0.12549, 0.396078, 0.529412,
0.75, 0.117647, 0.321569, 0.5215689999999999,
0.8, 0.121569, 0.258824, 0.509804,
0.85, 0.133333, 0.227451, 0.501961,
0.9, 0.145098, 0.192157, 0.490196,
0.95, 0.188235, 0.164706, 0.470588,
1, 0.258824, 0.196078, 0.439216
}
};
static constexpr ColorTable<5> ColdAndHot = {
vtkm::cont::ColorSpace::RGB,
{ 0, 0, 1, 1,
0.45, 0, 0, 1,
0.5, 0, 0, 0.501960784314,
0.55, 1, 0, 0,
1, 1, 1, 0
}
};
static constexpr ColorTable<8> RainbowDesaturated = {
vtkm::cont::ColorSpace::RGB,
{ 0, 0.278431372549, 0.278431372549, 0.858823529412,
0.143, 0, 0, 0.360784313725,
0.285, 0, 1, 1,
0.429, 0, 0.501960784314, 0,
0.571, 1, 1, 0,
0.714, 1, 0.380392156863, 0,
0.857, 0.419607843137, 0, 0,
1, 0.8784313725489999, 0.301960784314, 0.301960784314
}
};
static constexpr ColorTable<35> CoolToWarmExtended = {
vtkm::cont::ColorSpace::LAB,
{ 0, 0, 0, 0.34902,
0.03125, 0.039216, 0.062745, 0.380392,
0.0625, 0.062745, 0.117647, 0.411765,
0.09375, 0.090196, 0.184314, 0.45098,
0.125, 0.12549, 0.262745, 0.501961,
0.15625, 0.160784, 0.337255, 0.541176,
0.1875, 0.2, 0.396078, 0.568627,
0.21875, 0.239216, 0.454902, 0.6,
0.25, 0.286275, 0.5215689999999999, 0.65098,
0.28125, 0.337255, 0.592157, 0.7019609999999999,
0.3125, 0.388235, 0.654902, 0.74902,
0.34375, 0.466667, 0.737255, 0.819608,
0.375, 0.572549, 0.819608, 0.878431,
0.40625, 0.654902, 0.866667, 0.9098039999999999,
0.4375, 0.752941, 0.917647, 0.941176,
0.46875, 0.823529, 0.956863, 0.968627,
0.5, 0.988235, 0.960784, 0.901961,
0.5, 0.941176, 0.984314, 0.988235,
0.52, 0.988235, 0.945098, 0.85098,
0.54, 0.980392, 0.898039, 0.784314,
0.5625, 0.968627, 0.835294, 0.698039,
0.59375, 0.94902, 0.733333, 0.588235,
0.625, 0.929412, 0.65098, 0.509804,
0.65625, 0.9098039999999999, 0.564706, 0.435294,
0.6875, 0.878431, 0.458824, 0.352941,
0.71875, 0.839216, 0.388235, 0.286275,
0.75, 0.760784, 0.294118, 0.211765,
0.78125, 0.7019609999999999, 0.211765, 0.168627,
0.8125, 0.65098, 0.156863, 0.129412,
0.84375, 0.6, 0.09411799999999999, 0.09411799999999999,
0.875, 0.54902, 0.066667, 0.098039,
0.90625, 0.501961, 0.05098, 0.12549,
0.9375, 0.45098, 0.054902, 0.172549,
0.96875, 0.4, 0.054902, 0.192157,
1, 0.34902, 0.070588, 0.211765
}
};
static constexpr ColorTable<2> XRay = {
vtkm::cont::ColorSpace::RGB,
{ 0, 1, 1, 1,
1, 0, 0, 0
}
};
static constexpr ColorTable<4> BlackBlueWhite = {
vtkm::cont::ColorSpace::RGB,
{ 0, 0, 0, 0,
0.333, 0, 0, 0.501960784314,
0.666, 0, 0.501960784314, 1,
1, 1, 1, 1
}
};
static constexpr ColorTable<21> LinearGreen = {
vtkm::cont::ColorSpace::LAB,
{ 0, 0.054901999999999999, 0.109804, 0.121569, 0.050000000000000003,
0.074510000000000007, 0.17254900000000001, 0.180392, 0.10000000000000001,
0.086275000000000004, 0.231373, 0.219608, 0.14999999999999999,
0.094117999999999993, 0.27843099999999998, 0.25097999999999998,
0.20000000000000001, 0.109804, 0.34902, 0.27843099999999998, 0.25,
0.11372500000000001, 0.40000000000000002, 0.27843099999999998,
0.29999999999999999, 0.117647, 0.45097999999999999, 0.270588,
0.34999999999999998, 0.117647, 0.49019600000000002, 0.24313699999999999,
0.40000000000000002, 0.11372500000000001, 0.52156899999999995,
0.20392199999999999, 0.45000000000000001, 0.109804, 0.54901999999999995,
0.15294099999999999, 0.5, 0.082352999999999996, 0.58823499999999995,
0.082352999999999996, 0.55000000000000004, 0.109804, 0.63137299999999996,
0.050979999999999998, 0.59999999999999998, 0.21176500000000001,
0.67843100000000001, 0.082352999999999996, 0.65000000000000002,
0.31764700000000001, 0.72156900000000002, 0.11372500000000001,
0.69999999999999996, 0.43137300000000001, 0.76078400000000002,
0.16078400000000001, 0.75, 0.556863, 0.80000000000000004,
0.23921600000000001, 0.80000000000000004, 0.66666700000000001,
0.83921599999999996, 0.29411799999999999, 0.84999999999999998,
0.78431399999999996, 0.87843099999999996, 0.39607799999999999,
0.90000000000000002, 0.88627500000000003, 0.92156899999999997,
0.53333299999999995, 0.94999999999999996, 0.96078399999999997,
0.94901999999999997, 0.67058799999999996, 1, 1, 0.98431400000000002,
0.90196100000000001
}
};
static constexpr ColorTable<256> Virdis =
{
vtkm::cont::ColorSpace::LAB,
{ 0.000000, 0.267004, 0.004874, 0.329415, 0.003922, 0.268510, 0.009605, 0.335427, 0.007843,
0.269944, 0.014625, 0.341379, 0.011765, 0.271305, 0.019942, 0.347269, 0.015686, 0.272594,
0.025563, 0.353093, 0.019608, 0.273809, 0.031497, 0.358853, 0.023529, 0.274952, 0.037752,
0.364543, 0.027451, 0.276022, 0.044167, 0.370164, 0.031373, 0.277018, 0.050344, 0.375715,
0.035294, 0.277941, 0.056324, 0.381191, 0.039216, 0.278791, 0.062145, 0.386592, 0.043137,
0.279566, 0.067836, 0.391917, 0.047059, 0.280267, 0.073417, 0.397163, 0.050980, 0.280894,
0.078907, 0.402329, 0.054902, 0.281446, 0.084320, 0.407414, 0.058824, 0.281924, 0.089666,
0.412415, 0.062745, 0.282327, 0.094955, 0.417331, 0.066667, 0.282656, 0.100196, 0.422160,
0.070588, 0.282910, 0.105393, 0.426902, 0.074510, 0.283091, 0.110553, 0.431554, 0.078431,
0.283197, 0.115680, 0.436115, 0.082353, 0.283229, 0.120777, 0.440584, 0.086275, 0.283187,
0.125848, 0.444960, 0.090196, 0.283072, 0.130895, 0.449241, 0.094118, 0.282884, 0.135920,
0.453427, 0.098039, 0.282623, 0.140926, 0.457517, 0.101961, 0.282290, 0.145912, 0.461510,
0.105882, 0.281887, 0.150881, 0.465405, 0.109804, 0.281412, 0.155834, 0.469201, 0.113725,
0.280868, 0.160771, 0.472899, 0.117647, 0.280255, 0.165693, 0.476498, 0.121569, 0.279574,
0.170599, 0.479997, 0.125490, 0.278826, 0.175490, 0.483397, 0.129412, 0.278012, 0.180367,
0.486697, 0.133333, 0.277134, 0.185228, 0.489898, 0.137255, 0.276194, 0.190074, 0.493001,
0.141176, 0.275191, 0.194905, 0.496005, 0.145098, 0.274128, 0.199721, 0.498911, 0.149020,
0.273006, 0.204520, 0.501721, 0.152941, 0.271828, 0.209303, 0.504434, 0.156863, 0.270595,
0.214069, 0.507052, 0.160784, 0.269308, 0.218818, 0.509577, 0.164706, 0.267968, 0.223549,
0.512008, 0.168627, 0.266580, 0.228262, 0.514349, 0.172549, 0.265145, 0.232956, 0.516599,
0.176471, 0.263663, 0.237631, 0.518762, 0.180392, 0.262138, 0.242286, 0.520837, 0.184314,
0.260571, 0.246922, 0.522828, 0.188235, 0.258965, 0.251537, 0.524736, 0.192157, 0.257322,
0.256130, 0.526563, 0.196078, 0.255645, 0.260703, 0.528312, 0.200000, 0.253935, 0.265254,
0.529983, 0.203922, 0.252194, 0.269783, 0.531579, 0.207843, 0.250425, 0.274290, 0.533103,
0.211765, 0.248629, 0.278775, 0.534556, 0.215686, 0.246811, 0.283237, 0.535941, 0.219608,
0.244972, 0.287675, 0.537260, 0.223529, 0.243113, 0.292092, 0.538516, 0.227451, 0.241237,
0.296485, 0.539709, 0.231373, 0.239346, 0.300855, 0.540844, 0.235294, 0.237441, 0.305202,
0.541921, 0.239216, 0.235526, 0.309527, 0.542944, 0.243137, 0.233603, 0.313828, 0.543914,
0.247059, 0.231674, 0.318106, 0.544834, 0.250980, 0.229739, 0.322361, 0.545706, 0.254902,
0.227802, 0.326594, 0.546532, 0.258824, 0.225863, 0.330805, 0.547314, 0.262745, 0.223925,
0.334994, 0.548053, 0.266667, 0.221989, 0.339161, 0.548752, 0.270588, 0.220057, 0.343307,
0.549413, 0.274510, 0.218130, 0.347432, 0.550038, 0.278431, 0.216210, 0.351535, 0.550627,
0.282353, 0.214298, 0.355619, 0.551184, 0.286275, 0.212395, 0.359683, 0.551710, 0.290196,
0.210503, 0.363727, 0.552206, 0.294118, 0.208623, 0.367752, 0.552675, 0.298039, 0.206756,
0.371758, 0.553117, 0.301961, 0.204903, 0.375746, 0.553533, 0.305882, 0.203063, 0.379716,
0.553925, 0.309804, 0.201239, 0.383670, 0.554294, 0.313725, 0.199430, 0.387607, 0.554642,
0.317647, 0.197636, 0.391528, 0.554969, 0.321569, 0.195860, 0.395433, 0.555276, 0.325490,
0.194100, 0.399323, 0.555565, 0.329412, 0.192357, 0.403199, 0.555836, 0.333333, 0.190631,
0.407061, 0.556089, 0.337255, 0.188923, 0.410910, 0.556326, 0.341176, 0.187231, 0.414746,
0.556547, 0.345098, 0.185556, 0.418570, 0.556753, 0.349020, 0.183898, 0.422383, 0.556944,
0.352941, 0.182256, 0.426184, 0.557120, 0.356863, 0.180629, 0.429975, 0.557282, 0.360784,
0.179019, 0.433756, 0.557430, 0.364706, 0.177423, 0.437527, 0.557565, 0.368627, 0.175841,
0.441290, 0.557685, 0.372549, 0.174274, 0.445044, 0.557792, 0.376471, 0.172719, 0.448791,
0.557885, 0.380392, 0.171176, 0.452530, 0.557965, 0.384314, 0.169646, 0.456262, 0.558030,
0.388235, 0.168126, 0.459988, 0.558082, 0.392157, 0.166617, 0.463708, 0.558119, 0.396078,
0.165117, 0.467423, 0.558141, 0.400000, 0.163625, 0.471133, 0.558148, 0.403922, 0.162142,
0.474838, 0.558140, 0.407843, 0.160665, 0.478540, 0.558115, 0.411765, 0.159194, 0.482237,
0.558073, 0.415686, 0.157729, 0.485932, 0.558013, 0.419608, 0.156270, 0.489624, 0.557936,
0.423529, 0.154815, 0.493313, 0.557840, 0.427451, 0.153364, 0.497000, 0.557724, 0.431373,
0.151918, 0.500685, 0.557587, 0.435294, 0.150476, 0.504369, 0.557430, 0.439216, 0.149039,
0.508051, 0.557250, 0.443137, 0.147607, 0.511733, 0.557049, 0.447059, 0.146180, 0.515413,
0.556823, 0.450980, 0.144759, 0.519093, 0.556572, 0.454902, 0.143343, 0.522773, 0.556295,
0.458824, 0.141935, 0.526453, 0.555991, 0.462745, 0.140536, 0.530132, 0.555659, 0.466667,
0.139147, 0.533812, 0.555298, 0.470588, 0.137770, 0.537492, 0.554906, 0.474510, 0.136408,
0.541173, 0.554483, 0.478431, 0.135066, 0.544853, 0.554029, 0.482353, 0.133743, 0.548535,
0.553541, 0.486275, 0.132444, 0.552216, 0.553018, 0.490196, 0.131172, 0.555899, 0.552459,
0.494118, 0.129933, 0.559582, 0.551864, 0.498039, 0.128729, 0.563265, 0.551229, 0.501961,
0.127568, 0.566949, 0.550556, 0.505882, 0.126453, 0.570633, 0.549841, 0.509804, 0.125394,
0.574318, 0.549086, 0.513725, 0.124395, 0.578002, 0.548287, 0.517647, 0.123463, 0.581687,
0.547445, 0.521569, 0.122606, 0.585371, 0.546557, 0.525490, 0.121831, 0.589055, 0.545623,
0.529412, 0.121148, 0.592739, 0.544641, 0.533333, 0.120565, 0.596422, 0.543611, 0.537255,
0.120092, 0.600104, 0.542530, 0.541176, 0.119738, 0.603785, 0.541400, 0.545098, 0.119512,
0.607464, 0.540218, 0.549020, 0.119423, 0.611141, 0.538982, 0.552941, 0.119483, 0.614817,
0.537692, 0.556863, 0.119699, 0.618490, 0.536347, 0.560784, 0.120081, 0.622161, 0.534946,
0.564706, 0.120638, 0.625828, 0.533488, 0.568627, 0.121380, 0.629492, 0.531973, 0.572549,
0.122312, 0.633153, 0.530398, 0.576471, 0.123444, 0.636809, 0.528763, 0.580392, 0.124780,
0.640461, 0.527068, 0.584314, 0.126326, 0.644107, 0.525311, 0.588235, 0.128087, 0.647749,
0.523491, 0.592157, 0.130067, 0.651384, 0.521608, 0.596078, 0.132268, 0.655014, 0.519661,
0.600000, 0.134692, 0.658636, 0.517649, 0.603922, 0.137339, 0.662252, 0.515571, 0.607843,
0.140210, 0.665859, 0.513427, 0.611765, 0.143303, 0.669459, 0.511215, 0.615686, 0.146616,
0.673050, 0.508936, 0.619608, 0.150148, 0.676631, 0.506589, 0.623529, 0.153894, 0.680203,
0.504172, 0.627451, 0.157851, 0.683765, 0.501686, 0.631373, 0.162016, 0.687316, 0.499129,
0.635294, 0.166383, 0.690856, 0.496502, 0.639216, 0.170948, 0.694384, 0.493803, 0.643137,
0.175707, 0.697900, 0.491033, 0.647059, 0.180653, 0.701402, 0.488189, 0.650980, 0.185783,
0.704891, 0.485273, 0.654902, 0.191090, 0.708366, 0.482284, 0.658824, 0.196571, 0.711827,
0.479221, 0.662745, 0.202219, 0.715272, 0.476084, 0.666667, 0.208030, 0.718701, 0.472873,
0.670588, 0.214000, 0.722114, 0.469588, 0.674510, 0.220124, 0.725509, 0.466226, 0.678431,
0.226397, 0.728888, 0.462789, 0.682353, 0.232815, 0.732247, 0.459277, 0.686275, 0.239374,
0.735588, 0.455688, 0.690196, 0.246070, 0.738910, 0.452024, 0.694118, 0.252899, 0.742211,
0.448284, 0.698039, 0.259857, 0.745492, 0.444467, 0.701961, 0.266941, 0.748751, 0.440573,
0.705882, 0.274149, 0.751988, 0.436601, 0.709804, 0.281477, 0.755203, 0.432552, 0.713725,
0.288921, 0.758394, 0.428426, 0.717647, 0.296479, 0.761561, 0.424223, 0.721569, 0.304148,
0.764704, 0.419943, 0.725490, 0.311925, 0.767822, 0.415586, 0.729412, 0.319809, 0.770914,
0.411152, 0.733333, 0.327796, 0.773980, 0.406640, 0.737255, 0.335885, 0.777018, 0.402049,
0.741176, 0.344074, 0.780029, 0.397381, 0.745098, 0.352360, 0.783011, 0.392636, 0.749020,
0.360741, 0.785964, 0.387814, 0.752941, 0.369214, 0.788888, 0.382914, 0.756863, 0.377779,
0.791781, 0.377939, 0.760784, 0.386433, 0.794644, 0.372886, 0.764706, 0.395174, 0.797475,
0.367757, 0.768627, 0.404001, 0.800275, 0.362552, 0.772549, 0.412913, 0.803041, 0.357269,
0.776471, 0.421908, 0.805774, 0.351910, 0.780392, 0.430983, 0.808473, 0.346476, 0.784314,
0.440137, 0.811138, 0.340967, 0.788235, 0.449368, 0.813768, 0.335384, 0.792157, 0.458674,
0.816363, 0.329727, 0.796078, 0.468053, 0.818921, 0.323998, 0.800000, 0.477504, 0.821444,
0.318195, 0.803922, 0.487026, 0.823929, 0.312321, 0.807843, 0.496615, 0.826376, 0.306377,
0.811765, 0.506271, 0.828786, 0.300362, 0.815686, 0.515992, 0.831158, 0.294279, 0.819608,
0.525776, 0.833491, 0.288127, 0.823529, 0.535621, 0.835785, 0.281908, 0.827451, 0.545524,
0.838039, 0.275626, 0.831373, 0.555484, 0.840254, 0.269281, 0.835294, 0.565498, 0.842430,
0.262877, 0.839216, 0.575563, 0.844566, 0.256415, 0.843137, 0.585678, 0.846661, 0.249897,
0.847059, 0.595839, 0.848717, 0.243329, 0.850980, 0.606045, 0.850733, 0.236712, 0.854902,
0.616293, 0.852709, 0.230052, 0.858824, 0.626579, 0.854645, 0.223353, 0.862745, 0.636902,
0.856542, 0.216620, 0.866667, 0.647257, 0.858400, 0.209861, 0.870588, 0.657642, 0.860219,
0.203082, 0.874510, 0.668054, 0.861999, 0.196293, 0.878431, 0.678489, 0.863742, 0.189503,
0.882353, 0.688944, 0.865448, 0.182725, 0.886275, 0.699415, 0.867117, 0.175971, 0.890196,
0.709898, 0.868751, 0.169257, 0.894118, 0.720391, 0.870350, 0.162603, 0.898039, 0.730889,
0.871916, 0.156029, 0.901961, 0.741388, 0.873449, 0.149561, 0.905882, 0.751884, 0.874951,
0.143228, 0.909804, 0.762373, 0.876424, 0.137064, 0.913725, 0.772852, 0.877868, 0.131109,
0.917647, 0.783315, 0.879285, 0.125405, 0.921569, 0.793760, 0.880678, 0.120005, 0.925490,
0.804182, 0.882046, 0.114965, 0.929412, 0.814576, 0.883393, 0.110347, 0.933333, 0.824940,
0.884720, 0.106217, 0.937255, 0.835270, 0.886029, 0.102646, 0.941176, 0.845561, 0.887322,
0.099702, 0.945098, 0.855810, 0.888601, 0.097452, 0.949020, 0.866013, 0.889868, 0.095953,
0.952941, 0.876168, 0.891125, 0.095250, 0.956863, 0.886271, 0.892374, 0.095374, 0.960784,
0.896320, 0.893616, 0.096335, 0.964706, 0.906311, 0.894855, 0.098125, 0.968627, 0.916242,
0.896091, 0.100717, 0.972549, 0.926106, 0.897330, 0.104071, 0.976471, 0.935904, 0.898570,
0.108131, 0.980392, 0.945636, 0.899815, 0.112838, 0.984314, 0.955300, 0.901065, 0.118128,
0.988235, 0.964894, 0.902323, 0.123941, 0.992157, 0.974417, 0.903590, 0.130215, 0.996078,
0.983868, 0.904867, 0.136897, 1.000000, 0.993248, 0.906157, 0.143936
}
};
static constexpr ColorTable<7> Jet = {
vtkm::cont::ColorSpace::RGB,
{ -1, 0, 0, 0.5625,
-0.777778, 0,0,1,
-0.269841, 0, 1, 1,
-0.015873, 0.5, 1, 0.5,
0.238095, 1, 1, 0,
0.746032, 1, 0, 0,
1, 0.5, 0, 0
}
};
static constexpr ColorTable<5> Rainbow = {
vtkm::cont::ColorSpace::RGB,
{ -1, 0, 0, 1,
-0.5, 0, 1, 1,
0, 0, 1, 0,
0.5, 1, 1, 0,
1, 1, 0, 0
}
};
// clang-format on
void loadCoolToWarm(vtkm::cont::ColorTable& table)
{
table.FillColorTableFromDataPointer(CoolToWarm.size, CoolToWarm.values);
table.SetColorSpace(CoolToWarm.space);
table.SetNaNColor(vtkm::Vec<float, 3>{ 1.0f, 1.0f, 0.0f });
}
void loadBlackBody(vtkm::cont::ColorTable& table)
{
table.FillColorTableFromDataPointer(BlackBody.size, BlackBody.values);
table.SetColorSpace(BlackBody.space);
table.SetNaNColor(vtkm::Vec<float, 3>{ 0.0f, 0.49803921f, 1.0f });
}
void loadSamselFire(vtkm::cont::ColorTable& table)
{
table.FillColorTableFromDataPointer(SamselFire.size, SamselFire.values);
table.SetColorSpace(SamselFire.space);
table.SetNaNColor(vtkm::Vec<float, 3>{ 1.0f, 1.0f, 0.0f });
}
void loadInferno(vtkm::cont::ColorTable& table)
{
table.FillColorTableFromDataPointer(Inferno.size, Inferno.values);
table.SetColorSpace(Inferno.space);
table.SetNaNColor(vtkm::Vec<float, 3>{ 0.0f, 1.0f, 0.0f });
}
void loadLinearYGB(vtkm::cont::ColorTable& table)
{
table.FillColorTableFromDataPointer(LinearYGB.size, LinearYGB.values);
table.SetColorSpace(LinearYGB.space);
table.SetNaNColor(vtkm::Vec<float, 3>{ 0.25f, 0.0f, 0.0f });
}
void loadColdAndHot(vtkm::cont::ColorTable& table)
{
table.FillColorTableFromDataPointer(ColdAndHot.size, ColdAndHot.values);
table.SetColorSpace(ColdAndHot.space);
table.SetNaNColor(vtkm::Vec<float, 3>{ 1.0f, 1.0f, 0.0f });
}
void loadRainbowDesaturated(vtkm::cont::ColorTable& table)
{
table.FillColorTableFromDataPointer(RainbowDesaturated.size, RainbowDesaturated.values);
table.SetColorSpace(RainbowDesaturated.space);
table.SetNaNColor(vtkm::Vec<float, 3>{ 1.0f, 1.0f, 0.0f });
}
void loadCoolToWarmExtended(vtkm::cont::ColorTable& table)
{
table.FillColorTableFromDataPointer(CoolToWarmExtended.size, CoolToWarmExtended.values);
table.SetColorSpace(CoolToWarmExtended.space);
table.SetNaNColor(vtkm::Vec<float, 3>{ 0.25f, 0.0f, 0.0f });
}
void loadXRay(vtkm::cont::ColorTable& table)
{
table.FillColorTableFromDataPointer(XRay.size, XRay.values);
table.SetColorSpace(XRay.space);
table.SetNaNColor(vtkm::Vec<float, 3>{ 1.0f, 0.0f, 0.0f });
}
void loadBlackBlueWhite(vtkm::cont::ColorTable& table)
{
table.FillColorTableFromDataPointer(BlackBlueWhite.size, BlackBlueWhite.values);
table.SetColorSpace(BlackBlueWhite.space);
table.SetNaNColor(vtkm::Vec<float, 3>{ 1.0f, 1.0f, 0.0f });
}
void loadVirdis(vtkm::cont::ColorTable& table)
{
table.FillColorTableFromDataPointer(Virdis.size, Virdis.values);
table.SetColorSpace(Virdis.space);
table.SetNaNColor(vtkm::Vec<float, 3>{ 1.0f, 0.0f, 0.0f });
}
void loadLinearGreen(vtkm::cont::ColorTable& table)
{
table.FillColorTableFromDataPointer(LinearGreen.size, LinearGreen.values);
table.SetColorSpace(LinearGreen.space);
table.SetNaNColor(vtkm::Vec<float, 3>{ 0.25f, 0.0f, 0.0f });
}
void loadJet(vtkm::cont::ColorTable& table)
{
table.FillColorTableFromDataPointer(Jet.size, Jet.values);
table.SetColorSpace(Jet.space);
}
void loadRainbow(vtkm::cont::ColorTable& table)
{
table.FillColorTableFromDataPointer(Rainbow.size, Rainbow.values);
table.SetColorSpace(Rainbow.space);
}
struct LoadColorTablePresetCommand
{
using FunctionType = void (*)(vtkm::cont::ColorTable& table);
std::string name;
FunctionType function;
};
constexpr int numberOfPresets = 14;
struct LoadColorTablePresetCommand presets[numberOfPresets] = {
{ "cool to warm", loadCoolToWarm },
{ "black-body radiation", loadBlackBody },
{ "samsel fire", loadSamselFire },
{ "inferno", loadInferno },
{ "linear ygb", loadLinearYGB },
{ "cold and hot", loadColdAndHot },
{ "rainbow desaturated", loadRainbowDesaturated },
{ "cool to warm (extended)", loadCoolToWarmExtended },
{ "x ray", loadXRay },
{ "black, blue and white", loadBlackBlueWhite },
{ "virdis", loadVirdis },
{ "linear green", loadLinearGreen },
{ "jet", loadJet },
{ "rainbow", loadRainbow },
};
}
namespace vtkm
{
namespace cont
{
namespace detail
{
VTKM_CONT_EXPORT std::set<std::string> GetPresetNames()
{
std::set<std::string> names;
for (int i = 0; i < numberOfPresets; ++i)
{
names.insert(presets[i].name);
}
return names;
}
VTKM_CONT_EXPORT bool loadColorTablePreset(std::string name, vtkm::cont::ColorTable& table)
{
//convert to lower case
std::transform(name.begin(), name.end(), name.begin(), [](char c) {
return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
});
for (int i = 0; i < numberOfPresets; ++i)
{
if (name == presets[i].name)
{
presets[i].function(table);
return true;
}
}
return false;
}
}
}
}

@ -53,7 +53,7 @@ namespace internal
template <typename ControlSignatureTag>
struct ControlSignatureTagCheck
{
static VTKM_CONSTEXPR bool Valid =
static constexpr bool Valid =
std::is_base_of<vtkm::cont::arg::ControlSignatureTagBase, ControlSignatureTag>::value;
};

@ -46,7 +46,7 @@ struct TypeCheck
/// The static constant boolean \c value is set to \c true if the type is
/// valid for the given check tag and \c false otherwise.
///
static const bool value = false;
static constexpr bool value = false;
};
}
}

@ -51,13 +51,13 @@ struct TypeCheckArrayValueType;
template <typename TypeList, typename ArrayType>
struct TypeCheckArrayValueType<TypeList, ArrayType, true>
{
static const bool value = vtkm::ListContains<TypeList, typename ArrayType::ValueType>::value;
static constexpr bool value = vtkm::ListContains<TypeList, typename ArrayType::ValueType>::value;
};
template <typename TypeList, typename ArrayType>
struct TypeCheckArrayValueType<TypeList, ArrayType, false>
{
static const bool value = false;
static constexpr bool value = false;
};
} // namespace detail
@ -65,7 +65,7 @@ struct TypeCheckArrayValueType<TypeList, ArrayType, false>
template <typename TypeList, typename ArrayType>
struct TypeCheck<TypeCheckTagArray<TypeList>, ArrayType>
{
static const bool value = detail::TypeCheckArrayValueType<
static constexpr bool value = detail::TypeCheckArrayValueType<
TypeList,
ArrayType,
vtkm::cont::internal::ArrayHandleCheck<ArrayType>::type::value>::value;

@ -49,15 +49,15 @@ struct TypeCheckTagAtomicArray
template <typename TypeList, typename ArrayType>
struct TypeCheck<TypeCheckTagAtomicArray<TypeList>, ArrayType>
{
static const bool value = false;
static constexpr bool value = false;
};
template <typename T, typename TypeList>
struct TypeCheck<TypeCheckTagAtomicArray<TypeList>,
vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic>>
{
static const bool value = (vtkm::ListContains<TypeList, T>::value &&
vtkm::ListContains<vtkm::exec::AtomicArrayTypeListTag, T>::value);
static constexpr bool value = (vtkm::ListContains<TypeList, T>::value &&
vtkm::ListContains<vtkm::exec::AtomicArrayTypeListTag, T>::value);
};
}
}

@ -40,7 +40,7 @@ struct TypeCheckTagCellSet
template <typename CellSetType>
struct TypeCheck<TypeCheckTagCellSet, CellSetType>
{
static const bool value = vtkm::cont::internal::CellSetCheck<CellSetType>::type::value;
static constexpr bool value = vtkm::cont::internal::CellSetCheck<CellSetType>::type::value;
};
}
}

@ -45,7 +45,8 @@ struct TypeCheck<TypeCheckTagCellSetStructured, CellSetType>
using is_2d_cellset = std::is_same<CellSetType, vtkm::cont::CellSetStructured<2>>;
using is_1d_cellset = std::is_same<CellSetType, vtkm::cont::CellSetStructured<1>>;
static const bool value = is_3d_cellset::value || is_2d_cellset::value || is_1d_cellset::value;
static constexpr bool value =
is_3d_cellset::value || is_2d_cellset::value || is_1d_cellset::value;
};
}
}

@ -46,7 +46,7 @@ struct TypeCheckTagExecObject
template <typename Type>
struct TypeCheck<TypeCheckTagExecObject, Type>
{
static VTKM_CONSTEXPR bool value = std::is_base_of<vtkm::exec::ExecutionObjectBase, Type>::value;
static constexpr bool value = std::is_base_of<vtkm::exec::ExecutionObjectBase, Type>::value;
};
}
}

@ -41,7 +41,7 @@ struct TypeCheckTagKeys
template <typename Type>
struct TypeCheck<TypeCheckTagKeys, Type>
{
static const bool value = false;
static constexpr bool value = false;
};
}
}

@ -30,7 +30,7 @@
namespace
{
static const vtkm::Id ARRAY_SIZE = 10;
static constexpr vtkm::Id ARRAY_SIZE = 10;
template <typename PortalType>
struct TestKernelIn : public vtkm::exec::FunctorBase

@ -30,7 +30,7 @@
namespace
{
static const vtkm::Id ARRAY_SIZE = 10;
static constexpr vtkm::Id ARRAY_SIZE = 10;
template <typename PortalType>
struct TestKernelInOut : public vtkm::exec::FunctorBase

@ -31,7 +31,7 @@
namespace
{
static const vtkm::Id ARRAY_SIZE = 10;
static constexpr vtkm::Id ARRAY_SIZE = 10;
template <typename PortalType>
struct TestKernelOut : public vtkm::exec::FunctorBase

@ -34,7 +34,7 @@
namespace
{
static const vtkm::Id ARRAY_SIZE = 10;
static constexpr vtkm::Id ARRAY_SIZE = 10;
#define OFFSET 10

@ -28,8 +28,10 @@ VTKM_THIRDPARTY_POST_INCLUDE
// These static vars are in an anon namespace to work around MSVC linker issues.
namespace
{
#if CUDART_VERSION >= 8000
// Has CudaAllocator::Initialize been called?
static bool IsInitialized = false;
#endif
// True if all devices support concurrent pagable managed memory.
static bool ManagedMemorySupported = false;
@ -183,6 +185,7 @@ void CudaAllocator::PrepareForInPlace(const void* ptr, std::size_t numBytes)
void CudaAllocator::Initialize()
{
#if CUDART_VERSION >= 8000
if (!IsInitialized)
{
int numDevices;
@ -209,6 +212,9 @@ void CudaAllocator::Initialize()
ManagedMemorySupported = managed;
IsInitialized = true;
}
#else
ManagedMemorySupported = false;
#endif
}
}
}

@ -163,7 +163,7 @@ public:
// 3. cudaErrorNoKernelImageForDevice we built for a compute version
// greater than the device we are running on
// Most likely others that I don't even know about
vtkm::cont::cuda::internal::DetermineIfValidCudaDevice<<<1, 1>>>();
vtkm::cont::cuda::internal::DetermineIfValidCudaDevice<<<1, 1, 0, cudaStreamPerThread>>>();
if (cudaSuccess != cudaGetLastError())
{
numDevices = 0;

@ -80,14 +80,18 @@ struct VirtualObjectTransfer<VirtualDerivedType, vtkm::cont::DeviceAdapterTagCud
// will be wrong.
VirtualDerivedType* deviceTarget;
VTKM_CUDA_CALL(cudaMalloc(&deviceTarget, sizeof(VirtualDerivedType)));
VTKM_CUDA_CALL(cudaMemcpy(
deviceTarget, this->ControlObject, sizeof(VirtualDerivedType), cudaMemcpyHostToDevice));
VTKM_CUDA_CALL(cudaMemcpyAsync(deviceTarget,
this->ControlObject,
sizeof(VirtualDerivedType),
cudaMemcpyHostToDevice,
cudaStreamPerThread));
// Allocate memory for the object that will eventually be a correct copy on the device.
VTKM_CUDA_CALL(cudaMalloc(&this->ExecutionObject, sizeof(VirtualDerivedType)));
// Initialize the device object
detail::ConstructVirtualObjectKernel<<<1, 1>>>(this->ExecutionObject, deviceTarget);
detail::ConstructVirtualObjectKernel<<<1, 1, 0, cudaStreamPerThread>>>(this->ExecutionObject,
deviceTarget);
VTKM_CUDA_CHECK_ASYNCHRONOUS_ERROR();
// Clean up intermediate copy
@ -99,11 +103,15 @@ struct VirtualObjectTransfer<VirtualDerivedType, vtkm::cont::DeviceAdapterTagCud
// will be wrong.
VirtualDerivedType* deviceTarget;
VTKM_CUDA_CALL(cudaMalloc(&deviceTarget, sizeof(VirtualDerivedType)));
VTKM_CUDA_CALL(cudaMemcpy(
deviceTarget, this->ControlObject, sizeof(VirtualDerivedType), cudaMemcpyHostToDevice));
VTKM_CUDA_CALL(cudaMemcpyAsync(deviceTarget,
this->ControlObject,
sizeof(VirtualDerivedType),
cudaMemcpyHostToDevice,
cudaStreamPerThread));
// Initialize the device object
detail::UpdateVirtualObjectKernel<<<1, 1>>>(this->ExecutionObject, deviceTarget);
detail::UpdateVirtualObjectKernel<<<1, 1, 0, cudaStreamPerThread>>>(this->ExecutionObject,
deviceTarget);
VTKM_CUDA_CHECK_ASYNCHRONOUS_ERROR();
// Clean up intermediate copy
@ -121,7 +129,7 @@ struct VirtualObjectTransfer<VirtualDerivedType, vtkm::cont::DeviceAdapterTagCud
{
if (this->ExecutionObject != nullptr)
{
detail::DeleteVirtualObjectKernel<<<1, 1>>>(this->ExecutionObject);
detail::DeleteVirtualObjectKernel<<<1, 1, 0, cudaStreamPerThread>>>(this->ExecutionObject);
VTKM_CUDA_CALL(cudaFree(this->ExecutionObject));
this->ExecutionObject = nullptr;
}

@ -23,6 +23,7 @@ set(unit_tests
UnitTestCudaArrayHandleVirtualCoordinates.cu
UnitTestCudaCellLocatorTwoLevelUniformGrid.cu
UnitTestCudaComputeRange.cu
UnitTestCudaColorTable.cu
UnitTestCudaDataSetExplicit.cu
UnitTestCudaDataSetSingleType.cu
UnitTestCudaDeviceAdapter.cu

@ -0,0 +1,33 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
// Make sure that the tested code is using the device adapter specified. This
// is important in the long run so we don't, for example, use the CUDA device
// for a part of an operation where the TBB device was specified.
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_ERROR
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/testing/TestingColorTable.h>
int UnitTestCudaColorTable(int, char* [])
{
return vtkm::cont::testing::TestingColorTable<vtkm::cont::DeviceAdapterTagCuda>::Run();
}

@ -430,7 +430,7 @@ public:
// Don't bother with the keys_output if it's an ArrayHandleDiscard -- there
// will be a runtime exception in Unique() otherwise:
if (!vtkm::cont::IsArrayHandleDiscard<KeysOutputType>::Value)
if (!vtkm::cont::IsArrayHandleDiscard<KeysOutputType>::value)
{
//find all the unique keys
DerivedAlgorithm::Copy(keys, keys_output);

@ -47,7 +47,7 @@ struct DeviceAdapterTraits;
template <typename DeviceAdapter>
struct DeviceAdapterTagCheck
{
static const bool Valid = false;
static constexpr bool Valid = false;
};
}
}
@ -68,12 +68,12 @@ struct DeviceAdapterTagCheck
{ \
static DeviceAdapterId GetId() { return DeviceAdapterId(Id); } \
static DeviceAdapterNameType GetName() { return DeviceAdapterNameType(#Name); } \
static const bool Valid = true; \
static constexpr bool Valid = true; \
}; \
template <> \
struct DeviceAdapterTagCheck<vtkm::cont::DeviceAdapterTag##Name> \
{ \
static const bool Valid = true; \
static constexpr bool Valid = true; \
}; \
} \
}
@ -94,12 +94,12 @@ struct DeviceAdapterTagCheck
{ \
static DeviceAdapterId GetId() { return DeviceAdapterId(Id); } \
static DeviceAdapterNameType GetName() { return DeviceAdapterNameType(#Name); } \
static const bool Valid = false; \
static constexpr bool Valid = false; \
}; \
template <> \
struct DeviceAdapterTagCheck<vtkm::cont::DeviceAdapterTag##Name> \
{ \
static const bool Valid = false; \
static constexpr bool Valid = false; \
}; \
} \
}

@ -116,6 +116,20 @@ void CastAndCall(const vtkm::cont::CellSetPermutation<PermutationType, CellSetTy
f(cellset, std::forward<Args>(args)...);
}
/// CastAndCall if the condition is true.
template <typename... Args>
void ConditionalCastAndCall(std::true_type, Args&&... args)
{
vtkm::cont::CastAndCall(std::forward<Args>(args)...);
}
/// No-op variant since the condition is false.
template <typename... Args>
void ConditionalCastAndCall(std::false_type, Args&&...)
{
}
namespace internal
{

@ -29,7 +29,7 @@ namespace
template <typename T>
struct TemplatedTests
{
static const vtkm::Id ARRAY_SIZE = 10;
static constexpr vtkm::Id ARRAY_SIZE = 10;
using ValueType = T;
using ComponentType = typename vtkm::VecTraits<ValueType>::ComponentType;
@ -76,7 +76,7 @@ struct TemplatedTests
{
ValueType array[ARRAY_SIZE];
static const ComponentType ORIGINAL_VALUE = 109;
constexpr ComponentType ORIGINAL_VALUE = 109;
FillIterator(array, array + ARRAY_SIZE, ORIGINAL_VALUE);
::vtkm::cont::internal::ArrayPortalFromIterators<ValueType*> portal(array, array + ARRAY_SIZE);
@ -124,7 +124,7 @@ struct TemplatedTests
VTKM_TEST_ASSERT(CheckPortal(const_portal, ORIGINAL_VALUE),
"Const portal iterator has bad value.");
static const ComponentType SET_VALUE = 62;
constexpr ComponentType SET_VALUE = 62;
std::cout << " Check get/set methods." << std::endl;
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)

@ -39,7 +39,7 @@ namespace vtkm
template <>
struct VecTraits<std::string>
{
static const vtkm::IdComponent NUM_COMPONENTS = 1;
static constexpr vtkm::IdComponent NUM_COMPONENTS = 1;
using HasMultipleComponents = vtkm::VecTraitsTagSingleComponent;
};

@ -31,7 +31,7 @@ namespace
template <typename T>
struct TemplatedTests
{
static const vtkm::Id ARRAY_SIZE = 10;
static constexpr vtkm::Id ARRAY_SIZE = 10;
using ValueType = T;
using ComponentType = typename vtkm::VecTraits<ValueType>::ComponentType;

@ -433,7 +433,7 @@ public:
const BinaryCompare& binary_compare)
{
internal::WrappedBinaryOperator<bool, BinaryCompare> wrappedCompare(binary_compare);
VTKM_CONSTEXPR bool larger_than_64bits = sizeof(U) > sizeof(vtkm::Int64);
constexpr bool larger_than_64bits = sizeof(U) > sizeof(vtkm::Int64);
if (larger_than_64bits)
{
/// More efficient sort:

@ -24,6 +24,7 @@ set(unit_tests
UnitTestSerialArrayHandleVirtualCoordinates.cxx
UnitTestSerialCellLocatorTwoLevelUniformGrid.cxx
UnitTestSerialComputeRange.cxx
UnitTestSerialColorTable.cxx
UnitTestSerialDataSetExplicit.cxx
UnitTestSerialDataSetSingleType.cxx
UnitTestSerialDeviceAdapter.cxx

@ -0,0 +1,33 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
// Make sure that the tested code is using the device adapter specified. This
// is important in the long run so we don't, for example, use the CUDA device
// for a part of an operation where the TBB device was specified.
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_ERROR
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
#include <vtkm/cont/testing/TestingColorTable.h>
int UnitTestSerialColorTable(int, char* [])
{
return vtkm::cont::testing::TestingColorTable<vtkm::cont::DeviceAdapterTagSerial>::Run();
}

@ -50,7 +50,7 @@ void DeviceAdapterAlgorithm<vtkm::cont::DeviceAdapterTagTBB>::ScheduleTask(
vtkm::exec::tbb::internal::TaskTiling3D& functor,
vtkm::Id3 size)
{
static const vtkm::UInt32 TBB_GRAIN_SIZE_3D[3] = { 1, 4, 256 };
static constexpr vtkm::UInt32 TBB_GRAIN_SIZE_3D[3] = { 1, 4, 256 };
const vtkm::Id MESSAGE_SIZE = 1024;
char errorString[MESSAGE_SIZE];
errorString[0] = '\0';

@ -88,7 +88,7 @@ using WrappedBinaryOperator = vtkm::cont::internal::WrappedBinaryOperator<Result
// The "grain size" of scheduling with TBB. Not a lot of thought has gone
// into picking this size.
static const vtkm::Id TBB_GRAIN_SIZE = 1024;
static constexpr vtkm::Id TBB_GRAIN_SIZE = 1024;
template <typename InputPortalType, typename OutputPortalType>
struct CopyBody

@ -686,7 +686,7 @@ private:
size_t max_elems_;
int max_threads_;
static const size_t kOutBufferSize = internal::kOutBufferSize;
static constexpr size_t kOutBufferSize = internal::kOutBufferSize;
ValueType *original_, *tmp_;
ValueType *src_, *dst_;
ValueType*** out_buf_;

@ -195,7 +195,7 @@ void parallel_sort_bykey(vtkm::cont::ArrayHandle<T, StorageT>& keys,
PSortTag)
{
using KeyType = vtkm::cont::ArrayHandle<T, StorageT>;
VTKM_CONSTEXPR bool larger_than_64bits = sizeof(U) > sizeof(vtkm::Int64);
constexpr bool larger_than_64bits = sizeof(U) > sizeof(vtkm::Int64);
if (larger_than_64bits)
{
/// More efficient sort:

@ -72,7 +72,7 @@ class quick_sort_range : private no_assign
}
public:
static const size_t grainsize = 500;
static constexpr size_t grainsize = 500;
const Compare& comp;
RandomAccessIterator begin;
size_t size;

@ -31,17 +31,17 @@
namespace kx
{
static const int kRadixBits = 8;
static const size_t kInsertSortThreshold = 64;
static const int kRadixMask = (1 << kRadixBits) - 1;
static const int kRadixBin = 1 << kRadixBits;
static constexpr int kRadixBits = 8;
static constexpr size_t kInsertSortThreshold = 64;
static constexpr int kRadixMask = (1 << kRadixBits) - 1;
static constexpr int kRadixBin = 1 << kRadixBits;
//================= HELPING FUNCTIONS ====================
template <class T>
struct RadixTraitsUnsigned
{
static const int nBytes = sizeof(T);
static constexpr int nBytes = sizeof(T);
int kth_byte(const T& x, int k) { return (x >> (kRadixBits * k)) & kRadixMask; }
bool compare(const T& x, const T& y) { return x < y; }
};
@ -49,7 +49,7 @@ struct RadixTraitsUnsigned
template <class T>
struct RadixTraitsSigned
{
static const int nBytes = sizeof(T);
static constexpr int nBytes = sizeof(T);
static const T kMSB = T(0x80) << ((sizeof(T) - 1) * 8);
int kth_byte(const T& x, int k) { return ((x ^ kMSB) >> (kRadixBits * k)) & kRadixMask; }
bool compare(const T& x, const T& y) { return x < y; }

@ -23,6 +23,7 @@ set(unit_tests
UnitTestTBBArrayHandleFancy.cxx
UnitTestTBBArrayHandleVirtualCoordinates.cxx
UnitTestTBBCellLocatorTwoLevelUniformGrid.cxx
UnitTestTBBColorTable.cxx
UnitTestTBBComputeRange.cxx
UnitTestTBBDataSetExplicit.cxx
UnitTestTBBDataSetSingleType.cxx

@ -0,0 +1,33 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
// Make sure that the tested code is using the device adapter specified. This
// is important in the long run so we don't, for example, use the CUDA device
// for a part of an operation where the TBB device was specified.
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_ERROR
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
#include <vtkm/cont/testing/TestingColorTable.h>
int UnitTestTBBColorTable(int, char* [])
{
return vtkm::cont::testing::TestingColorTable<vtkm::cont::DeviceAdapterTagTBB>::Run();
}

@ -25,6 +25,7 @@ set(headers
TestingArrayHandles.h
TestingArrayHandleVirtualCoordinates.h
TestingCellLocatorTwoLevelUniformGrid.h
TestingColorTable.h
TestingComputeRange.h
TestingDeviceAdapter.h
TestingDataSetExplicit.h

@ -322,7 +322,7 @@ inline vtkm::cont::DataSet MakeTestDataSet::Make3DRegularDataSet0()
dataSet.AddField(make_Field(
"cellvar", vtkm::cont::Field::ASSOC_CELL_SET, "cells", cellvar, 4, vtkm::CopyFlag::On));
static const vtkm::IdComponent dim = 3;
static constexpr vtkm::IdComponent dim = 3;
vtkm::cont::CellSetStructured<dim> cellSet("cells");
cellSet.SetPointDimensions(vtkm::make_Vec(3, 2, 3));
dataSet.AddCellSet(cellSet);
@ -349,7 +349,7 @@ inline vtkm::cont::DataSet MakeTestDataSet::Make3DRegularDataSet1()
dataSet.AddField(make_Field(
"cellvar", vtkm::cont::Field::ASSOC_CELL_SET, "cells", cellvar, 1, vtkm::CopyFlag::On));
static const vtkm::IdComponent dim = 3;
static constexpr vtkm::IdComponent dim = 3;
vtkm::cont::CellSetStructured<dim> cellSet("cells");
cellSet.SetPointDimensions(vtkm::make_Vec(2, 2, 2));
dataSet.AddCellSet(cellSet);

@ -75,7 +75,7 @@ private:
static void TestAll()
{
using PointType = vtkm::Vec<vtkm::FloatDefault, 3>;
static const vtkm::Id length = 64;
static constexpr vtkm::Id length = 64;
vtkm::cont::ArrayHandle<PointType> out;

@ -132,7 +132,7 @@ struct TestingArrayHandles
};
private:
static const vtkm::Id ARRAY_SIZE = 100;
static constexpr vtkm::Id ARRAY_SIZE = 100;
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapterTag>;

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

@ -31,7 +31,7 @@ namespace
// need to ensure we instatiate each algorithm in a source
// file to verify compilation.
//
static const vtkm::Id ARRAY_SIZE = 10;
static constexpr vtkm::Id ARRAY_SIZE = 10;
void CopyTest()
{

@ -28,7 +28,7 @@
namespace
{
static const vtkm::Id ARRAY_SIZE = 10;
static constexpr vtkm::Id ARRAY_SIZE = 10;
template <typename PortalType>
void TestValues(const PortalType& portal)

@ -38,8 +38,8 @@ namespace UnitTestArrayHandleDiscardDetail
template <typename ValueType>
struct Test
{
static const vtkm::Id ARRAY_SIZE = 100;
static const vtkm::Id NUM_KEYS = 3;
static constexpr vtkm::Id ARRAY_SIZE = 100;
static constexpr vtkm::Id NUM_KEYS = 3;
using DeviceTag = vtkm::cont::DeviceAdapterTagSerial;
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceTag>;

@ -30,7 +30,7 @@ namespace
template <typename T>
struct TemplatedTests
{
static const vtkm::Id ARRAY_SIZE = 10;
static constexpr vtkm::Id ARRAY_SIZE = 10;
using ValueType = T;
using ComponentType = typename vtkm::VecTraits<ValueType>::ComponentType;

Some files were not shown because too many files have changed in this diff Show More