mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Merge topic 'update-warps'
1f07b0ecf Consolidate WarpScalar and WarpVector filter Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !3115
This commit is contained in:
commit
5b588a8a04
@ -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();
|
||||
|
32
docs/changelog/update-warps.md
Normal file
32
docs/changelog/update-warps.md
Normal file
@ -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
|
||||
|
248
vtkm/filter/field_transform/Warp.cxx
Normal file
248
vtkm/filter/field_transform/Warp.cxx
Normal file
@ -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
|
141
vtkm/filter/field_transform/Warp.h
Normal file
141
vtkm/filter/field_transform/Warp.h
Normal file
@ -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;
|
||||
}
|
||||
|
||||
VTKM_CONT const std::string& GetScalarFactorFieldName() const
|
||||
if ((association != vtkm::cont::Field::Association::Any) &&
|
||||
(association != vtkm::cont::Field::Association::Points))
|
||||
{
|
||||
return this->ScalarFactorFieldName;
|
||||
throw vtkm::cont::ErrorBadValue("Normal field should always be associated with points.");
|
||||
}
|
||||
this->SetScaleField(name);
|
||||
}
|
||||
|
||||
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
|
Loading…
Reference in New Issue
Block a user