Commit 376b3042 authored by Haocheng LIU's avatar Haocheng LIU Committed by Kitware Robot

Merge topic 'Create-warp-by-Vector-workletAndFilter'

a4c4c193 Add a warpVector worklet and filter
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Merge-request: !1268
parents 776d0854 a4c4c193
# Add a warp vector worklet and filter
This commit adds a worklet that modifies point coordinates by moving points
along point normals by the scalar amount. It's a simpified version of the
vtkWarpScalar in VTK. Additionally the filter doesn't modify the point coordinates,
but creates a new point coordinates that have been warped.
Useful for showing flow profiles or mechanical deformation.
......@@ -63,6 +63,7 @@ set(headers
Triangulate.h
VectorMagnitude.h
VertexClustering.h
WarpVector.h
)
set(header_template_sources
......@@ -105,6 +106,7 @@ set(header_template_sources
Triangulate.hxx
VectorMagnitude.hxx
VertexClustering.hxx
WarpVector.hxx
)
vtkm_declare_headers(${headers}
......
//============================================================================
// 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_filter_WarpVector_h
#define vtk_m_filter_WarpVector_h
#include <vtkm/filter/FilterField.h>
#include <vtkm/worklet/WarpVector.h>
namespace vtkm
{
namespace filter
{
/// \brief Modify points by moving points along a vector then timing
/// the scale factor
///
/// A functor that modify point coordinates by moving points along a vector
/// then timing a scale factor. It's a VTK-m version of the vtkWarpVector in VTK.
/// Useful for showing flow profiles or mechanical deformation.
/// This worklet does not modify the input points but generate new point
/// coordinate instance that has been warped.
class WarpVector : public vtkm::filter::FilterField<WarpVector>
{
public:
VTKM_CONT
WarpVector(vtkm::FloatDefault scale);
//@{
/// Choose the primary field to operate on. In the warp op A + B *scale, A is
/// the primary field
VTKM_CONT
void SetPrimaryField(
const std::string& name,
vtkm::cont::Field::Association association = vtkm::cont::Field::Association::ANY)
{
this->SetActiveField(name, association);
}
//@}
VTKM_CONT const std::string& GetPrimaryFieldName() const { return this->GetActiveFieldName(); }
VTKM_CONT vtkm::cont::Field::Association GetPrimaryFieldAssociation() const
{
return this->GetActiveFieldAssociation();
}
//@{
/// When set to true, uses a coordinate system as the primary field instead of the one selected
/// by name. Use SetPrimaryCoordinateSystem to select which coordinate system.
VTKM_CONT
void SetUseCoordinateSystemAsPrimaryField(bool flag)
{
this->SetUseCoordinateSystemAsField(flag);
}
VTKM_CONT
bool GetUseCoordinateSystemAsPrimaryField() const
{
return this->GetUseCoordinateSystemAsField();
}
//@}
//@{
/// Select the coordinate system index to use as the primary field. This only has an effect when
/// UseCoordinateSystemAsPrimaryField is true.
VTKM_CONT
void SetPrimaryCoordinateSystem(vtkm::Id index) { this->SetActiveCoordinateSystem(index); }
VTKM_CONT
vtkm::Id GetPrimaryCoordinateSystemIndex() const
{
return this->GetActiveCoordinateSystemIndex();
}
//@}
//@{
/// Choose the vector field to operate on. In the warp op A + B *scale, B is
/// the vector field
VTKM_CONT
void SetVectorField(
const std::string& name,
vtkm::cont::Field::Association association = vtkm::cont::Field::Association::ANY)
{
this->VectorFieldName = name;
this->VectorFieldAssociation = association;
}
VTKM_CONT const std::string& GetVectorFieldName() const { return this->VectorFieldName; }
VTKM_CONT vtkm::cont::Field::Association GetVectorFieldAssociation() const
{
return this->VectorFieldAssociation;
}
//@}
template <typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
VTKM_CONT vtkm::cont::DataSet DoExecute(
const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& tag);
private:
vtkm::worklet::WarpVector Worklet;
std::string VectorFieldName;
vtkm::cont::Field::Association VectorFieldAssociation;
vtkm::FloatDefault Scale;
};
template <>
class FilterTraits<WarpVector>
{
public:
// WarpVector can only applies to Float and Double Vec3 arrays
using InputFieldTypeList = vtkm::TypeListTagFieldVec3;
};
}
}
#include <vtkm/filter/WarpVector.hxx>
#endif // vtk_m_filter_WarpVector_h
//============================================================================
// 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.
//============================================================================
#include <vtkm/filter/internal/CreateResult.h>
#include <vtkm/worklet/DispatcherMapField.h>
namespace vtkm
{
namespace filter
{
//-----------------------------------------------------------------------------
inline VTKM_CONT WarpVector::WarpVector(vtkm::FloatDefault scale)
: vtkm::filter::FilterField<WarpVector>()
, Worklet()
, VectorFieldName()
, VectorFieldAssociation(vtkm::cont::Field::Association::ANY)
, Scale(scale)
{
this->SetOutputFieldName("warpvector");
}
//-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
inline VTKM_CONT vtkm::cont::DataSet WarpVector::DoExecute(
const vtkm::cont::DataSet& inDataSet,
const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMetadata,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& device)
{
using vecType = vtkm::Vec<T, 3>;
auto vectorF = inDataSet.GetField(this->VectorFieldName, this->VectorFieldAssociation);
vtkm::cont::ArrayHandle<vecType> result;
this->Worklet.Run(field, vtkm::filter::ApplyPolicy(vectorF, policy), this->Scale, result, device);
return internal::CreateResult(inDataSet,
result,
this->GetOutputFieldName(),
fieldMetadata.GetAssociation(),
fieldMetadata.GetCellSetName());
}
}
}
......@@ -57,6 +57,7 @@ set(unit_tests
UnitTestTriangulateFilter.cxx
UnitTestVectorMagnitudeFilter.cxx
UnitTestVertexClusteringFilter.cxx
UnitTestWarpVectorFilter.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/WarpVector.h>
#include <random>
#include <vector>
namespace
{
const vtkm::Id dim = 5;
template <typename T>
vtkm::cont::DataSet MakeWarpVectorTestDataSet()
{
using vecType = vtkm::Vec<T, 3>;
vtkm::cont::DataSet dataSet;
std::vector<vecType> coordinates;
std::vector<vecType> vec1;
for (vtkm::Id j = 0; j < dim; ++j)
{
T z = static_cast<T>(j) / static_cast<T>(dim - 1);
for (vtkm::Id i = 0; i < dim; ++i)
{
T x = static_cast<T>(i) / static_cast<T>(dim - 1);
T y = (x * x + z * z) / static_cast<T>(2.0);
coordinates.push_back(vtkm::make_Vec(x, y, z));
vec1.push_back(vtkm::make_Vec(x, y, y));
}
}
dataSet.AddCoordinateSystem(
vtkm::cont::make_CoordinateSystem("coordinates", coordinates, vtkm::CopyFlag::On));
vtkm::cont::DataSetFieldAdd::AddPointField(dataSet, "vec1", vec1);
vecType vector = vtkm::make_Vec<T>(static_cast<T>(0.0), static_cast<T>(0.0), static_cast<T>(2.0));
vtkm::cont::ArrayHandleConstant<vecType> vectorAH =
vtkm::cont::make_ArrayHandleConstant(vector, dim * dim);
vtkm::cont::DataSetFieldAdd::AddPointField(dataSet, "vec2", vectorAH);
return dataSet;
}
class PolicyWarpVector : public vtkm::filter::PolicyBase<PolicyWarpVector>
{
public:
using vecType = vtkm::Vec<vtkm::FloatDefault, 3>;
struct TypeListTagWarpVectorTags
: vtkm::ListTagBase<vtkm::cont::ArrayHandleConstant<vecType>::StorageTag,
vtkm::cont::ArrayHandle<vecType>::StorageTag>
{
};
using FieldStorageList = TypeListTagWarpVectorTags;
};
void CheckResult(const vtkm::filter::WarpVector& filter, const vtkm::cont::DataSet& result)
{
VTKM_TEST_ASSERT(result.HasField("warpvector", vtkm::cont::Field::Association::POINTS),
"Output filed WarpVector is missing");
using vecType = vtkm::Vec<vtkm::FloatDefault, 3>;
vtkm::cont::ArrayHandle<vecType> outputArray;
result.GetField("warpvector", vtkm::cont::Field::Association::POINTS)
.GetData()
.CopyTo(outputArray);
auto outPortal = outputArray.GetPortalConstControl();
for (vtkm::Id j = 0; j < dim; ++j)
{
vtkm::FloatDefault z =
static_cast<vtkm::FloatDefault>(j) / static_cast<vtkm::FloatDefault>(dim - 1);
for (vtkm::Id i = 0; i < dim; ++i)
{
vtkm::FloatDefault x =
static_cast<vtkm::FloatDefault>(i) / static_cast<vtkm::FloatDefault>(dim - 1);
vtkm::FloatDefault y = (x * x + z * z) / static_cast<vtkm::FloatDefault>(2.0);
vtkm::FloatDefault targetZ = filter.GetUseCoordinateSystemAsPrimaryField()
? z + static_cast<vtkm::FloatDefault>(2 * 2)
: y + static_cast<vtkm::FloatDefault>(2 * 2);
auto point = outPortal.Get(j * dim + i);
VTKM_TEST_ASSERT(point[0] == x, "Wrong result of x value for warp vector");
VTKM_TEST_ASSERT(point[1] == y, "Wrong result of y value for warp vector");
VTKM_TEST_ASSERT(point[2] == targetZ, "Wrong result of z value for warp vector");
}
}
VTKM_TEST_ASSERT(filter.GetVectorFieldName() == "vec2", "Vector field name is wrong");
}
void TestWarpVectorFilter()
{
std::cout << "Testing WarpVector filter" << std::endl;
vtkm::cont::DataSet ds = MakeWarpVectorTestDataSet<vtkm::FloatDefault>();
vtkm::FloatDefault scale = 2;
{
std::cout << " First field as coordinates" << std::endl;
vtkm::filter::WarpVector filter(scale);
filter.SetUseCoordinateSystemAsPrimaryField(true);
filter.SetVectorField("vec2");
vtkm::cont::DataSet result = filter.Execute(ds, PolicyWarpVector());
CheckResult(filter, result);
}
{
std::cout << " First field as a vector" << std::endl;
vtkm::filter::WarpVector filter(scale);
filter.SetPrimaryField("vec1");
filter.SetVectorField("vec2");
vtkm::cont::DataSet result = filter.Execute(ds, PolicyWarpVector());
CheckResult(filter, result);
}
}
}
int UnitTestWarpVectorFilter(int, char* [])
{
return vtkm::cont::testing::Testing::Run(TestWarpVectorFilter);
}
......@@ -72,6 +72,7 @@ set(headers
ThresholdPoints.h
Triangulate.h
VertexClustering.h
WarpVector.h
WaveletCompressor.h
WorkletMapField.h
WorkletMapTopology.h
......
//============================================================================
// 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_worklet_WarpVector_h
#define vtk_m_worklet_WarpVector_h
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/VecTraits.h>
namespace vtkm
{
namespace worklet
{
// A functor that modify points by moving points along a vector
// then timing a scale factor. It's a VTK-m version of the vtkWarpVector in VTK.
// Useful for showing flow profiles or mechanical deformation.
// This worklet does not modify the input points but generate new point coordinate
// instance that has been warped.
class WarpVector
{
public:
class WarpVectorImp : public vtkm::worklet::WorkletMapField
{
public:
using ControlSignature = void(FieldIn<Vec3>, FieldIn<Vec3>, FieldOut<Vec3>);
using ExecutionSignature = _3(_1, _2);
VTKM_CONT
WarpVectorImp(vtkm::FloatDefault scale)
: Scale(scale)
{
}
VTKM_EXEC
vtkm::Vec<vtkm::FloatDefault, 3> operator()(
const vtkm::Vec<vtkm::FloatDefault, 3>& point,
const vtkm::Vec<vtkm::FloatDefault, 3>& vector) const
{
return point + this->Scale * vector;
}
template <typename T>
VTKM_EXEC vtkm::Vec<T, 3> operator()(const vtkm::Vec<T, 3>& point,
const vtkm::Vec<T, 3>& vector) const
{
return point + static_cast<T>(this->Scale) * vector;
}
private:
vtkm::FloatDefault Scale;
};
// Execute the WarpVector worklet given the points, vector and a scale factor.
// Returns:
// warped points
template <typename PointType, typename VectorType, typename ResultType, typename DeviceAdapter>
void Run(PointType point,
VectorType vector,
vtkm::FloatDefault scale,
ResultType warpedPoint,
DeviceAdapter vtkmNotUsed(adapter))
{
WarpVectorImp warpVectorImp(scale);
vtkm::worklet::DispatcherMapField<WarpVectorImp, DeviceAdapter> dispatcher(warpVectorImp);
dispatcher.Invoke(point, vector, warpedPoint);
}
};
}
} // namespace vtkm::worklet
#endif // vtk_m_worklet_WarpVector_h
......@@ -77,6 +77,7 @@ set(unit_tests
UnitTestWorkletMapTopologyUniform.cxx
UnitTestWorkletReduceByKey.cxx
UnitTestVertexClustering.cxx
UnitTestWarpVector.cxx
UnitTestWaveletCompressor.cxx
)
......
//============================================================================
// 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.
//============================================================================
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WarpVector.h>
#include <vtkm/cont/CellSetExplicit.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vector>
namespace
{
template <typename T>
vtkm::cont::DataSet MakeWarpVectorTestDataSet()
{
vtkm::cont::DataSet dataSet;
std::vector<vtkm::Vec<T, 3>> coordinates;
const vtkm::Id dim = 5;
for (vtkm::Id j = 0; j < dim; ++j)
{
T z = static_cast<T>(j) / static_cast<T>(dim - 1);
for (vtkm::Id i = 0; i < dim; ++i)
{
T x = static_cast<T>(i) / static_cast<T>(dim - 1);
T y = (x * x + z * z) / 2.0f;
coordinates.push_back(vtkm::make_Vec(x, y, z));
}
}
vtkm::Id numCells = (dim - 1) * (dim - 1);
dataSet.AddCoordinateSystem(
vtkm::cont::make_CoordinateSystem("coordinates", coordinates, vtkm::CopyFlag::On));
vtkm::cont::CellSetExplicit<> cellSet("cells");
cellSet.PrepareToAddCells(numCells, numCells * 4);
for (vtkm::Id j = 0; j < dim - 1; ++j)
{
for (vtkm::Id i = 0; i < dim - 1; ++i)
{
cellSet.AddCell(vtkm::CELL_SHAPE_QUAD,
4,
vtkm::make_Vec<vtkm::Id>(
j * dim + i, j * dim + i + 1, (j + 1) * dim + i + 1, (j + 1) * dim + i));
}
}
cellSet.CompleteAddingCells(vtkm::Id(coordinates.size()));
dataSet.AddCellSet(cellSet);
return dataSet;
}
}
void TestWarpVector()
{
using DeviceAdapter = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
std::cout << "Testing WarpVector Worklet" << std::endl;
using vecType = vtkm::Vec<vtkm::FloatDefault, 3>;
vtkm::cont::DataSet ds = MakeWarpVectorTestDataSet<vtkm::FloatDefault>();
vtkm::cont::ArrayHandle<vecType> result;
vtkm::FloatDefault scale = 2;
vecType vector = vtkm::make_Vec<vtkm::FloatDefault>(static_cast<vtkm::FloatDefault>(0.0),
static_cast<vtkm::FloatDefault>(0.0),
static_cast<vtkm::FloatDefault>(2.0));
auto coordinate = ds.GetCoordinateSystem().GetData();
vtkm::Id nov = coordinate.GetNumberOfValues();
vtkm::cont::ArrayHandleConstant<vecType> vectorAH =
vtkm::cont::make_ArrayHandleConstant(vector, nov);
vtkm::worklet::WarpVector warpWorklet;
warpWorklet.Run(ds.GetCoordinateSystem(), vectorAH, scale, result, DeviceAdapter());
auto resultPortal = result.GetPortalConstControl();
for (vtkm::Id i = 0; i < nov; i++)
{
for (vtkm::Id j = 0; j < 3; j++)
{
vtkm::FloatDefault ans =
coordinate.GetPortalConstControl().Get(i)[static_cast<vtkm::IdComponent>(j)] +
scale * vector[static_cast<vtkm::IdComponent>(j)];
VTKM_TEST_ASSERT(test_equal(ans, resultPortal.Get(i)[static_cast<vtkm::IdComponent>(j)]),
" Wrong result for WarpVector worklet");
}
}
}
int UnitTestWarpVector(int, char* [])
{
return vtkm::cont::testing::Testing::Run(TestWarpVector);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment