Consolidate WarpScalar and WarpVector filter

In reflection, the `WarpScalar` filter is surprisingly a superset of the
`WarpVector` features. `WarpScalar` has the ability to displace in the
directions of the mesh normals. In VTK, there is a distinction of normals
to vectors, but in VTK-m it is a matter of selecting the correct one. As
such, it makes little sense to have two separate implementations for the
same operation. The filters have been combined and the interface names have
been generalized for general warping (e.g., "normal" or "vector" becomes
"direction").

In addition to consolidating the implementation, the `Warp` filter
implementation has been updated to use the modern features of VTK-m's
filter base classes. In particular, when the `Warp` filters were originally
implemented, the filter base classes did not support more than one active
scalar field, so filters like `Warp` had to manage multiple fields
themselves. The `FilterField` base class now allows specifying multiple,
indexed active fields, and the updated implementation uses this to manage
the input vectors and scalars.

The `Warp` filters have also been updated to directly support constant
vectors and scalars, which is common for `WarpScalar` and `WarpVector`,
respectively. Previously, to implement a constant field, you had to add a
field containing an `ArrayHandleConstant`. This is still supported, but an
easier method of just selecting constant vectors or scalars makes this
easier.

Internally, the implementation now uses tricks with extracting array
components to support many different array types (including
`ArrayHandleConstant`. This allows it to simultaneously interact with
coordinates, directions, and scalars without creating too many template
instances.
This commit is contained in:
Kenneth Moreland 2023-08-05 13:16:13 -06:00
parent e6353ac103
commit 1f07b0ecf6
15 changed files with 571 additions and 503 deletions

@ -36,8 +36,7 @@
#include <vtkm/filter/entity_extraction/ThresholdPoints.h>
#include <vtkm/filter/field_conversion/CellAverage.h>
#include <vtkm/filter/field_conversion/PointAverage.h>
#include <vtkm/filter/field_transform/WarpScalar.h>
#include <vtkm/filter/field_transform/WarpVector.h>
#include <vtkm/filter/field_transform/Warp.h>
#include <vtkm/filter/geometry_refinement/Tetrahedralize.h>
#include <vtkm/filter/geometry_refinement/Triangulate.h>
#include <vtkm/filter/geometry_refinement/VertexClustering.h>
@ -358,10 +357,11 @@ void BenchWarpScalar(::benchmark::State& state)
const vtkm::cont::DeviceAdapterId device = Config.Device;
const bool isPartitioned = static_cast<bool>(state.range(0));
vtkm::filter::field_transform::WarpScalar filter{ 2. };
vtkm::filter::field_transform::Warp filter;
filter.SetScaleFactor(2.0f);
filter.SetUseCoordinateSystemAsField(true);
filter.SetNormalField(PointVectorsName, vtkm::cont::Field::Association::Points);
filter.SetScalarFactorField(PointScalarsName, vtkm::cont::Field::Association::Points);
filter.SetDirectionField(PointVectorsName);
filter.SetScaleField(PointScalarsName);
vtkm::cont::PartitionedDataSet input;
input = isPartitioned ? GetInputPartitionedData() : GetInputDataSet();
@ -385,9 +385,10 @@ void BenchWarpVector(::benchmark::State& state)
const vtkm::cont::DeviceAdapterId device = Config.Device;
const bool isPartitioned = static_cast<bool>(state.range(0));
vtkm::filter::field_transform::WarpVector filter{ 2. };
vtkm::filter::field_transform::Warp filter;
filter.SetScaleFactor(2.0f);
filter.SetUseCoordinateSystemAsField(true);
filter.SetVectorField(PointVectorsName, vtkm::cont::Field::Association::Points);
filter.SetDirectionField(PointVectorsName);
vtkm::cont::PartitionedDataSet input;
input = isPartitioned ? GetInputPartitionedData() : GetInputDataSet();

@ -0,0 +1,32 @@
# Consolidate WarpScalar and WarpVector filter
In reflection, the `WarpScalar` filter is surprisingly a superset of the
`WarpVector` features. `WarpScalar` has the ability to displace in the
directions of the mesh normals. In VTK, there is a distinction of normals
to vectors, but in VTK-m it is a matter of selecting the correct one. As
such, it makes little sense to have two separate implementations for the
same operation. The filters have been combined and the interface names have
been generalized for general warping (e.g., "normal" or "vector" becomes
"direction").
In addition to consolidating the implementation, the `Warp` filter
implementation has been updated to use the modern features of VTK-m's
filter base classes. In particular, when the `Warp` filters were originally
implemented, the filter base classes did not support more than one active
scalar field, so filters like `Warp` had to manage multiple fields
themselves. The `FilterField` base class now allows specifying multiple,
indexed active fields, and the updated implementation uses this to manage
the input vectors and scalars.
The `Warp` filters have also been updated to directly support constant
vectors and scalars, which is common for `WarpScalar` and `WarpVector`,
respectively. Previously, to implement a constant field, you had to add a
field containing an `ArrayHandleConstant`. This is still supported, but an
easier method of just selecting constant vectors or scalars makes this
easier.
Internally, the implementation now uses tricks with extracting array
components to support many different array types (including
`ArrayHandleConstant`. This allows it to simultaneously interact with
coordinates, directions, and scalars without creating too many template
instances.

@ -16,6 +16,7 @@ set(field_transform_headers
PointElevation.h
PointTransform.h
SphericalCoordinateTransform.h
Warp.h
WarpScalar.h
WarpVector.h
)
@ -28,8 +29,7 @@ set(field_transform_sources
PointElevation.cxx
PointTransform.cxx
SphericalCoordinateTransform.cxx
WarpScalar.cxx
WarpVector.cxx
Warp.cxx
)
set(field_transform_sources_no_device

@ -0,0 +1,248 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/StaticAssert.h>
#include <vtkm/TypeTraits.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/ArrayHandleRuntimeVec.h>
#include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/filter/field_transform/Warp.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <type_traits>
namespace
{
struct WarpWorklet : vtkm::worklet::WorkletMapField
{
vtkm::FloatDefault ScaleFactor;
VTKM_CONT explicit WarpWorklet(vtkm::FloatDefault scale)
: ScaleFactor(scale)
{
}
using ControlSignature = void(FieldIn pointCoordinates,
FieldIn directions,
FieldIn scales,
FieldOut result);
template <typename PointType, typename DirectionType, typename ScaleType, typename ResultType>
VTKM_EXEC void operator()(const PointType& point,
const DirectionType& direction,
ScaleType scale,
ResultType& result) const
{
vtkm::IdComponent numComponents = result.GetNumberOfComponents();
VTKM_ASSERT(point.GetNumberOfComponents() == numComponents);
VTKM_ASSERT(direction.GetNumberOfComponents() == numComponents);
result = direction;
result *= scale * this->ScaleFactor;
result += point;
}
};
// The warp filter operates on 3 arrays: coordiantes, directions, and scale factors. Rather than
// try to satisfy every possible array type we expect, which would add to a lot of possibilities
// (especially because we add the constant varieties), we will just extract components as either
// `vtkm::Float32` or `vtkm::Float64`. That way for each we just need just 6 combinations. We can
// do this by extracting arrays by components using `UnknownArrayHandle`'s
// `ExtractArrayFromComponents`.
template <typename Functor>
VTKM_CONT void CastAndCallExtractedArrayFloats(const vtkm::cont::UnknownArrayHandle& array,
Functor&& functor)
{
if (array.IsBaseComponentType<vtkm::Float32>())
{
functor(array.ExtractArrayFromComponents<vtkm::Float32>());
}
else if (array.IsBaseComponentType<vtkm::Float64>())
{
functor(array.ExtractArrayFromComponents<vtkm::Float64>());
}
else
{
// Array is not float. Copy it to a float array and call the functor.
vtkm::cont::ArrayHandleRuntimeVec<vtkm::FloatDefault> arrayCopy{
array.GetNumberOfComponentsFlat()
};
vtkm::cont::ArrayCopy(array, arrayCopy);
// We could call the functor directly on arrayCopy. But that would add a third
// type of array. We would like to limit it to 2 types. Thus, stuff the known
// array into its own `UnknownArrayHandle` and get an extracted array that will
// match the others.
vtkm::cont::UnknownArrayHandle arrayCopyContainer = arrayCopy;
functor(arrayCopyContainer.ExtractArrayFromComponents<vtkm::FloatDefault>());
}
}
template <typename T1, typename T2>
struct BiggerTypeImpl
{
VTKM_STATIC_ASSERT(
(std::is_same<typename vtkm::TypeTraits<T1>::NumericTag, vtkm::TypeTraitsRealTag>::value));
VTKM_STATIC_ASSERT(
(std::is_same<typename vtkm::TypeTraits<T2>::NumericTag, vtkm::TypeTraitsRealTag>::value));
VTKM_STATIC_ASSERT((std::is_same<typename vtkm::TypeTraits<T1>::DimensionalityTag,
vtkm::TypeTraitsScalarTag>::value));
VTKM_STATIC_ASSERT((std::is_same<typename vtkm::TypeTraits<T2>::DimensionalityTag,
vtkm::TypeTraitsScalarTag>::value));
using type = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
};
template <typename T1, typename T2>
using BiggerType = typename BiggerTypeImpl<T1, T2>::type;
template <typename CoordinateType, typename DirectionType, typename ScalarFactorType>
VTKM_CONT vtkm::cont::UnknownArrayHandle ComputeWarp(
const vtkm::cont::Invoker& invoke,
const vtkm::cont::ArrayHandleRecombineVec<CoordinateType>& points,
const vtkm::cont::ArrayHandleRecombineVec<DirectionType>& directions,
const vtkm::cont::ArrayHandleRecombineVec<ScalarFactorType>& scales,
vtkm::FloatDefault scaleFactor)
{
vtkm::IdComponent numComponents = points.GetNumberOfComponents();
if (directions.GetNumberOfComponents() != numComponents)
{
throw vtkm::cont::ErrorBadValue(
"Number of components for points and directions does not agree.");
}
if (scales.GetNumberOfComponents() != 1)
{
throw vtkm::cont::ErrorBadValue("ScaleField must be scalars, but they are not.");
}
auto scalarFactorsComponents = scales.GetComponentArray(0);
using ResultType = BiggerType<BiggerType<CoordinateType, DirectionType>, ScalarFactorType>;
vtkm::cont::ArrayHandleRuntimeVec<ResultType> result{ numComponents };
invoke(WarpWorklet{ scaleFactor }, points, directions, scalarFactorsComponents, result);
return result;
}
template <typename CoordinateType, typename DirectionType>
VTKM_CONT vtkm::cont::UnknownArrayHandle ComputeWarp(
const vtkm::cont::Invoker& invoke,
const vtkm::cont::ArrayHandleRecombineVec<CoordinateType>& points,
const vtkm::cont::ArrayHandleRecombineVec<DirectionType>& directions,
const vtkm::cont::UnknownArrayHandle& scales,
vtkm::FloatDefault scaleFactor)
{
vtkm::cont::UnknownArrayHandle result;
auto functor = [&](auto concrete) {
result = ComputeWarp(invoke, points, directions, concrete, scaleFactor);
};
CastAndCallExtractedArrayFloats(scales, functor);
return result;
}
template <typename CoordinateType>
VTKM_CONT vtkm::cont::UnknownArrayHandle ComputeWarp(
const vtkm::cont::Invoker& invoke,
const vtkm::cont::ArrayHandleRecombineVec<CoordinateType>& points,
const vtkm::cont::UnknownArrayHandle& directions,
const vtkm::cont::UnknownArrayHandle& scales,
vtkm::FloatDefault scaleFactor)
{
vtkm::cont::UnknownArrayHandle result;
auto functor = [&](auto concrete) {
result = ComputeWarp(invoke, points, concrete, scales, scaleFactor);
};
CastAndCallExtractedArrayFloats(directions, functor);
return result;
}
VTKM_CONT vtkm::cont::UnknownArrayHandle ComputeWarp(
const vtkm::cont::Invoker& invoke,
const vtkm::cont::UnknownArrayHandle& points,
const vtkm::cont::UnknownArrayHandle& directions,
const vtkm::cont::UnknownArrayHandle& scales,
vtkm::FloatDefault scaleFactor)
{
vtkm::cont::UnknownArrayHandle result;
auto functor = [&](auto concrete) {
result = ComputeWarp(invoke, concrete, directions, scales, scaleFactor);
};
CastAndCallExtractedArrayFloats(points, functor);
return result;
}
} // anonymous namespace
namespace vtkm
{
namespace filter
{
namespace field_transform
{
//-----------------------------------------------------------------------------
VTKM_CONT Warp::Warp()
{
this->SetOutputFieldName("Warp");
this->SetUseCoordinateSystemAsField(0, true);
this->SetActiveField(1, "direction", vtkm::cont::Field::Association::Points);
this->SetActiveField(2, "scale", vtkm::cont::Field::Association::Points);
}
//-----------------------------------------------------------------------------
VTKM_CONT vtkm::cont::DataSet Warp::DoExecute(const vtkm::cont::DataSet& inDataSet)
{
vtkm::cont::Field pointField = this->GetFieldFromDataSet(0, inDataSet);
vtkm::cont::UnknownArrayHandle points = pointField.GetData();
vtkm::cont::UnknownArrayHandle directions;
if (this->GetUseConstantDirection())
{
directions = vtkm::cont::make_ArrayHandleConstant(this->GetConstantDirection(),
points.GetNumberOfValues());
}
else
{
directions = this->GetFieldFromDataSet(1, inDataSet).GetData();
}
vtkm::cont::UnknownArrayHandle scaleFactors;
if (this->GetUseScaleField())
{
scaleFactors = this->GetFieldFromDataSet(2, inDataSet).GetData();
}
else
{
scaleFactors =
vtkm::cont::make_ArrayHandleConstant<vtkm::FloatDefault>(1, points.GetNumberOfValues());
}
vtkm::cont::UnknownArrayHandle warpedPoints =
ComputeWarp(this->Invoke, points, directions, scaleFactors, this->ScaleFactor);
if (this->GetChangeCoordinateSystem())
{
auto fieldMapper = [](vtkm::cont::DataSet& out, const vtkm::cont::Field& fieldToPass) {
out.AddField(fieldToPass);
};
return this->CreateResultCoordinateSystem(
inDataSet, inDataSet.GetCellSet(), this->GetOutputFieldName(), warpedPoints, fieldMapper);
}
else
{
return this->CreateResultField(
inDataSet, this->GetOutputFieldName(), pointField.GetAssociation(), warpedPoints);
}
}
} // namespace field_transform
} // namespace filter
} // namespace vtkm

@ -0,0 +1,141 @@
//============================================================================
// 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.
//============================================================================
#ifndef vtk_m_filter_field_transform_Warp_h
#define vtk_m_filter_field_transform_Warp_h
#include <vtkm/filter/FilterField.h>
#include <vtkm/filter/field_transform/vtkm_filter_field_transform_export.h>
namespace vtkm
{
namespace filter
{
namespace field_transform
{
/// \brief Modify points by moving points along scaled direction vectors.
///
/// This filter displaces the point coordinates of a dataset either in the direction
/// of a direction vector field or in a constant direction.
///
/// The filter starts with a set of point coordinates or other vectors. By default these vectors
/// are the coordinate system, but they can be changed by modifying active field 0. These vectors
/// are then displaced by a set of vectors. This is done by selecting a field of directions, a
/// field of scales, and an additional scale factor. The directions are multiplied by the scale
/// field and the scale factor, and this displacement is added to the vector.
///
/// It is common to wish to warp in a constant direction by a scaled amount. To support
/// this so called "WarpScalar", the `Warp` filter allows you to specify a constant
/// direction direction with the `SetConstantDirection()` method. When this is set,
/// no direction field is retrieved. By default `Warp` uses (0, 0, 1) as the direction
/// direction.
///
/// It is also common to wish to simply apply a vector direction field (with a possible
/// constant scale). To support this so called "WarpVector", the `Warp` filter allows you
/// to ignore the scale field with the `SetUseScaleField()` method. When this is unset,
/// no scale field is retrieved. Calling `SetScaleField()` turns on the `UseScaleField`
/// flag. By default, `Warp` uses will not use the scale field unless specified.
///
/// The main use case for `Warp` is to adjust the spatial location and shape
/// of objects in 3D space. This filter will operate on the `vtkm::cont::CoordinateSystem`
/// of the input data unless a different active field is specified. Likewise,
/// this filter will save its results as the first coordinate system in the output
/// unless `SetChangeCoordinateSystem()` is set to say otherwise.
///
class VTKM_FILTER_FIELD_TRANSFORM_EXPORT Warp : public vtkm::filter::FilterField
{
public:
VTKM_CONT Warp();
/// @brief Specify a field to use as the directions.
///
/// The directions, when not set to use constant directions, are set as active field index 1.
VTKM_CONT void SetDirectionField(const std::string& name)
{
this->UseConstantDirection = false;
this->SetActiveField(1, name, vtkm::cont::Field::Association::Points);
}
/// @copydoc SetDirectionField
VTKM_CONT std::string GetDirectionFieldName() const { return this->GetActiveFieldName(1); }
/// @brief Specify a constant value to use as the directions.
///
/// This will provide a (constant) direction of the direction, and the direction field
/// will be ignored.
VTKM_CONT void SetConstantDirection(const vtkm::Vec3f& direction)
{
this->UseConstantDirection = true;
this->ConstantDirection = direction;
}
/// @copydoc SetConstantDirection
VTKM_CONT const vtkm::Vec3f& GetConstantDirection() const { return this->ConstantDirection; }
/// @brief Specifies whether a direction field or a constant direction direction is used.
///
/// When true, the constant direction direction is used. When false, the direction field (active
/// field index 1) is used.
VTKM_CONT void SetUseConstantDirection(bool flag) { this->UseConstantDirection = flag; }
/// @copydoc SetUseConstantDirection
VTKM_CONT bool GetUseConstantDirection() const { return this->UseConstantDirection; }
/// @brief Specify a field to use to scale the directions.
///
/// The scale factor field scales the size of the direction.
/// The scale factor, when not set to use a constant factor, is set as active field index 2.
VTKM_CONT void SetScaleField(const std::string& name)
{
this->UseScaleField = true;
this->SetActiveField(2, name, vtkm::cont::Field::Association::Points);
}
/// @copydoc SetScalarFactorField
VTKM_CONT std::string GetScaleFieldName() const { return this->GetActiveFieldName(2); }
/// @brief Specifies whether a scale factor field is used.
///
/// When true, a scale factor field the constant scale factor is used. When false, the scale factor field (active
/// field index 2) is used.
VTKM_CONT void SetUseScaleField(bool flag) { this->UseScaleField = flag; }
/// @copydoc SetUseConstantScale
VTKM_CONT bool GetUseScaleField() const { return this->UseScaleField; }
/// @brief Specifies an additional scale factor to scale the displacements.
///
/// When using a non-constant scale field, it is possible that the scale field is
/// of the wrong units and needs to be rescaled. This scale factor is multiplied to the
/// direction and scale to re-adjust the overall scale.
VTKM_CONT void SetScaleFactor(vtkm::FloatDefault scale) { this->ScaleFactor = scale; }
/// @copydoc SetScaleFactor
VTKM_CONT vtkm::FloatDefault GetScaleFactor() const { return this->ScaleFactor; }
/// @brief Specify whether the result should become the coordinate system of the output.
///
/// When this flag is on (the default) the first coordinate system in the output
/// `vtkm::cont::DataSet` is set to the transformed point coordinates.
void SetChangeCoordinateSystem(bool flag) { this->ChangeCoordinateSystem = flag; }
/// @copydoc SetChangeCoordinateSystem
bool GetChangeCoordinateSystem() const { return this->ChangeCoordinateSystem; }
protected:
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override;
private:
vtkm::Vec3f ConstantDirection = { 0, 0, 1 };
vtkm::FloatDefault ScaleFactor = 1;
bool UseConstantDirection = true;
bool UseScaleField = false;
bool ChangeCoordinateSystem = true;
};
} // namespace field_transform
} // namespace filter
} // namespace vtkm
#endif // vtk_m_filter_field_transform_Warp_h

@ -1,83 +0,0 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/filter/field_transform/WarpScalar.h>
#include <vtkm/filter/field_transform/worklet/WarpScalar.h>
namespace vtkm
{
namespace filter
{
namespace field_transform
{
//-----------------------------------------------------------------------------
VTKM_CONT WarpScalar::WarpScalar(vtkm::FloatDefault scaleAmount)
: ScaleAmount(scaleAmount)
{
this->SetOutputFieldName("warpscalar");
}
//-----------------------------------------------------------------------------
VTKM_CONT vtkm::cont::DataSet WarpScalar::DoExecute(const vtkm::cont::DataSet& inDataSet)
{
// TODO: do we still need to deal with this?
// WarpScalar often operates on a constant normal value
// using AdditionalFieldStorage =
// vtkm::List<vtkm::cont::ArrayHandleConstant<vtkm::Vec3f_32>::StorageTag,
// vtkm::cont::ArrayHandleConstant<vtkm::Vec3f_64>::StorageTag>;
// TODO:
// Ken suggested to provide additional public interface for user to supply a single
// value for const normal (and scale factor?).
vtkm::cont::Field normalF =
inDataSet.GetField(this->NormalFieldName, this->NormalFieldAssociation);
vtkm::cont::ArrayHandle<vtkm::Vec3f> normalArray;
if (normalF.GetData().CanConvert<vtkm::cont::ArrayHandleConstant<vtkm::Vec3f_32>>())
{
vtkm::Vec3f_32 norm =
normalF.GetData().AsArrayHandle<vtkm::cont::ArrayHandleConstant<vtkm::Vec3f_32>>().GetValue();
normalArray.AllocateAndFill(normalF.GetData().GetNumberOfValues(), vtkm::Vec3f(norm));
}
else if (normalF.GetData().CanConvert<vtkm::cont::ArrayHandleConstant<vtkm::Vec3f_64>>())
{
vtkm::Vec3f_64 norm =
normalF.GetData().AsArrayHandle<vtkm::cont::ArrayHandleConstant<vtkm::Vec3f_64>>().GetValue();
normalArray.AllocateAndFill(normalF.GetData().GetNumberOfValues(), vtkm::Vec3f(norm));
}
else
{
vtkm::cont::ArrayCopyShallowIfPossible(normalF.GetData(), normalArray);
}
vtkm::cont::Field sfF =
inDataSet.GetField(this->ScalarFactorFieldName, this->ScalarFactorFieldAssociation);
vtkm::cont::ArrayHandle<vtkm::FloatDefault> scaleFactorArray;
vtkm::cont::ArrayCopyShallowIfPossible(sfF.GetData(), scaleFactorArray);
vtkm::cont::UnknownArrayHandle outArray;
auto resolveType = [&](const auto& concrete) {
// We know ValueType is some form of Vec3 due to CastAndCallVecField
using VecType = typename std::decay_t<decltype(concrete)>::ValueType;
vtkm::cont::ArrayHandle<VecType> result;
vtkm::worklet::WarpScalar worklet{ this->ScaleAmount };
this->Invoke(worklet, concrete, normalArray, scaleFactorArray, result);
outArray = result;
};
const auto& field = this->GetFieldFromDataSet(inDataSet);
this->CastAndCallVecField<3>(field, resolveType);
return this->CreateResultField(
inDataSet, this->GetOutputFieldName(), field.GetAssociation(), outArray);
}
} // namespace field_transform
} // namespace filter
} // namespace vtkm

@ -11,8 +11,16 @@
#ifndef vtk_m_filter_field_transform_WarpScalar_h
#define vtk_m_filter_field_transform_WarpScalar_h
#include <vtkm/filter/FilterField.h>
#include <vtkm/filter/field_transform/vtkm_filter_field_transform_export.h>
#include <vtkm/filter/field_transform/Warp.h>
#include <vtkm/Deprecated.h>
struct VTKM_DEPRECATED(2.2, "WarpScalar.h header no longer supported. Use Warp.h.")
vtkm_deprecated_WarpScalar_h_warning
{
};
vtkm_deprecated_WarpScalar_h_warning vtkm_give_WarpScalar_h_warning;
namespace vtkm
{
@ -20,73 +28,65 @@ namespace filter
{
namespace field_transform
{
/// \brief Modify points by moving points along point normals by the scalar
/// amount times the scalar factor.
///
/// A filter that modifies point coordinates by moving points along point normals
/// by the scalar amount times the scalar factor.
/// It's a VTK-m version of the vtkWarpScalar in VTK.
/// Useful for creating carpet or x-y-z plots.
/// It doesn't modify the point coordinates, but creates a new point coordinates that have been warped.
class VTKM_FILTER_FIELD_TRANSFORM_EXPORT WarpScalar : public vtkm::filter::FilterField
class VTKM_DEPRECATED(2.2, "Use more general Warp filter.") WarpScalar
: public vtkm::filter::field_transform::Warp
{
public:
VTKM_CONT
explicit WarpScalar(vtkm::FloatDefault scaleAmount);
VTKM_DEPRECATED(2.2, "Use SetScaleFactor().")
VTKM_CONT explicit WarpScalar(vtkm::FloatDefault scaleAmount)
{
this->SetScaleFactor(scaleAmount);
this->SetOutputFieldName("warpscalar");
}
///@{
/// Choose the secondary field to operate on. In the warp op A + B *
/// scaleAmount * scalarFactor, B is the secondary field
VTKM_CONT
void SetNormalField(
VTKM_DEPRECATED(2.2, "Use SetDirectionField().")
VTKM_CONT void SetNormalField(
const std::string& name,
vtkm::cont::Field::Association association = vtkm::cont::Field::Association::Any)
{
this->NormalFieldName = name;
this->NormalFieldAssociation = association;
if ((association != vtkm::cont::Field::Association::Any) &&
(association != vtkm::cont::Field::Association::Points))
{
throw vtkm::cont::ErrorBadValue("Normal field should always be associated with points.");
}
this->SetDirectionField(name);
}
VTKM_CONT const std::string& GetNormalFieldName() const { return this->NormalFieldName; }
VTKM_DEPRECATED(2.2, "Use GetDirectionFieldName().")
VTKM_CONT std::string GetNormalFieldName() const { return this->GetDirectionFieldName(); }
VTKM_DEPRECATED(2.2, "Only point association supported.")
VTKM_CONT vtkm::cont::Field::Association GetNormalFieldAssociation() const
{
return this->NormalFieldAssociation;
return this->GetActiveFieldAssociation(1);
}
///@}
///@{
/// Choose the scalar factor field to operate on. In the warp op A + B *
/// scaleAmount * scalarFactor, scalarFactor is the scalar factor field.
VTKM_CONT
void SetScalarFactorField(
VTKM_DEPRECATED(2.2, "Use SetScaleField().")
VTKM_CONT void SetScalarFactorField(
const std::string& name,
vtkm::cont::Field::Association association = vtkm::cont::Field::Association::Any)
{
this->ScalarFactorFieldName = name;
this->ScalarFactorFieldAssociation = association;
if ((association != vtkm::cont::Field::Association::Any) &&
(association != vtkm::cont::Field::Association::Points))
{
throw vtkm::cont::ErrorBadValue("Normal field should always be associated with points.");
}
this->SetScaleField(name);
}
VTKM_CONT const std::string& GetScalarFactorFieldName() const
{
return this->ScalarFactorFieldName;
}
VTKM_DEPRECATED(2.2, "Use GetScaleField().")
VTKM_CONT std::string GetScalarFactorFieldName() const { return this->GetScaleFieldName(); }
VTKM_DEPRECATED(2.2, "Only point association supported.")
VTKM_CONT vtkm::cont::Field::Association GetScalarFactorFieldAssociation() const
{
return this->ScalarFactorFieldAssociation;
return this->GetActiveFieldAssociation(1);
}
///@}
private:
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override;
std::string NormalFieldName = "normal";
vtkm::cont::Field::Association NormalFieldAssociation = vtkm::cont::Field::Association::Any;
std::string ScalarFactorFieldName = "scalarfactor";
vtkm::cont::Field::Association ScalarFactorFieldAssociation = vtkm::cont::Field::Association::Any;
vtkm::FloatDefault ScaleAmount;
};
} // namespace field_transform
} // namespace filter
} // namespace vtkm
#endif // vtk_m_filter_field_transform_WarpScalar_h
#endif //vtk_m_filter_field_transform_WarpScalar_h

@ -1,70 +0,0 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/filter/field_transform/WarpVector.h>
#include <vtkm/filter/field_transform/worklet/WarpVector.h>
namespace vtkm
{
namespace filter
{
namespace field_transform
{
//-----------------------------------------------------------------------------
VTKM_CONT WarpVector::WarpVector(vtkm::FloatDefault scale)
: Scale(scale)
{
this->SetOutputFieldName("warpvector");
}
//-----------------------------------------------------------------------------
VTKM_CONT vtkm::cont::DataSet WarpVector::DoExecute(const vtkm::cont::DataSet& inDataSet)
{
vtkm::cont::Field vectorF =
inDataSet.GetField(this->VectorFieldName, this->VectorFieldAssociation);
vtkm::cont::ArrayHandle<vtkm::Vec3f> vectorArray;
if (vectorF.GetData().CanConvert<vtkm::cont::ArrayHandleConstant<vtkm::Vec3f_32>>())
{
vtkm::Vec3f_32 norm =
vectorF.GetData().AsArrayHandle<vtkm::cont::ArrayHandleConstant<vtkm::Vec3f_32>>().GetValue();
vectorArray.AllocateAndFill(vectorF.GetData().GetNumberOfValues(), vtkm::Vec3f(norm));
}
else if (vectorF.GetData().CanConvert<vtkm::cont::ArrayHandleConstant<vtkm::Vec3f_64>>())
{
vtkm::Vec3f_64 norm =
vectorF.GetData().AsArrayHandle<vtkm::cont::ArrayHandleConstant<vtkm::Vec3f_64>>().GetValue();
vectorArray.AllocateAndFill(vectorF.GetData().GetNumberOfValues(), vtkm::Vec3f(norm));
}
else
{
vtkm::cont::ArrayCopyShallowIfPossible(vectorF.GetData(), vectorArray);
}
vtkm::cont::UnknownArrayHandle outArray;
auto resolveType = [&](const auto& concrete) {
// We know ValueType is some form of Vec3 due to CastAndCallVecField
using VecType = typename std::decay_t<decltype(concrete)>::ValueType;
vtkm::cont::ArrayHandle<VecType> result;
vtkm::worklet::WarpVector worklet{ this->Scale };
this->Invoke(worklet, concrete, vectorArray, result);
outArray = result;
};
const auto& field = this->GetFieldFromDataSet(inDataSet);
this->CastAndCallVecField<3>(field, resolveType);
return this->CreateResultField(
inDataSet, this->GetOutputFieldName(), field.GetAssociation(), outArray);
}
} // namespace field_transform
} // namespace filter
} // namespace vtkm

@ -11,8 +11,16 @@
#ifndef vtk_m_filter_field_transform_WarpVector_h
#define vtk_m_filter_field_transform_WarpVector_h
#include <vtkm/filter/FilterField.h>
#include <vtkm/filter/field_transform/vtkm_filter_field_transform_export.h>
#include <vtkm/filter/field_transform/Warp.h>
#include <vtkm/Deprecated.h>
struct VTKM_DEPRECATED(2.2, "WarpVector.h header no longer supported. Use Warp.h.")
vtkm_deprecated_WarpVector_h_warning
{
};
vtkm_deprecated_WarpVector_h_warning vtkm_give_WarpVector_h_warning;
namespace vtkm
{
@ -20,47 +28,41 @@ namespace filter
{
namespace field_transform
{
/// \brief Modify points by moving points along a vector multiplied by
/// the scale factor
///
/// A filter that modifies point coordinates by moving points along a vector
/// multiplied by 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 VTKM_FILTER_FIELD_TRANSFORM_EXPORT WarpVector : public vtkm::filter::FilterField
class VTKM_DEPRECATED(2.2, "Use more general Warp filter.") WarpVector
: public vtkm::filter::field_transform::Warp
{
public:
VTKM_CONT
explicit WarpVector(vtkm::FloatDefault scale);
VTKM_DEPRECATED(2.2, "Use SetScaleFactor().")
VTKM_CONT explicit WarpVector(vtkm::FloatDefault scale)
{
this->SetScaleFactor(scale);
this->SetOutputFieldName("warpvector");
}
///@{
/// Choose the vector field to operate on. In the warp op A + B *scale, B is
/// the vector field
VTKM_CONT
void SetVectorField(
VTKM_DEPRECATED(2.2, "Use SetDirectionField().")
VTKM_CONT void SetVectorField(
const std::string& name,
vtkm::cont::Field::Association association = vtkm::cont::Field::Association::Any)
{
this->VectorFieldName = name;
this->VectorFieldAssociation = association;
if ((association != vtkm::cont::Field::Association::Any) &&
(association != vtkm::cont::Field::Association::Points))
{
throw vtkm::cont::ErrorBadValue("Normal field should always be associated with points.");
}
this->SetDirectionField(name);
}
VTKM_CONT const std::string& GetVectorFieldName() const { return this->VectorFieldName; }
VTKM_DEPRECATED(2.2, "Use GetDirectionFieldName().")
VTKM_CONT std::string GetVectorFieldName() const { return this->GetDirectionFieldName(); }
VTKM_DEPRECATED(2.2, "Only point association supported.")
VTKM_CONT vtkm::cont::Field::Association GetVectorFieldAssociation() const
{
return this->VectorFieldAssociation;
return this->GetActiveFieldAssociation(1);
}
///@}
private:
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override;
std::string VectorFieldName = "normal";
vtkm::cont::Field::Association VectorFieldAssociation = vtkm::cont::Field::Association::Any;
vtkm::FloatDefault Scale;
};
} // namespace field_transform
} // namespace filter
} // namespace vtkm

@ -14,8 +14,7 @@ set(unit_tests
UnitTestGenerateIds.cxx
UnitTestPointElevationFilter.cxx
UnitTestPointTransform.cxx
UnitTestWarpScalarFilter.cxx
UnitTestWarpVectorFilter.cxx
UnitTestWarpFilter.cxx
UnitTestLogValues.cxx
UnitTestCompositeVectors.cxx
)

@ -9,15 +9,17 @@
//============================================================================
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/field_transform/WarpScalar.h>
#include <vtkm/filter/field_transform/Warp.h>
#include <vector>
namespace
{
const vtkm::Id dim = 5;
constexpr vtkm::Id DIM = 5;
template <typename T>
vtkm::cont::DataSet MakeWarpScalarTestDataSet()
vtkm::cont::DataSet MakeWarpTestDataSet()
{
using vecType = vtkm::Vec<T, 3>;
vtkm::cont::DataSet dataSet;
@ -25,16 +27,18 @@ vtkm::cont::DataSet MakeWarpScalarTestDataSet()
std::vector<vecType> coordinates;
std::vector<vecType> vec1;
std::vector<T> scalarFactor;
for (vtkm::Id j = 0; j < dim; ++j)
std::vector<vecType> vec2;
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 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 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));
scalarFactor.push_back(static_cast<T>(j * dim + i));
scalarFactor.push_back(static_cast<T>(j * DIM + i));
vec2.push_back(vtkm::make_Vec<T>(0, 0, static_cast<T>(j * DIM + i)));
}
}
@ -43,77 +47,101 @@ vtkm::cont::DataSet MakeWarpScalarTestDataSet()
dataSet.AddPointField("vec1", vec1);
dataSet.AddPointField("scalarfactor", scalarFactor);
dataSet.AddPointField("vec2", vec2);
vecType normal = vtkm::make_Vec<T>(static_cast<T>(0.0), static_cast<T>(0.0), static_cast<T>(1.0));
vtkm::cont::ArrayHandleConstant<vecType> vectorAH =
vtkm::cont::make_ArrayHandleConstant(normal, dim * dim);
vtkm::cont::make_ArrayHandleConstant(normal, DIM * DIM);
dataSet.AddPointField("normal", vectorAH);
return dataSet;
}
void CheckResult(const vtkm::filter::field_transform::WarpScalar& filter,
void CheckResult(const vtkm::filter::field_transform::Warp& filter,
const vtkm::cont::DataSet& result)
{
VTKM_TEST_ASSERT(result.HasPointField("warpscalar"), "Output filed warpscalar is missing");
VTKM_TEST_ASSERT(result.HasPointField(filter.GetOutputFieldName()));
using vecType = vtkm::Vec3f;
vtkm::cont::ArrayHandle<vecType> outputArray;
result.GetPointField("warpscalar").GetData().AsArrayHandle(outputArray);
result.GetPointField(filter.GetOutputFieldName()).GetData().AsArrayHandle(outputArray);
auto outPortal = outputArray.ReadPortal();
vtkm::cont::ArrayHandle<vtkm::FloatDefault> sfArray;
result.GetPointField("scalarfactor").GetData().AsArrayHandle(sfArray);
auto sfPortal = sfArray.ReadPortal();
for (vtkm::Id j = 0; j < dim; ++j)
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)
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);
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.GetUseCoordinateSystemAsField()
? z + static_cast<vtkm::FloatDefault>(2 * sfPortal.Get(j * dim + i))
: y + static_cast<vtkm::FloatDefault>(2 * sfPortal.Get(j * dim + i));
auto point = outPortal.Get(j * dim + i);
VTKM_TEST_ASSERT(point[0] == x, "Wrong result of x value for warp scalar");
VTKM_TEST_ASSERT(point[1] == y, "Wrong result of y value for warp scalar");
VTKM_TEST_ASSERT(point[2] == targetZ, "Wrong result of z value for warp scalar");
? z + static_cast<vtkm::FloatDefault>(2 * sfPortal.Get(j * DIM + i))
: y + static_cast<vtkm::FloatDefault>(2 * sfPortal.Get(j * DIM + i));
auto point = outPortal.Get(j * DIM + i);
VTKM_TEST_ASSERT(test_equal(point[0], x), "Wrong result of x value for warp scalar");
VTKM_TEST_ASSERT(test_equal(point[1], y), "Wrong result of y value for warp scalar");
VTKM_TEST_ASSERT(test_equal(point[2], targetZ), "Wrong result of z value for warp scalar");
}
}
}
void TestWarpScalarFilter()
void TestWarpFilter()
{
std::cout << "Testing WarpScalar filter" << std::endl;
vtkm::cont::DataSet ds = MakeWarpScalarTestDataSet<vtkm::FloatDefault>();
std::cout << "Testing Warp filter" << std::endl;
vtkm::cont::DataSet ds = MakeWarpTestDataSet<vtkm::FloatDefault>();
vtkm::FloatDefault scale = 2;
{
std::cout << " First field as coordinates" << std::endl;
vtkm::filter::field_transform::WarpScalar filter(scale);
vtkm::filter::field_transform::Warp filter;
filter.SetScaleFactor(scale);
filter.SetUseCoordinateSystemAsField(true);
filter.SetNormalField("normal");
filter.SetScalarFactorField("scalarfactor");
filter.SetDirectionField("normal");
filter.SetScaleField("scalarfactor");
vtkm::cont::DataSet result = filter.Execute(ds);
CheckResult(filter, result);
}
{
std::cout << " First field as a vector" << std::endl;
vtkm::filter::field_transform::WarpScalar filter(scale);
vtkm::filter::field_transform::Warp filter;
filter.SetScaleFactor(scale);
filter.SetActiveField("vec1");
filter.SetNormalField("normal");
filter.SetScalarFactorField("scalarfactor");
filter.SetDirectionField("normal");
filter.SetScaleField("scalarfactor");
vtkm::cont::DataSet result = filter.Execute(ds);
CheckResult(filter, result);
}
{
std::cout << " Constant direction (warp scalar)" << std::endl;
vtkm::filter::field_transform::Warp filter;
filter.SetScaleFactor(scale);
filter.SetUseCoordinateSystemAsField(true);
filter.SetConstantDirection({ 0.0, 0.0, 1.0 });
filter.SetScaleField("scalarfactor");
vtkm::cont::DataSet result = filter.Execute(ds);
CheckResult(filter, result);
}
{
std::cout << " Constant scale (warp vector)" << std::endl;
vtkm::filter::field_transform::Warp filter;
filter.SetScaleFactor(scale);
filter.SetActiveField("vec1");
filter.SetDirectionField("vec2");
vtkm::cont::DataSet result = filter.Execute(ds);
CheckResult(filter, result);
}
}
}
int UnitTestWarpScalarFilter(int argc, char* argv[])
int UnitTestWarpFilter(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(TestWarpScalarFilter, argc, argv);
return vtkm::cont::testing::Testing::Run(TestWarpFilter, argc, argv);
}

@ -1,112 +0,0 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/field_transform/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));
dataSet.AddPointField("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);
dataSet.AddPointField("vec2", vectorAH);
return dataSet;
}
void CheckResult(const vtkm::filter::field_transform::WarpVector& filter,
const vtkm::cont::DataSet& result)
{
VTKM_TEST_ASSERT(result.HasPointField("warpvector"), "Output filed WarpVector is missing");
using vecType = vtkm::Vec3f;
vtkm::cont::ArrayHandle<vecType> outputArray;
result.GetPointField("warpvector").GetData().AsArrayHandle(outputArray);
auto outPortal = outputArray.ReadPortal();
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.GetUseCoordinateSystemAsField()
? 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::field_transform::WarpVector filter(scale);
filter.SetUseCoordinateSystemAsField(true);
filter.SetVectorField("vec2");
vtkm::cont::DataSet result = filter.Execute(ds);
CheckResult(filter, result);
}
{
std::cout << " First field as a vector" << std::endl;
vtkm::filter::field_transform::WarpVector filter(scale);
filter.SetActiveField("vec1");
filter.SetVectorField("vec2");
vtkm::cont::DataSet result = filter.Execute(ds);
CheckResult(filter, result);
}
}
}
int UnitTestWarpVectorFilter(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(TestWarpVectorFilter, argc, argv);
}

@ -12,8 +12,6 @@ set(headers
CoordinateSystemTransform.h
PointElevation.h
PointTransform.h
WarpScalar.h
WarpVector.h
LogValues.h
)

@ -1,60 +0,0 @@
//============================================================================
// 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.
//============================================================================
#ifndef vtk_m_worklet_WarpScalar_h
#define vtk_m_worklet_WarpScalar_h
#include <vtkm/worklet/WorkletMapField.h>
namespace vtkm
{
namespace worklet
{
// A functor that modify points by moving points along point normals by the scalar
// amount times the scalar factor. It's a VTK-m version of the vtkWarpScalar in VTK.
// Useful for creating carpet or x-y-z plots.
// It doesn't modify the point coordinates, but creates a new point coordinates
// that have been warped.
class WarpScalar : public vtkm::worklet::WorkletMapField
{
public:
using ControlSignature = void(FieldIn, FieldIn, FieldIn, FieldOut);
using ExecutionSignature = void(_1, _2, _3, _4);
VTKM_CONT
explicit WarpScalar(vtkm::FloatDefault scaleAmount)
: ScaleAmount(scaleAmount)
{
}
VTKM_EXEC
void operator()(const vtkm::Vec3f& point,
const vtkm::Vec3f& normal,
const vtkm::FloatDefault& scaleFactor,
vtkm::Vec3f& result) const
{
result = point + this->ScaleAmount * scaleFactor * normal;
}
template <typename T1, typename T2, typename T3>
VTKM_EXEC void operator()(const vtkm::Vec<T1, 3>& point,
const vtkm::Vec<T2, 3>& normal,
const T3& scaleFactor,
vtkm::Vec<T1, 3>& result) const
{
result = point + static_cast<T1>(this->ScaleAmount * scaleFactor) * normal;
}
private:
vtkm::FloatDefault ScaleAmount;
};
}
} // namespace vtkm::worklet
#endif // vtk_m_worklet_WarpScalar_h

@ -1,56 +0,0 @@
//============================================================================
// 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.
//============================================================================
#ifndef vtk_m_worklet_WarpVector_h
#define vtk_m_worklet_WarpVector_h
#include <vtkm/worklet/WorkletMapField.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 vtkm::worklet::WorkletMapField
{
public:
using ControlSignature = void(FieldIn, FieldIn, FieldOut);
using ExecutionSignature = _3(_1, _2);
VTKM_CONT
explicit WarpVector(vtkm::FloatDefault scale)
: Scale(scale)
{
}
VTKM_EXEC
vtkm::Vec3f operator()(const vtkm::Vec3f& point, const vtkm::Vec3f& 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;
};
}
} // namespace vtkm::worklet
#endif // vtk_m_worklet_WarpVector_h