From 5241cab738d9cdd86b96fd5beb43d420a932eae2 Mon Sep 17 00:00:00 2001 From: Sujin Philip Date: Tue, 9 Jun 2015 11:02:17 -0400 Subject: [PATCH] Add PointElevation Worklet --- vtkm/worklet/CMakeLists.txt | 2 + vtkm/worklet/PointElevation.h | 92 +++++++++++++ vtkm/worklet/testing/CMakeLists.txt | 1 + .../testing/UnitTestPointElevation.cxx | 123 ++++++++++++++++++ 4 files changed, 218 insertions(+) create mode 100644 vtkm/worklet/PointElevation.h create mode 100644 vtkm/worklet/testing/UnitTestPointElevation.cxx diff --git a/vtkm/worklet/CMakeLists.txt b/vtkm/worklet/CMakeLists.txt index 4038f2b43..9919ca216 100644 --- a/vtkm/worklet/CMakeLists.txt +++ b/vtkm/worklet/CMakeLists.txt @@ -23,6 +23,8 @@ set(headers WorkletMapField.h DispatcherMapTopology.h WorkletMapTopology.h + CellAverage.h + PointElevation.h ) #----------------------------------------------------------------------------- diff --git a/vtkm/worklet/PointElevation.h b/vtkm/worklet/PointElevation.h new file mode 100644 index 000000000..81eee5e49 --- /dev/null +++ b/vtkm/worklet/PointElevation.h @@ -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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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_worklet_PointElevation_h +#define vtk_m_worklet_PointElevation_h + +#include + +namespace vtkm { +namespace worklet { + +namespace internal { + +template +VTKM_EXEC_EXPORT +T clamp(const T& val, const T& min, const T& max) +{ + return (val < min) ? min : ((val > max) ? max : val); +} + +} + +class PointElevation : public vtkm::worklet::WorkletMapField +{ +public: + typedef void ControlSignature(FieldIn, FieldIn, FieldIn, + FieldOut); + typedef void ExecutionSignature(_1, _2, _3, _4); + + VTKM_CONT_EXPORT + PointElevation() : LowPoint(0.0, 0.0, 0.0), HighPoint(0.0, 0.0, 1.0), + RangeLow(0.0), RangeHigh(1.0) {} + + VTKM_CONT_EXPORT + void SetLowPoint(const vtkm::Vec &point) + { + this->LowPoint = point; + } + + VTKM_CONT_EXPORT + void SetHighPoint(const vtkm::Vec &point) + { + this->HighPoint = point; + } + + VTKM_CONT_EXPORT + void SetRange(vtkm::Float64 low, vtkm::Float64 high) + { + this->RangeLow = low; + this->RangeHigh = high; + } + + template + VTKM_EXEC_EXPORT + void operator()(const T1 &x, const T2 &y, const T3 &z, T4 &elevation) const + { + vtkm::Vec direction = this->HighPoint - this->LowPoint; + vtkm::Float64 length = vtkm::dot(direction, direction); + vtkm::Float64 rangeLength = this->RangeHigh - this->RangeLow; + vtkm::Vec vec = vtkm::make_Vec(x, y, z) - + this->LowPoint; + vtkm::Float64 s = vtkm::dot(vec, direction) / length; + s = internal::clamp(s, 0.0, 1.0); + elevation = static_cast(this->RangeLow + (s * rangeLength)); + } + +private: + vtkm::Vec LowPoint, HighPoint; + vtkm::Float64 RangeLow, RangeHigh; +}; + +} +} // namespace vtkm::worklet + +#endif // vtk_m_worklet_PointElevation_h diff --git a/vtkm/worklet/testing/CMakeLists.txt b/vtkm/worklet/testing/CMakeLists.txt index eb38fdce1..02d6f724a 100644 --- a/vtkm/worklet/testing/CMakeLists.txt +++ b/vtkm/worklet/testing/CMakeLists.txt @@ -20,6 +20,7 @@ set(unit_tests UnitTestCellAverage.cxx + UnitTestPointElevation.cxx UnitTestWorkletMapField.cxx UnitTestWorkletMapFieldMultiParam.cxx UnitTestWorkletMapTopologyExplicit.cxx diff --git a/vtkm/worklet/testing/UnitTestPointElevation.cxx b/vtkm/worklet/testing/UnitTestPointElevation.cxx new file mode 100644 index 000000000..b084f906c --- /dev/null +++ b/vtkm/worklet/testing/UnitTestPointElevation.cxx @@ -0,0 +1,123 @@ +//============================================================================ +// 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 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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 +#include + +#include +#include + +#include + +namespace { + +vtkm::cont::DataSet MakePointElevationTestDataSet() +{ + vtkm::cont::DataSet ds; + + std::vector xVals, yVals, zVals; + const vtkm::Id dim = 5; + for (vtkm::Id j = 0; j < dim; ++j) + { + vtkm::Float32 z = static_cast(j) / + static_cast(dim - 1); + for (vtkm::Id i = 0; i < dim; ++i) + { + vtkm::Float32 x = static_cast(i) / + static_cast(dim - 1); + vtkm::Float32 y = (x*x + z*z)/2.0f; + xVals.push_back(x); + yVals.push_back(y); + zVals.push_back(z); + } + } + + vtkm::Id numVerts = dim * dim; + vtkm::Id numCells = (dim - 1) * (dim - 1); + ds.AddField(vtkm::cont::Field("x", 1, vtkm::cont::Field::ASSOC_POINTS, + &xVals[0], numVerts)); + ds.AddField(vtkm::cont::Field("y", 1, vtkm::cont::Field::ASSOC_POINTS, + &yVals[0], numVerts)); + ds.AddField(vtkm::cont::Field("z", 1, vtkm::cont::Field::ASSOC_POINTS, + &zVals[0], numVerts)); + ds.AddCoordinateSystem(vtkm::cont::CoordinateSystem("x","y","z")); + + boost::shared_ptr > cs( + new vtkm::cont::CellSetExplicit<>("cells", numCells)); + vtkm::cont::ExplicitConnectivity<> &ec = cs->nodesOfCellsConnectivity; + ec.PrepareToAddCells(numCells, numCells * 4); + for (vtkm::Id j = 0; j < dim - 1; ++j) + { + for (vtkm::Id i = 0; i < dim - 1; ++i) + { + ec.AddCell(vtkm::VTKM_QUAD, 4, vtkm::make_Vec(j * dim + i, + j * dim + i + 1, + (j + 1) * dim + i + 1, + (j + 1) * dim + i)); + } + } + ec.CompleteAddingCells(); + + ds.AddCellSet(cs); + return ds; +} + +} + +void TestPointElevation() +{ + std::cout << "Testing PointElevation Worklet" << std::endl; + + vtkm::cont::DataSet ds = MakePointElevationTestDataSet(); + + ds.AddField(vtkm::cont::Field("elevation", 1, vtkm::cont::Field::ASSOC_POINTS, + vtkm::Float32())); + + vtkm::worklet::PointElevation pointElevationWorklet; + pointElevationWorklet.SetLowPoint(vtkm::make_Vec(0.0, 0.0, 0.0)); + pointElevationWorklet.SetHighPoint(vtkm::make_Vec(0.0, 1.0, 0.0)); + pointElevationWorklet.SetRange(0.0, 2.0); + + vtkm::worklet::DispatcherMapField + dispatcher(pointElevationWorklet); + dispatcher.Invoke(ds.GetField("x").GetData(), + ds.GetField("y").GetData(), + ds.GetField("z").GetData(), + ds.GetField("elevation").GetData()); + + vtkm::cont::ArrayHandle yVals = + ds.GetField("y").GetData().CastToArrayHandle(vtkm::Float32(), + VTKM_DEFAULT_STORAGE_TAG()); + vtkm::cont::ArrayHandle result = + ds.GetField("elevation").GetData().CastToArrayHandle(vtkm::Float32(), + VTKM_DEFAULT_STORAGE_TAG()); + + for (vtkm::Id i = 0; i < result.GetNumberOfValues(); ++i) + { + VTKM_TEST_ASSERT(test_equal(yVals.GetPortalConstControl().Get(i) * 2.0, + result.GetPortalConstControl().Get(i)), + "Wrong result for PointElevation worklet"); + } +} + +int UnitTestPointElevation(int, char *[]) +{ + return vtkm::cont::testing::Testing::Run(TestPointElevation); +}