diff --git a/benchmarking/BenchmarkFilters.cxx b/benchmarking/BenchmarkFilters.cxx index fc40aa08d..3bf008a2e 100644 --- a/benchmarking/BenchmarkFilters.cxx +++ b/benchmarking/BenchmarkFilters.cxx @@ -36,8 +36,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -358,10 +357,11 @@ void BenchWarpScalar(::benchmark::State& state) const vtkm::cont::DeviceAdapterId device = Config.Device; const bool isPartitioned = static_cast(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(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(); diff --git a/docs/changelog/update-warps.md b/docs/changelog/update-warps.md new file mode 100644 index 000000000..b1e911720 --- /dev/null +++ b/docs/changelog/update-warps.md @@ -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. diff --git a/vtkm/filter/field_transform/CMakeLists.txt b/vtkm/filter/field_transform/CMakeLists.txt index ae4dc59ad..f5c01a24c 100644 --- a/vtkm/filter/field_transform/CMakeLists.txt +++ b/vtkm/filter/field_transform/CMakeLists.txt @@ -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 diff --git a/vtkm/filter/field_transform/Warp.cxx b/vtkm/filter/field_transform/Warp.cxx new file mode 100644 index 000000000..12889a972 --- /dev/null +++ b/vtkm/filter/field_transform/Warp.cxx @@ -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 +#include +#include +#include +#include +#include +#include +#include + +#include + +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 + 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 +VTKM_CONT void CastAndCallExtractedArrayFloats(const vtkm::cont::UnknownArrayHandle& array, + Functor&& functor) +{ + if (array.IsBaseComponentType()) + { + functor(array.ExtractArrayFromComponents()); + } + else if (array.IsBaseComponentType()) + { + functor(array.ExtractArrayFromComponents()); + } + else + { + // Array is not float. Copy it to a float array and call the functor. + vtkm::cont::ArrayHandleRuntimeVec 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()); + } +} + +template +struct BiggerTypeImpl +{ + VTKM_STATIC_ASSERT( + (std::is_same::NumericTag, vtkm::TypeTraitsRealTag>::value)); + VTKM_STATIC_ASSERT( + (std::is_same::NumericTag, vtkm::TypeTraitsRealTag>::value)); + VTKM_STATIC_ASSERT((std::is_same::DimensionalityTag, + vtkm::TypeTraitsScalarTag>::value)); + VTKM_STATIC_ASSERT((std::is_same::DimensionalityTag, + vtkm::TypeTraitsScalarTag>::value)); + using type = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>; +}; +template +using BiggerType = typename BiggerTypeImpl::type; + +template +VTKM_CONT vtkm::cont::UnknownArrayHandle ComputeWarp( + const vtkm::cont::Invoker& invoke, + const vtkm::cont::ArrayHandleRecombineVec& points, + const vtkm::cont::ArrayHandleRecombineVec& directions, + const vtkm::cont::ArrayHandleRecombineVec& 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, ScalarFactorType>; + vtkm::cont::ArrayHandleRuntimeVec result{ numComponents }; + + invoke(WarpWorklet{ scaleFactor }, points, directions, scalarFactorsComponents, result); + + return result; +} + +template +VTKM_CONT vtkm::cont::UnknownArrayHandle ComputeWarp( + const vtkm::cont::Invoker& invoke, + const vtkm::cont::ArrayHandleRecombineVec& points, + const vtkm::cont::ArrayHandleRecombineVec& 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 +VTKM_CONT vtkm::cont::UnknownArrayHandle ComputeWarp( + const vtkm::cont::Invoker& invoke, + const vtkm::cont::ArrayHandleRecombineVec& 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(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 diff --git a/vtkm/filter/field_transform/Warp.h b/vtkm/filter/field_transform/Warp.h new file mode 100644 index 000000000..593d7f792 --- /dev/null +++ b/vtkm/filter/field_transform/Warp.h @@ -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 +#include + +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 diff --git a/vtkm/filter/field_transform/WarpScalar.cxx b/vtkm/filter/field_transform/WarpScalar.cxx deleted file mode 100644 index 66d5172e3..000000000 --- a/vtkm/filter/field_transform/WarpScalar.cxx +++ /dev/null @@ -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 -#include -#include - -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::StorageTag, - // vtkm::cont::ArrayHandleConstant::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 normalArray; - if (normalF.GetData().CanConvert>()) - { - vtkm::Vec3f_32 norm = - normalF.GetData().AsArrayHandle>().GetValue(); - normalArray.AllocateAndFill(normalF.GetData().GetNumberOfValues(), vtkm::Vec3f(norm)); - } - else if (normalF.GetData().CanConvert>()) - { - vtkm::Vec3f_64 norm = - normalF.GetData().AsArrayHandle>().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 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::ValueType; - - vtkm::cont::ArrayHandle 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 diff --git a/vtkm/filter/field_transform/WarpScalar.h b/vtkm/filter/field_transform/WarpScalar.h index 8512a2452..eecf7868d 100644 --- a/vtkm/filter/field_transform/WarpScalar.h +++ b/vtkm/filter/field_transform/WarpScalar.h @@ -11,8 +11,16 @@ #ifndef vtk_m_filter_field_transform_WarpScalar_h #define vtk_m_filter_field_transform_WarpScalar_h -#include -#include +#include + +#include + +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 diff --git a/vtkm/filter/field_transform/WarpVector.cxx b/vtkm/filter/field_transform/WarpVector.cxx deleted file mode 100644 index a2a208acd..000000000 --- a/vtkm/filter/field_transform/WarpVector.cxx +++ /dev/null @@ -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 -#include -#include - -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 vectorArray; - if (vectorF.GetData().CanConvert>()) - { - vtkm::Vec3f_32 norm = - vectorF.GetData().AsArrayHandle>().GetValue(); - vectorArray.AllocateAndFill(vectorF.GetData().GetNumberOfValues(), vtkm::Vec3f(norm)); - } - else if (vectorF.GetData().CanConvert>()) - { - vtkm::Vec3f_64 norm = - vectorF.GetData().AsArrayHandle>().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::ValueType; - - vtkm::cont::ArrayHandle 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 diff --git a/vtkm/filter/field_transform/WarpVector.h b/vtkm/filter/field_transform/WarpVector.h index 6642e6156..0dd075542 100644 --- a/vtkm/filter/field_transform/WarpVector.h +++ b/vtkm/filter/field_transform/WarpVector.h @@ -11,8 +11,16 @@ #ifndef vtk_m_filter_field_transform_WarpVector_h #define vtk_m_filter_field_transform_WarpVector_h -#include -#include +#include + +#include + +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 diff --git a/vtkm/filter/field_transform/testing/CMakeLists.txt b/vtkm/filter/field_transform/testing/CMakeLists.txt index faf68cd3e..12e9d57d3 100644 --- a/vtkm/filter/field_transform/testing/CMakeLists.txt +++ b/vtkm/filter/field_transform/testing/CMakeLists.txt @@ -14,8 +14,7 @@ set(unit_tests UnitTestGenerateIds.cxx UnitTestPointElevationFilter.cxx UnitTestPointTransform.cxx - UnitTestWarpScalarFilter.cxx - UnitTestWarpVectorFilter.cxx + UnitTestWarpFilter.cxx UnitTestLogValues.cxx UnitTestCompositeVectors.cxx ) diff --git a/vtkm/filter/field_transform/testing/UnitTestWarpScalarFilter.cxx b/vtkm/filter/field_transform/testing/UnitTestWarpFilter.cxx similarity index 50% rename from vtkm/filter/field_transform/testing/UnitTestWarpScalarFilter.cxx rename to vtkm/filter/field_transform/testing/UnitTestWarpFilter.cxx index 1590626df..d2896eaa3 100644 --- a/vtkm/filter/field_transform/testing/UnitTestWarpScalarFilter.cxx +++ b/vtkm/filter/field_transform/testing/UnitTestWarpFilter.cxx @@ -9,15 +9,17 @@ //============================================================================ #include -#include +#include #include namespace { -const vtkm::Id dim = 5; + +constexpr vtkm::Id DIM = 5; + template -vtkm::cont::DataSet MakeWarpScalarTestDataSet() +vtkm::cont::DataSet MakeWarpTestDataSet() { using vecType = vtkm::Vec; vtkm::cont::DataSet dataSet; @@ -25,16 +27,18 @@ vtkm::cont::DataSet MakeWarpScalarTestDataSet() std::vector coordinates; std::vector vec1; std::vector scalarFactor; - for (vtkm::Id j = 0; j < dim; ++j) + std::vector vec2; + for (vtkm::Id j = 0; j < DIM; ++j) { - T z = static_cast(j) / static_cast(dim - 1); - for (vtkm::Id i = 0; i < dim; ++i) + T z = static_cast(j) / static_cast(DIM - 1); + for (vtkm::Id i = 0; i < DIM; ++i) { - T x = static_cast(i) / static_cast(dim - 1); + T x = static_cast(i) / static_cast(DIM - 1); T y = (x * x + z * z) / static_cast(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(j * dim + i)); + scalarFactor.push_back(static_cast(j * DIM + i)); + vec2.push_back(vtkm::make_Vec(0, 0, static_cast(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(static_cast(0.0), static_cast(0.0), static_cast(1.0)); vtkm::cont::ArrayHandleConstant 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 outputArray; - result.GetPointField("warpscalar").GetData().AsArrayHandle(outputArray); + result.GetPointField(filter.GetOutputFieldName()).GetData().AsArrayHandle(outputArray); auto outPortal = outputArray.ReadPortal(); vtkm::cont::ArrayHandle 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(j) / static_cast(dim - 1); - for (vtkm::Id i = 0; i < dim; ++i) + static_cast(j) / static_cast(DIM - 1); + for (vtkm::Id i = 0; i < DIM; ++i) { vtkm::FloatDefault x = - static_cast(i) / static_cast(dim - 1); + static_cast(i) / static_cast(DIM - 1); vtkm::FloatDefault y = (x * x + z * z) / static_cast(2.0); vtkm::FloatDefault targetZ = filter.GetUseCoordinateSystemAsField() - ? z + static_cast(2 * sfPortal.Get(j * dim + i)) - : y + static_cast(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(2 * sfPortal.Get(j * DIM + i)) + : y + static_cast(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(); + std::cout << "Testing Warp filter" << std::endl; + vtkm::cont::DataSet ds = MakeWarpTestDataSet(); 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); } diff --git a/vtkm/filter/field_transform/testing/UnitTestWarpVectorFilter.cxx b/vtkm/filter/field_transform/testing/UnitTestWarpVectorFilter.cxx deleted file mode 100644 index f9649154d..000000000 --- a/vtkm/filter/field_transform/testing/UnitTestWarpVectorFilter.cxx +++ /dev/null @@ -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 -#include - -#include -#include - -namespace -{ -const vtkm::Id dim = 5; -template -vtkm::cont::DataSet MakeWarpVectorTestDataSet() -{ - using vecType = vtkm::Vec; - vtkm::cont::DataSet dataSet; - - std::vector coordinates; - std::vector vec1; - for (vtkm::Id j = 0; j < dim; ++j) - { - T z = static_cast(j) / static_cast(dim - 1); - for (vtkm::Id i = 0; i < dim; ++i) - { - T x = static_cast(i) / static_cast(dim - 1); - T y = (x * x + z * z) / static_cast(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(static_cast(0.0), static_cast(0.0), static_cast(2.0)); - vtkm::cont::ArrayHandleConstant 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 outputArray; - result.GetPointField("warpvector").GetData().AsArrayHandle(outputArray); - auto outPortal = outputArray.ReadPortal(); - - for (vtkm::Id j = 0; j < dim; ++j) - { - vtkm::FloatDefault z = - static_cast(j) / static_cast(dim - 1); - for (vtkm::Id i = 0; i < dim; ++i) - { - vtkm::FloatDefault x = - static_cast(i) / static_cast(dim - 1); - vtkm::FloatDefault y = (x * x + z * z) / static_cast(2.0); - vtkm::FloatDefault targetZ = filter.GetUseCoordinateSystemAsField() - ? z + static_cast(2 * 2) - : y + static_cast(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 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); -} diff --git a/vtkm/filter/field_transform/worklet/CMakeLists.txt b/vtkm/filter/field_transform/worklet/CMakeLists.txt index f95c2de1d..5549ce7f0 100644 --- a/vtkm/filter/field_transform/worklet/CMakeLists.txt +++ b/vtkm/filter/field_transform/worklet/CMakeLists.txt @@ -12,8 +12,6 @@ set(headers CoordinateSystemTransform.h PointElevation.h PointTransform.h - WarpScalar.h - WarpVector.h LogValues.h ) diff --git a/vtkm/filter/field_transform/worklet/WarpScalar.h b/vtkm/filter/field_transform/worklet/WarpScalar.h deleted file mode 100644 index 3950a8080..000000000 --- a/vtkm/filter/field_transform/worklet/WarpScalar.h +++ /dev/null @@ -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 - -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 - VTKM_EXEC void operator()(const vtkm::Vec& point, - const vtkm::Vec& normal, - const T3& scaleFactor, - vtkm::Vec& result) const - { - result = point + static_cast(this->ScaleAmount * scaleFactor) * normal; - } - -private: - vtkm::FloatDefault ScaleAmount; -}; -} -} // namespace vtkm::worklet - -#endif // vtk_m_worklet_WarpScalar_h diff --git a/vtkm/filter/field_transform/worklet/WarpVector.h b/vtkm/filter/field_transform/worklet/WarpVector.h deleted file mode 100644 index 8d20f7464..000000000 --- a/vtkm/filter/field_transform/worklet/WarpVector.h +++ /dev/null @@ -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 - -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 - VTKM_EXEC vtkm::Vec operator()(const vtkm::Vec& point, - const vtkm::Vec& vector) const - { - return point + static_cast(this->Scale) * vector; - } - - -private: - vtkm::FloatDefault Scale; -}; -} -} // namespace vtkm::worklet - -#endif // vtk_m_worklet_WarpVector_h