Merge topic 'precompiled-field-map-permutation'

5498ecd35 Properly handle global (whole mesh) fields in data set filters
f8fd0ce31 Silence warning about cast losing precision
3c4e8a2ea Convert filters to use precompiled field map functions where applicable
98f20ec26 Use a worklet to permute fields rather than ArrayHandlePermutation
4a5dbb65d Convert CleanGrid (and dependents) to use precompiled field map
2383a7fff Add MapFieldPermutation function
b1f288aae Add non-templated base class to Keys class.
934732bb6 Add MapFieldPermutation function

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Robert Maynard <robert.maynard@kitware.com>
Merge-request: !1954
This commit is contained in:
Kenneth Moreland 2020-05-21 19:10:07 +00:00 committed by Kitware Robot
commit 1565d74163
96 changed files with 1656 additions and 677 deletions

@ -133,11 +133,10 @@ public:
return output; return output;
} }
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet&, VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>&, const vtkm::cont::Field&,
const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase<DerivedPolicy>)
vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
return false; return false;
} }

@ -84,6 +84,7 @@ public:
VTKM_CONT bool IsFieldCell() const { return this->FieldAssociation == Association::CELL_SET; } VTKM_CONT bool IsFieldCell() const { return this->FieldAssociation == Association::CELL_SET; }
VTKM_CONT bool IsFieldPoint() const { return this->FieldAssociation == Association::POINTS; } VTKM_CONT bool IsFieldPoint() const { return this->FieldAssociation == Association::POINTS; }
VTKM_CONT bool IsFieldGlobal() const { return this->FieldAssociation == Association::WHOLE_MESH; }
VTKM_CONT vtkm::Id GetNumberOfValues() const { return this->Data.GetNumberOfValues(); } VTKM_CONT vtkm::Id GetNumberOfValues() const { return this->Data.GetNumberOfValues(); }

@ -25,14 +25,8 @@ struct TypeCheckTagKeys
{ {
}; };
// A more specific specialization that actually checks for Keys types is // The specialization that actually checks for Keys types is implemented in vtkm/worklet/Keys.h.
// implemented in vtkm/worklet/Keys.h. That class is not accessible from here // That class is not accessible from here due to VTK-m package dependencies.
// due to VTK-m package dependencies.
template <typename Type>
struct TypeCheck<TypeCheckTagKeys, Type>
{
static constexpr bool value = false;
};
} }
} }
} // namespace vtkm::cont::arg } // namespace vtkm::cont::arg

@ -33,13 +33,13 @@ class ThreadIndicesReduceByKey : public vtkm::exec::arg::ThreadIndicesBasic
using Superclass = vtkm::exec::arg::ThreadIndicesBasic; using Superclass = vtkm::exec::arg::ThreadIndicesBasic;
public: public:
template <typename P1, typename P2, typename P3> template <typename P1, typename P2>
VTKM_EXEC ThreadIndicesReduceByKey( VTKM_EXEC ThreadIndicesReduceByKey(
vtkm::Id threadIndex, vtkm::Id threadIndex,
vtkm::Id inIndex, vtkm::Id inIndex,
vtkm::IdComponent visitIndex, vtkm::IdComponent visitIndex,
vtkm::Id outIndex, vtkm::Id outIndex,
const vtkm::exec::internal::ReduceByKeyLookup<P1, P2, P3>& keyLookup) const vtkm::exec::internal::ReduceByKeyLookupBase<P1, P2>& keyLookup)
: Superclass(threadIndex, inIndex, visitIndex, outIndex) : Superclass(threadIndex, inIndex, visitIndex, outIndex)
, ValueOffset(keyLookup.Offsets.Get(inIndex)) , ValueOffset(keyLookup.Offsets.Get(inIndex))
, NumberOfValues(keyLookup.Counts.Get(inIndex)) , NumberOfValues(keyLookup.Counts.Get(inIndex))

@ -24,6 +24,34 @@ namespace exec
namespace internal namespace internal
{ {
/// A superclass of `ReduceBykeyLookup` that can be used when no key values are provided.
///
template <typename IdPortalType, typename IdComponentPortalType>
struct ReduceByKeyLookupBase
{
VTKM_STATIC_ASSERT((std::is_same<typename IdPortalType::ValueType, vtkm::Id>::value));
VTKM_STATIC_ASSERT(
(std::is_same<typename IdComponentPortalType::ValueType, vtkm::IdComponent>::value));
IdPortalType SortedValuesMap;
IdPortalType Offsets;
IdComponentPortalType Counts;
VTKM_EXEC_CONT
ReduceByKeyLookupBase(const IdPortalType& sortedValuesMap,
const IdPortalType& offsets,
const IdComponentPortalType& counts)
: SortedValuesMap(sortedValuesMap)
, Offsets(offsets)
, Counts(counts)
{
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ReduceByKeyLookupBase() {}
};
/// \brief Execution object holding lookup info for reduce by key. /// \brief Execution object holding lookup info for reduce by key.
/// ///
/// A WorkletReduceByKey needs several arrays to map the current output object /// A WorkletReduceByKey needs several arrays to map the current output object
@ -31,28 +59,19 @@ namespace internal
/// state. /// state.
/// ///
template <typename KeyPortalType, typename IdPortalType, typename IdComponentPortalType> template <typename KeyPortalType, typename IdPortalType, typename IdComponentPortalType>
struct ReduceByKeyLookup : vtkm::cont::ExecutionObjectBase struct ReduceByKeyLookup : ReduceByKeyLookupBase<IdPortalType, IdComponentPortalType>
{ {
using KeyType = typename KeyPortalType::ValueType; using KeyType = typename KeyPortalType::ValueType;
VTKM_STATIC_ASSERT((std::is_same<typename IdPortalType::ValueType, vtkm::Id>::value));
VTKM_STATIC_ASSERT(
(std::is_same<typename IdComponentPortalType::ValueType, vtkm::IdComponent>::value));
KeyPortalType UniqueKeys; KeyPortalType UniqueKeys;
IdPortalType SortedValuesMap;
IdPortalType Offsets;
IdComponentPortalType Counts;
VTKM_EXEC_CONT VTKM_EXEC_CONT
ReduceByKeyLookup(const KeyPortalType& uniqueKeys, ReduceByKeyLookup(const KeyPortalType& uniqueKeys,
const IdPortalType& sortedValuesMap, const IdPortalType& sortedValuesMap,
const IdPortalType& offsets, const IdPortalType& offsets,
const IdComponentPortalType& counts) const IdComponentPortalType& counts)
: UniqueKeys(uniqueKeys) : ReduceByKeyLookupBase<IdPortalType, IdComponentPortalType>(sortedValuesMap, offsets, counts)
, SortedValuesMap(sortedValuesMap) , UniqueKeys(uniqueKeys)
, Offsets(offsets)
, Counts(counts)
{ {
} }

@ -45,6 +45,8 @@ set(headers
ImageMedian.h ImageMedian.h
Lagrangian.h Lagrangian.h
LagrangianStructures.h LagrangianStructures.h
MapFieldMergeAverage.h
MapFieldPermutation.h
Mask.h Mask.h
MaskPoints.h MaskPoints.h
MeshQuality.h MeshQuality.h
@ -150,10 +152,13 @@ set(sources_device
ContourInteger.cxx ContourInteger.cxx
ContourScalar.cxx ContourScalar.cxx
ExternalFaces.cxx ExternalFaces.cxx
ExtractGeometry.cxx
ExtractStructured.cxx ExtractStructured.cxx
GradientScalar.cxx GradientScalar.cxx
GradientUniformPoints.cxx GradientUniformPoints.cxx
GradientVector.cxx GradientVector.cxx
MapFieldMergeAverage.cxx
MapFieldPermutation.cxx
PointAverage.cxx PointAverage.cxx
Threshold.cxx Threshold.cxx
VectorMagnitude.cxx VectorMagnitude.cxx

@ -12,6 +12,9 @@
#include <vtkm/filter/CleanGrid.h> #include <vtkm/filter/CleanGrid.h>
#include <vtkm/filter/CleanGrid.hxx> #include <vtkm/filter/CleanGrid.hxx>
#include <vtkm/filter/MapFieldMergeAverage.h>
#include <vtkm/filter/MapFieldPermutation.h>
namespace vtkm namespace vtkm
{ {
namespace filter namespace filter
@ -116,6 +119,46 @@ vtkm::cont::DataSet CleanGrid::GenerateOutput(const vtkm::cont::DataSet& inData,
return outData; return outData;
} }
bool CleanGrid::MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field)
{
if (field.IsFieldPoint() && (this->GetCompactPointFields() || this->GetMergePoints()))
{
vtkm::cont::Field compactedField;
if (this->GetCompactPointFields())
{
bool success = vtkm::filter::MapFieldPermutation(
field, this->PointCompactor.GetPointScatter().GetOutputToInputMap(), compactedField);
if (!success)
{
return false;
}
}
else
{
compactedField = field;
}
if (this->GetMergePoints())
{
return vtkm::filter::MapFieldMergeAverage(
compactedField, this->PointMerger.GetMergeKeys(), result);
}
else
{
result.AddField(compactedField);
return true;
}
}
else if (field.IsFieldCell() && this->GetRemoveDegenerateCells())
{
return vtkm::filter::MapFieldPermutation(field, this->CellCompactor.GetValidCellIds(), result);
}
else
{
result.AddField(field);
return true;
}
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(CleanGrid); VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(CleanGrid);
} }

@ -87,40 +87,15 @@ public:
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData, VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData,
vtkm::filter::PolicyBase<Policy> policy); vtkm::filter::PolicyBase<Policy> policy);
VTKM_FILTER_EXPORT
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field);
template <typename ValueType, typename Storage, typename Policy> template <typename DerivedPolicy>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<ValueType, Storage>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase<DerivedPolicy>)
vtkm::filter::PolicyBase<Policy>)
{ {
if (fieldMeta.IsPointField() && (this->GetCompactPointFields() || this->GetMergePoints())) return this->MapFieldOntoOutput(result, field);
{
vtkm::cont::ArrayHandle<ValueType> compactedArray;
if (this->GetCompactPointFields())
{
compactedArray = this->PointCompactor.MapPointFieldDeep(input);
if (this->GetMergePoints())
{
compactedArray = this->PointMerger.MapPointField(compactedArray);
}
}
else if (this->GetMergePoints())
{
compactedArray = this->PointMerger.MapPointField(input);
}
result.AddField(fieldMeta.AsField(compactedArray));
}
else if (fieldMeta.IsCellField() && this->GetRemoveDegenerateCells())
{
result.AddField(fieldMeta.AsField(this->CellCompactor.ProcessCellField(input)));
}
else
{
result.AddField(fieldMeta.AsField(input));
}
return true;
} }
private: private:

@ -14,6 +14,8 @@
#include <vtkm/filter/vtkm_filter_export.h> #include <vtkm/filter/vtkm_filter_export.h>
#include <vtkm/filter/FilterDataSetWithField.h> #include <vtkm/filter/FilterDataSetWithField.h>
#include <vtkm/filter/MapFieldPermutation.h>
#include <vtkm/worklet/Clip.h> #include <vtkm/worklet/Clip.h>
namespace vtkm namespace vtkm
@ -46,6 +48,35 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy> policy); vtkm::filter::PolicyBase<DerivedPolicy> policy);
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy> policy)
{
if (field.IsFieldPoint())
{
// If the field is a point field, then we need to do a custom interpolation of the points.
// In this case, we need to call the superclass's MapFieldOntoOutput, which will in turn
// call our DoMapField.
return this->FilterDataSetWithField<ClipWithField>::MapFieldOntoOutput(result, field, policy);
}
else if (field.IsFieldCell())
{
// Use the precompiled field permutation function.
vtkm::cont::ArrayHandle<vtkm::Id> permutation = this->Worklet.GetCellMapOutputToInput();
return vtkm::filter::MapFieldPermutation(field, permutation, result);
}
else if (field.IsFieldGlobal())
{
result.AddField(field);
return true;
}
else
{
return false;
}
}
//Map a new field onto the resulting dataset after running the filter. //Map a new field onto the resulting dataset after running the filter.
//This call is only valid after Execute has been called. //This call is only valid after Execute has been called.
template <typename T, typename StorageType, typename DerivedPolicy> template <typename T, typename StorageType, typename DerivedPolicy>
@ -54,20 +85,11 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy>) vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
vtkm::cont::ArrayHandle<T> output; // All other conditions should be handled by MapFieldOntoOutput directly.
VTKM_ASSERT(fieldMeta.IsPointField());
if (fieldMeta.IsPointField()) vtkm::cont::ArrayHandle<T> output;
{ output = this->Worklet.ProcessPointField(input);
output = this->Worklet.ProcessPointField(input);
}
else if (fieldMeta.IsCellField())
{
output = this->Worklet.ProcessCellField(input);
}
else
{
return false;
}
//use the same meta data as the input so we get the same field name, etc. //use the same meta data as the input so we get the same field name, etc.
result.AddField(fieldMeta.AsField(output)); result.AddField(fieldMeta.AsField(output));

@ -14,6 +14,7 @@
#include <vtkm/cont/ImplicitFunctionHandle.h> #include <vtkm/cont/ImplicitFunctionHandle.h>
#include <vtkm/filter/FilterDataSet.h> #include <vtkm/filter/FilterDataSet.h>
#include <vtkm/filter/MapFieldPermutation.h>
#include <vtkm/worklet/Clip.h> #include <vtkm/worklet/Clip.h>
namespace vtkm namespace vtkm
@ -43,6 +44,36 @@ public:
vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<DerivedPolicy> policy); vtkm::filter::PolicyBase<DerivedPolicy> policy);
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy> policy)
{
if (field.IsFieldPoint())
{
// If the field is a point field, then we need to do a custom interpolation of the points.
// In this case, we need to call the superclass's MapFieldOntoOutput, which will in turn
// call our DoMapField.
return this->FilterDataSet<ClipWithImplicitFunction>::MapFieldOntoOutput(
result, field, policy);
}
else if (field.IsFieldCell())
{
// Use the precompiled field permutation function.
vtkm::cont::ArrayHandle<vtkm::Id> permutation = this->Worklet.GetCellMapOutputToInput();
return vtkm::filter::MapFieldPermutation(field, permutation, result);
}
else if (field.IsFieldGlobal())
{
result.AddField(field);
return true;
}
else
{
return false;
}
}
//Map a new field onto the resulting dataset after running the filter. //Map a new field onto the resulting dataset after running the filter.
//This call is only valid after Execute has been called. //This call is only valid after Execute has been called.
template <typename T, typename StorageType, typename DerivedPolicy> template <typename T, typename StorageType, typename DerivedPolicy>
@ -51,24 +82,14 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy>) vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
vtkm::cont::ArrayHandle<T> output; // All other conditions should be handled by MapFieldOntoOutput directly.
VTKM_ASSERT(fieldMeta.IsPointField());
if (fieldMeta.IsPointField()) vtkm::cont::ArrayHandle<T> output;
{ output = this->Worklet.ProcessPointField(input);
output = this->Worklet.ProcessPointField(input);
}
else if (fieldMeta.IsCellField())
{
output = this->Worklet.ProcessCellField(input);
}
else
{
return false;
}
//use the same meta data as the input so we get the same field name, etc. //use the same meta data as the input so we get the same field name, etc.
result.AddField(fieldMeta.AsField(output)); result.AddField(fieldMeta.AsField(output));
return true; return true;
} }

@ -14,6 +14,8 @@
#include <vtkm/filter/vtkm_filter_export.h> #include <vtkm/filter/vtkm_filter_export.h>
#include <vtkm/filter/FilterDataSetWithField.h> #include <vtkm/filter/FilterDataSetWithField.h>
#include <vtkm/filter/MapFieldPermutation.h>
#include <vtkm/worklet/Contour.h> #include <vtkm/worklet/Contour.h>
namespace vtkm namespace vtkm
@ -111,6 +113,35 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy> policy); vtkm::filter::PolicyBase<DerivedPolicy> policy);
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy> policy)
{
if (field.IsFieldPoint())
{
// If the field is a point field, then we need to do a custom interpolation of the points.
// In this case, we need to call the superclass's MapFieldOntoOutput, which will in turn
// call our DoMapField.
return this->FilterDataSetWithField<Contour>::MapFieldOntoOutput(result, field, policy);
}
else if (field.IsFieldCell())
{
// Use the precompiled field permutation function.
vtkm::cont::ArrayHandle<vtkm::Id> permutation = this->Worklet.GetCellIdMap();
return vtkm::filter::MapFieldPermutation(field, permutation, result);
}
else if (field.IsFieldGlobal())
{
result.AddField(field);
return true;
}
else
{
return false;
}
}
//Map a new field onto the resulting dataset after running the filter //Map a new field onto the resulting dataset after running the filter
//this call is only valid //this call is only valid
template <typename T, typename StorageType, typename DerivedPolicy> template <typename T, typename StorageType, typename DerivedPolicy>
@ -119,20 +150,12 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy>) vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
// All other conditions should be handled by MapFieldOntoOutput directly.
VTKM_ASSERT(fieldMeta.IsPointField());
vtkm::cont::ArrayHandle<T> fieldArray; vtkm::cont::ArrayHandle<T> fieldArray;
if (fieldMeta.IsPointField()) fieldArray = this->Worklet.ProcessPointField(input);
{
fieldArray = this->Worklet.ProcessPointField(input);
}
else if (fieldMeta.IsCellField())
{
fieldArray = this->Worklet.ProcessCellField(input);
}
else
{
return false;
}
//use the same meta data as the input so we get the same field name, etc. //use the same meta data as the input so we get the same field name, etc.
result.AddField(fieldMeta.AsField(fieldArray)); result.AddField(fieldMeta.AsField(fieldArray));

@ -64,6 +64,35 @@ vtkm::cont::DataSet ExternalFaces::GenerateOutput(const vtkm::cont::DataSet& inp
} }
} }
bool ExternalFaces::MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field)
{
if (field.IsFieldPoint())
{
if (this->CompactPoints)
{
return this->Compactor.MapFieldOntoOutput(result, field);
}
else
{
result.AddField(field);
return true;
}
}
else if (field.IsFieldCell())
{
return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetCellIdMap(), result);
}
else if (field.IsFieldGlobal())
{
result.AddField(field);
return true;
}
else
{
return false;
}
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(ExternalFaces); VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(ExternalFaces);
} }

@ -15,6 +15,7 @@
#include <vtkm/filter/CleanGrid.h> #include <vtkm/filter/CleanGrid.h>
#include <vtkm/filter/FilterDataSet.h> #include <vtkm/filter/FilterDataSet.h>
#include <vtkm/filter/MapFieldPermutation.h>
#include <vtkm/worklet/ExternalFaces.h> #include <vtkm/worklet/ExternalFaces.h>
namespace vtkm namespace vtkm
@ -59,35 +60,15 @@ public:
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<DerivedPolicy> policy); vtkm::filter::PolicyBase<DerivedPolicy> policy);
//Map a new field onto the resulting dataset after running the filter VTKM_FILTER_EXPORT VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
//this call is only valid const vtkm::cont::Field& field);
template <typename T, typename StorageType, typename DerivedPolicy>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy> policy)
{
if (fieldMeta.IsPointField())
{
if (this->CompactPoints)
{
return this->Compactor.DoMapField(result, input, fieldMeta, policy);
}
else
{
result.AddField(fieldMeta.AsField(input));
return true;
}
}
else if (fieldMeta.IsCellField())
{
vtkm::cont::ArrayHandle<T> fieldArray;
fieldArray = this->Worklet.ProcessCellField(input);
result.AddField(fieldMeta.AsField(fieldArray));
return true;
}
return false; template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
return this->MapFieldOntoOutput(result, field);
} }
private: private:

@ -0,0 +1,56 @@
//============================================================================
// 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.
//============================================================================
#define vtkm_filter_ExtractGeometry_cxx
#include <vtkm/filter/ExtractGeometry.h>
#include <vtkm/filter/MapFieldPermutation.h>
namespace vtkm
{
namespace filter
{
//-----------------------------------------------------------------------------
VTKM_FILTER_EXPORT ExtractGeometry::ExtractGeometry()
: vtkm::filter::FilterDataSet<ExtractGeometry>()
, ExtractInside(true)
, ExtractBoundaryCells(false)
, ExtractOnlyBoundaryCells(false)
{
}
VTKM_FILTER_EXPORT bool ExtractGeometry::MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field)
{
if (field.IsFieldPoint())
{
result.AddField(field);
return true;
}
else if (field.IsFieldCell())
{
vtkm::cont::ArrayHandle<vtkm::Id> permutation = this->Worklet.GetValidCellIds();
return vtkm::filter::MapFieldPermutation(field, permutation, result);
}
else if (field.IsFieldGlobal())
{
result.AddField(field);
return true;
}
else
{
return false;
}
}
//-----------------------------------------------------------------------------
VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(ExtractGeometry);
}
} // namespace vtkm::filter

@ -11,6 +11,8 @@
#ifndef vtk_m_filter_ExtractGeometry_h #ifndef vtk_m_filter_ExtractGeometry_h
#define vtk_m_filter_ExtractGeometry_h #define vtk_m_filter_ExtractGeometry_h
#include <vtkm/filter/vtkm_filter_export.h>
#include <vtkm/cont/ImplicitFunctionHandle.h> #include <vtkm/cont/ImplicitFunctionHandle.h>
#include <vtkm/filter/FilterDataSet.h> #include <vtkm/filter/FilterDataSet.h>
#include <vtkm/worklet/ExtractGeometry.h> #include <vtkm/worklet/ExtractGeometry.h>
@ -35,14 +37,13 @@ namespace filter
/// This differs from Clip in that Clip will subdivide boundary cells into new /// This differs from Clip in that Clip will subdivide boundary cells into new
/// cells, while this filter will not, producing a more 'crinkly' output. /// cells, while this filter will not, producing a more 'crinkly' output.
/// ///
class ExtractGeometry : public vtkm::filter::FilterDataSet<ExtractGeometry> class VTKM_ALWAYS_EXPORT ExtractGeometry : public vtkm::filter::FilterDataSet<ExtractGeometry>
{ {
public: public:
//currently the ExtractGeometry filter only works on scalar data. //currently the ExtractGeometry filter only works on scalar data.
using SupportedTypes = TypeListScalarAll; using SupportedTypes = TypeListScalarAll;
VTKM_CONT VTKM_FILTER_EXPORT VTKM_CONT ExtractGeometry();
ExtractGeometry();
// Set the volume of interest to extract // Set the volume of interest to extract
void SetImplicitFunction(const vtkm::cont::ImplicitFunctionHandle& func) void SetImplicitFunction(const vtkm::cont::ImplicitFunctionHandle& func)
@ -83,12 +84,16 @@ public:
vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
//Map a new field onto the resulting dataset after running the filter VTKM_FILTER_EXPORT VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
template <typename T, typename StorageType, typename DerivedPolicy> const vtkm::cont::Field& field);
bool DoMapField(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, template <typename DerivedPolicy>
const vtkm::filter::FieldMetadata& fieldMeta, VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
return this->MapFieldOntoOutput(result, field);
}
private: private:
bool ExtractInside; bool ExtractInside;
@ -97,6 +102,10 @@ private:
vtkm::cont::ImplicitFunctionHandle Function; vtkm::cont::ImplicitFunctionHandle Function;
vtkm::worklet::ExtractGeometry Worklet; vtkm::worklet::ExtractGeometry Worklet;
}; };
#ifndef vtkm_filter_ExtractGeometry_cxx
VTKM_FILTER_EXPORT_EXECUTE_METHOD(ExtractGeometry);
#endif
} }
} // namespace vtkm::filter } // namespace vtkm::filter

@ -65,15 +65,6 @@ namespace vtkm
namespace filter namespace filter
{ {
//-----------------------------------------------------------------------------
inline VTKM_CONT ExtractGeometry::ExtractGeometry()
: vtkm::filter::FilterDataSet<ExtractGeometry>()
, ExtractInside(true)
, ExtractBoundaryCells(false)
, ExtractOnlyBoundaryCells(false)
{
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename DerivedPolicy> template <typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::DataSet ExtractGeometry::DoExecute( inline VTKM_CONT vtkm::cont::DataSet ExtractGeometry::DoExecute(
@ -101,34 +92,6 @@ inline VTKM_CONT vtkm::cont::DataSet ExtractGeometry::DoExecute(
output.SetCellSet(outCells); output.SetCellSet(outCells);
return output; return output;
} }
//-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy>
inline VTKM_CONT bool ExtractGeometry::DoMapField(
vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
vtkm::cont::VariantArrayHandle output;
if (fieldMeta.IsPointField())
{
output = input; // pass through, points aren't changed.
}
else if (fieldMeta.IsCellField())
{
output = this->Worklet.ProcessCellField(input);
}
else
{
return false;
}
// use the same meta data as the input so we get the same field name, etc.
result.AddField(fieldMeta.AsField(output));
return true;
}
} }
} }

@ -64,11 +64,10 @@ public:
vtkm::filter::PolicyBase<DerivedPolicy> policy); vtkm::filter::PolicyBase<DerivedPolicy> policy);
//Map a new field onto the resulting dataset after running the filter //Map a new field onto the resulting dataset after running the filter
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
bool DoMapField(vtkm::cont::DataSet& result, VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase<DerivedPolicy>);
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private: private:
bool ExtractInside; bool ExtractInside;

@ -65,29 +65,35 @@ inline vtkm::cont::DataSet ExtractPoints::DoExecute(const vtkm::cont::DataSet& i
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
inline VTKM_CONT bool ExtractPoints::DoMapField( inline VTKM_CONT bool ExtractPoints::MapFieldOntoOutput(
vtkm::cont::DataSet& result, vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy> policy) vtkm::filter::PolicyBase<DerivedPolicy> policy)
{ {
// point data is copied as is because it was not collapsed // point data is copied as is because it was not collapsed
if (fieldMeta.IsPointField()) if (field.IsFieldPoint())
{ {
if (this->CompactPoints) if (this->CompactPoints)
{ {
return this->Compactor.DoMapField(result, input, fieldMeta, policy); return this->Compactor.MapFieldOntoOutput(result, field, policy);
} }
else else
{ {
result.AddField(fieldMeta.AsField(input)); result.AddField(field);
return true; return true;
} }
} }
else if (field.IsFieldGlobal())
// cell data does not apply {
return false; result.AddField(field);
return true;
}
else
{
// cell data does not apply
return false;
}
} }
} }
} }

@ -10,6 +10,8 @@
#define vtkm_filter_ExtractStructured_cxx #define vtkm_filter_ExtractStructured_cxx
#include <vtkm/filter/ExtractStructured.h> #include <vtkm/filter/ExtractStructured.h>
#include <vtkm/filter/MapFieldPermutation.h>
namespace vtkm namespace vtkm
{ {
namespace filter namespace filter
@ -26,6 +28,36 @@ ExtractStructured::ExtractStructured()
{ {
} }
//-----------------------------------------------------------------------------
bool ExtractStructured::MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field)
{
if (field.IsFieldPoint())
{
return vtkm::filter::MapFieldPermutation(field, this->PointFieldMap, result);
}
else if (field.IsFieldCell())
{
return vtkm::filter::MapFieldPermutation(field, this->CellFieldMap, result);
}
else if (field.IsFieldGlobal())
{
result.AddField(field);
return true;
}
else
{
return false;
}
}
//-----------------------------------------------------------------------------
void ExtractStructured::PostExecute(const vtkm::cont::PartitionedDataSet&,
vtkm::cont::PartitionedDataSet&)
{
this->CellFieldMap.ReleaseResources();
this->PointFieldMap.ReleaseResources();
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(ExtractStructured); VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(ExtractStructured);

@ -87,31 +87,27 @@ public:
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<DerivedPolicy> policy); vtkm::filter::PolicyBase<DerivedPolicy> policy);
// Map new field onto the resulting dataset after running the filter VTKM_FILTER_EXPORT VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
template <typename T, typename StorageType, typename DerivedPolicy> const vtkm::cont::Field& field);
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, template <typename DerivedPolicy>
const vtkm::filter::FieldMetadata& fieldMeta, VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
vtkm::filter::PolicyBase<DerivedPolicy>) const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
if (fieldMeta.IsPointField()) return this->MapFieldOntoOutput(result, field);
{ }
vtkm::cont::ArrayHandle<T> output = this->Worklet.ProcessPointField(input);
result.AddField(fieldMeta.AsField(output));
return true;
}
// cell data must be scattered to the cells created per input cell VTKM_FILTER_EXPORT VTKM_CONT void PostExecute(const vtkm::cont::PartitionedDataSet&,
if (fieldMeta.IsCellField()) vtkm::cont::PartitionedDataSet&);
{
vtkm::cont::ArrayHandle<T> output = this->Worklet.ProcessCellField(input);
result.AddField(fieldMeta.AsField(output)); template <typename DerivedPolicy>
return true; VTKM_CONT void PostExecute(const vtkm::cont::PartitionedDataSet& input,
} vtkm::cont::PartitionedDataSet& output,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
return false; {
this->PostExecute(input, output);
} }
private: private:
@ -120,6 +116,9 @@ private:
bool IncludeBoundary; bool IncludeBoundary;
bool IncludeOffset; bool IncludeOffset;
vtkm::worklet::ExtractStructured Worklet; vtkm::worklet::ExtractStructured Worklet;
vtkm::cont::ArrayHandle<vtkm::Id> CellFieldMap;
vtkm::cont::ArrayHandle<vtkm::Id> PointFieldMap;
}; };
#ifndef vtkm_filter_ExtractStructured_cxx #ifndef vtkm_filter_ExtractStructured_cxx
@ -128,6 +127,8 @@ VTKM_FILTER_EXPORT_EXECUTE_METHOD(ExtractStructured);
} }
} // namespace vtkm::filter } // namespace vtkm::filter
#ifndef vtk_m_filter_ExtractStructured_hxx
#include <vtkm/filter/ExtractStructured.hxx> #include <vtkm/filter/ExtractStructured.hxx>
#endif
#endif // vtk_m_filter_ExtractStructured_h #endif // vtk_m_filter_ExtractStructured_h

@ -10,6 +10,7 @@
#ifndef vtk_m_filter_ExtractStructured_hxx #ifndef vtk_m_filter_ExtractStructured_hxx
#define vtk_m_filter_ExtractStructured_hxx #define vtk_m_filter_ExtractStructured_hxx
#include <vtkm/filter/ExtractStructured.h>
namespace vtkm namespace vtkm
{ {
@ -36,6 +37,14 @@ inline VTKM_CONT vtkm::cont::DataSet ExtractStructured::DoExecute(
vtkm::cont::DataSet output; vtkm::cont::DataSet output;
output.SetCellSet(vtkm::cont::DynamicCellSet(cellset)); output.SetCellSet(vtkm::cont::DynamicCellSet(cellset));
output.AddCoordinateSystem(outputCoordinates); output.AddCoordinateSystem(outputCoordinates);
// Create map arrays for mapping fields. Could potentially save some time to first check to see
// if these arrays would be used.
this->CellFieldMap =
this->Worklet.ProcessCellField(vtkm::cont::ArrayHandleIndex(input.GetNumberOfCells()));
this->PointFieldMap =
this->Worklet.ProcessPointField(vtkm::cont::ArrayHandleIndex(input.GetNumberOfPoints()));
return output; return output;
} }
} }

@ -63,12 +63,11 @@ public:
vtkm::filter::PolicyBase<DerivedPolicy> policy); vtkm::filter::PolicyBase<DerivedPolicy> policy);
//Map a new field onto the resulting dataset after running the filter //Map a new field onto the resulting dataset after running the filter
//this call is only valid //this call is only valid after DoExecute is run
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase<DerivedPolicy> policy);
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private: private:
bool RemoveAll; bool RemoveAll;

@ -19,6 +19,7 @@
#include <vtkm/RangeId3.h> #include <vtkm/RangeId3.h>
#include <vtkm/filter/ExtractStructured.h> #include <vtkm/filter/ExtractStructured.h>
#include <vtkm/filter/MapFieldPermutation.h>
#include <vtkm/worklet/CellDeepCopy.h> #include <vtkm/worklet/CellDeepCopy.h>
namespace namespace
@ -360,23 +361,24 @@ inline VTKM_CONT vtkm::cont::DataSet GhostCellRemove::DoExecute(
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
inline VTKM_CONT bool GhostCellRemove::DoMapField( VTKM_CONT bool GhostCellRemove::MapFieldOntoOutput(vtkm::cont::DataSet& result,
vtkm::cont::DataSet& result, const vtkm::cont::Field& field,
const vtkm::cont::ArrayHandle<T, StorageType>& input, vtkm::filter::PolicyBase<DerivedPolicy>)
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
if (fieldMeta.IsPointField()) if (field.IsFieldPoint())
{ {
//we copy the input handle to the result dataset, reusing the metadata //we copy the input handle to the result dataset, reusing the metadata
result.AddField(fieldMeta.AsField(input)); result.AddField(field);
return true; return true;
} }
else if (fieldMeta.IsCellField()) else if (field.IsFieldCell())
{ {
vtkm::cont::ArrayHandle<T> out = this->Worklet.ProcessCellField(input); return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetValidCellIds(), result);
result.AddField(fieldMeta.AsField(out)); }
else if (field.IsFieldGlobal())
{
result.AddField(field);
return true; return true;
} }
else else

@ -79,11 +79,10 @@ public:
vtkm::filter::PolicyBase<DerivedPolicy> policy); vtkm::filter::PolicyBase<DerivedPolicy> policy);
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase<DerivedPolicy> policy);
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private: private:
vtkm::Id rank; vtkm::Id rank;

@ -326,13 +326,20 @@ inline VTKM_CONT vtkm::cont::DataSet Lagrangian::DoExecute(
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
inline VTKM_CONT bool Lagrangian::DoMapField(vtkm::cont::DataSet&, inline VTKM_CONT bool Lagrangian::MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>&, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase<DerivedPolicy>)
const vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
return false; if (field.IsFieldGlobal())
{
result.AddField(field);
return true;
}
else
{
return false;
}
} }
} }
} // namespace vtkm::filter } // namespace vtkm::filter

@ -67,12 +67,11 @@ public:
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
//Map a new field onto the resulting dataset after running the filter //Map a new field onto the resulting dataset after running the filter
//this call is only valid //this call is only valid after calling DoExecute
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase<DerivedPolicy> policy);
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private: private:
vtkm::FloatDefault StepSize; vtkm::FloatDefault StepSize;

@ -155,14 +155,21 @@ inline VTKM_CONT vtkm::cont::DataSet LagrangianStructures::DoExecute(
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
inline VTKM_CONT bool LagrangianStructures::DoMapField( inline VTKM_CONT bool LagrangianStructures::MapFieldOntoOutput(
vtkm::cont::DataSet&, vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>&, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata&,
vtkm::filter::PolicyBase<DerivedPolicy>) vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
return false; if (field.IsFieldGlobal())
{
result.AddField(field);
return true;
}
else
{
return false;
}
} }
} }
} // namespace vtkm::filter } // namespace vtkm::filter

@ -0,0 +1,69 @@
//============================================================================
// 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/filter/MapFieldMergeAverage.h>
#include <vtkm/cont/Logging.h>
#include <vtkm/worklet/AverageByKey.h>
#include <vtkm/filter/PolicyDefault.h>
namespace
{
struct DoMapFieldMerge
{
bool CalledMap = false;
template <typename T, typename S>
void operator()(const vtkm::cont::ArrayHandle<T, S>& inputArray,
const vtkm::worklet::internal::KeysBase& keys,
vtkm::cont::VariantArrayHandle& output)
{
vtkm::cont::ArrayHandle<T> outputArray = vtkm::worklet::AverageByKey::Run(keys, inputArray);
output = vtkm::cont::VariantArrayHandle(outputArray);
this->CalledMap = true;
}
};
} // anonymous namespace
bool vtkm::filter::MapFieldMergeAverage(const vtkm::cont::Field& inputField,
const vtkm::worklet::internal::KeysBase& keys,
vtkm::cont::Field& outputField)
{
vtkm::cont::VariantArrayHandle outputArray;
DoMapFieldMerge functor;
inputField.GetData().ResetTypes<vtkm::TypeListAll>().CastAndCall(
vtkm::filter::PolicyDefault::StorageList{}, functor, keys, outputArray);
if (functor.CalledMap)
{
outputField = vtkm::cont::Field(inputField.GetName(), inputField.GetAssociation(), outputArray);
}
else
{
VTKM_LOG_S(vtkm::cont::LogLevel::Warn, "Faild to map field " << inputField.GetName());
}
return functor.CalledMap;
}
bool vtkm::filter::MapFieldMergeAverage(const vtkm::cont::Field& inputField,
const vtkm::worklet::internal::KeysBase& keys,
vtkm::cont::DataSet& outputData)
{
vtkm::cont::Field outputField;
bool success = vtkm::filter::MapFieldMergeAverage(inputField, keys, outputField);
if (success)
{
outputData.AddField(outputField);
}
return success;
}

@ -0,0 +1,73 @@
//============================================================================
// 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_MapFieldMergeAverage_h
#define vtk_m_filter_MapFieldMergeAverage_h
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/Field.h>
#include <vtkm/worklet/Keys.h>
#include <vtkm/filter/vtkm_filter_export.h>
namespace vtkm
{
namespace filter
{
/// \brief Maps a field by merging entries based on a keys object.
///
/// This method will create a new field containing the data from the provided `inputField` but but
/// with groups of entities merged together. The input `keys` object encapsulates which elements
/// should be merged together. A group of elements merged together will be averaged. The result is
/// placed in `outputField`.
///
/// The intention of this method is to implement the `MapFieldOntoOutput` methods in filters (many
/// of which require this merge of a field), but can be used in other places as well.
///
/// `outputField` is set to have the same metadata as the input. If the metadata needs to change
/// (such as the name or the association) that should be done after the function returns.
///
/// This function returns whether the field was successfully merged. If the returned result is
/// `true`, then the results in `outputField` are valid. If it is `false`, then `outputField`
/// should not be used.
///
VTKM_FILTER_EXPORT VTKM_CONT bool MapFieldMergeAverage(
const vtkm::cont::Field& inputField,
const vtkm::worklet::internal::KeysBase& keys,
vtkm::cont::Field& outputField);
/// \brief Maps a field by merging entries based on a keys object.
///
/// This method will create a new field containing the data from the provided `inputField` but but
/// with groups of entities merged together. The input `keys` object encapsulates which elements
/// should be merged together. A group of elements merged together will be averaged.
///
/// The intention of this method is to implement the `MapFieldOntoOutput` methods in filters (many
/// of which require this merge of a field), but can be used in other places as well. The
/// resulting field is put in the given `DataSet`.
///
/// The returned `Field` has the same metadata as the input. If the metadata needs to change (such
/// as the name or the association), then a different form of `MapFieldMergeAverage` should be used.
///
/// This function returns whether the field was successfully merged. If the returned result is
/// `true`, then `outputData` has the merged field. If it is `false`, then the field is not
/// placed in `outputData`.
///
VTKM_FILTER_EXPORT VTKM_CONT bool MapFieldMergeAverage(
const vtkm::cont::Field& inputField,
const vtkm::worklet::internal::KeysBase& keys,
vtkm::cont::DataSet& outputData);
}
} // namespace vtkm::filter
#endif //vtk_m_filter_MapFieldMergeAverage_h

@ -0,0 +1,137 @@
//============================================================================
// 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/filter/MapFieldPermutation.h>
#include <vtkm/TypeList.h>
#include <vtkm/TypeTraits.h>
#include <vtkm/VecTraits.h>
#include <vtkm/cont/Logging.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/filter/PolicyDefault.h>
namespace
{
template <typename T>
struct MapPermutationWorklet : vtkm::worklet::WorkletMapField
{
T InvalidValue;
explicit MapPermutationWorklet(T invalidValue)
: InvalidValue(invalidValue)
{
}
using ControlSignature = void(FieldIn permutationIndex, WholeArrayIn input, FieldOut output);
template <typename InputPortalType>
VTKM_EXEC void operator()(vtkm::Id permutationIndex, InputPortalType inputPortal, T& output) const
{
if ((permutationIndex >= 0) && (permutationIndex < inputPortal.GetNumberOfValues()))
{
output = inputPortal.Get(permutationIndex);
}
else
{
output = this->InvalidValue;
}
}
};
// For simplicity, the invalid value is specified as a single type (vtkm::Float64), and this is
// often a non-finite value, which is not well represented by integer types. This function does its
// best to find a reasonable cast for the value.
template <typename T>
T CastInvalidValue(vtkm::Float64 invalidValue)
{
using ComponentType = typename vtkm::VecTraits<T>::BaseComponentType;
if (std::is_same<vtkm::TypeTraitsIntegerTag, typename vtkm::TypeTraits<T>::NumericTag>::value)
{
// Casting to integer types
if (vtkm::IsFinite(invalidValue))
{
return T(static_cast<ComponentType>(invalidValue));
}
else if (vtkm::IsInf(invalidValue) && (invalidValue > 0))
{
return T(std::numeric_limits<ComponentType>::max());
}
else
{
return T(std::numeric_limits<ComponentType>::min());
}
}
else
{
// Not an integer type. Assume can be directly cast
return T(static_cast<ComponentType>(invalidValue));
}
}
struct DoMapFieldPermutation
{
bool CalledMap = false;
template <typename T, typename S>
void operator()(const vtkm::cont::ArrayHandle<T, S>& inputArray,
const vtkm::cont::ArrayHandle<vtkm::Id>& permutation,
vtkm::cont::VariantArrayHandle& output,
vtkm::Float64 invalidValue)
{
vtkm::cont::ArrayHandle<T> outputArray;
MapPermutationWorklet<T> worklet(CastInvalidValue<T>(invalidValue));
vtkm::cont::Invoker invoke;
invoke(worklet, permutation, inputArray, outputArray);
output = vtkm::cont::VariantArrayHandle(outputArray);
this->CalledMap = true;
}
};
} // anonymous namespace
bool vtkm::filter::MapFieldPermutation(const vtkm::cont::Field& inputField,
const vtkm::cont::ArrayHandle<vtkm::Id>& permutation,
vtkm::cont::Field& outputField,
vtkm::Float64 invalidValue)
{
vtkm::cont::VariantArrayHandle outputArray;
DoMapFieldPermutation functor;
inputField.GetData().ResetTypes<vtkm::TypeListAll>().CastAndCall(
vtkm::filter::PolicyDefault::StorageList{}, functor, permutation, outputArray, invalidValue);
if (functor.CalledMap)
{
outputField = vtkm::cont::Field(inputField.GetName(), inputField.GetAssociation(), outputArray);
}
else
{
VTKM_LOG_S(vtkm::cont::LogLevel::Warn, "Faild to map field " << inputField.GetName());
}
return functor.CalledMap;
}
bool vtkm::filter::MapFieldPermutation(const vtkm::cont::Field& inputField,
const vtkm::cont::ArrayHandle<vtkm::Id>& permutation,
vtkm::cont::DataSet& outputData,
vtkm::Float64 invalidValue)
{
vtkm::cont::Field outputField;
bool success =
vtkm::filter::MapFieldPermutation(inputField, permutation, outputField, invalidValue);
if (success)
{
outputData.AddField(outputField);
}
return success;
}

@ -0,0 +1,82 @@
//============================================================================
// 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_MapFieldPermutation_h
#define vtk_m_filter_MapFieldPermutation_h
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/Field.h>
#include <vtkm/filter/vtkm_filter_export.h>
namespace vtkm
{
namespace filter
{
/// \brief Maps a field by permuting it by a given index array.
///
/// This method will create a new field containing the data from the provided `inputField` but
/// reorded by the given `permutation` index array. The value in the resulting field for index _i_
/// will be be a value from `inputField`, but comes from the index that comes from `permutation` at
/// position _i_. The result is placed in `outputField`.
///
/// The intention of this method is to implement the `MapFieldOntoOutput` methods in filters (many
/// of which require this permutation of a field), but can be used in other places as well.
///
/// `outputField` is set to have the same metadata as the input. If the metadata needs to change
/// (such as the name or the association) that should be done after the function returns.
///
/// This function returns whether the field was successfully permuted. If the returned result is
/// `true`, then the results in `outputField` are valid. If it is `false`, then `outputField`
/// should not be used.
///
/// If an invalid index is given in the permutation array (i.e. less than 0 or greater than the
/// size of the array), then the resulting outputField will be given `invalidValue` (converted as
/// best as possible to the correct data type).
///
VTKM_FILTER_EXPORT VTKM_CONT bool MapFieldPermutation(
const vtkm::cont::Field& inputField,
const vtkm::cont::ArrayHandle<vtkm::Id>& permutation,
vtkm::cont::Field& outputField,
vtkm::Float64 invalidValue = vtkm::Nan<vtkm::Float64>());
/// \brief Maps a field by permuting it by a given index array.
///
/// This method will create a new field containing the data from the provided `inputField` but
/// reorded by the given `permutation` index array. The value in the resulting field for index _i_
/// will be be a value from `inputField`, but comes from the index that comes from `permutation` at
/// position _i_.
///
/// The intention of this method is to implement the `MapFieldOntoOutput` methods in filters (many
/// of which require this permutation of a field), but can be used in other places as well. The
/// resulting field is put in the given `DataSet`.
///
/// The returned `Field` has the same metadata as the input. If the metadata needs to change (such
/// as the name or the association), then a different form of `MapFieldPermutation` should be used.
///
/// This function returns whether the field was successfully permuted. If the returned result is
/// `true`, then `outputData` has the permuted field. If it is `false`, then the field is not
/// placed in `outputData`.
///
/// If an invalid index is given in the permutation array (i.e. less than 0 or greater than the
/// size of the array), then the resulting outputField will be given `invalidValue` (converted as
/// best as possible to the correct data type).
///
VTKM_FILTER_EXPORT VTKM_CONT bool MapFieldPermutation(
const vtkm::cont::Field& inputField,
const vtkm::cont::ArrayHandle<vtkm::Id>& permutation,
vtkm::cont::DataSet& outputData,
vtkm::Float64 invalidValue = vtkm::Nan<vtkm::Float64>());
}
} // namespace vtkm::filter
#endif //vtk_m_filter_MapFieldPermutation_h

@ -45,11 +45,10 @@ public:
vtkm::filter::PolicyBase<DerivedPolicy> policy); vtkm::filter::PolicyBase<DerivedPolicy> policy);
//Map a new field onto the resulting dataset after running the filter //Map a new field onto the resulting dataset after running the filter
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase<DerivedPolicy> policy);
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private: private:
vtkm::Id Stride; vtkm::Id Stride;

@ -10,6 +10,8 @@
#ifndef vtk_m_filter_Mask_hxx #ifndef vtk_m_filter_Mask_hxx
#define vtk_m_filter_Mask_hxx #define vtk_m_filter_Mask_hxx
#include <vtkm/filter/MapFieldPermutation.h>
namespace namespace
{ {
@ -66,29 +68,24 @@ inline VTKM_CONT vtkm::cont::DataSet Mask::DoExecute(const vtkm::cont::DataSet&
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
inline VTKM_CONT bool Mask::DoMapField(vtkm::cont::DataSet& result, inline VTKM_CONT bool Mask::MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase<DerivedPolicy>)
vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
vtkm::cont::Field output; if (field.IsFieldPoint() || field.IsFieldGlobal())
if (fieldMeta.IsPointField())
{ {
output = fieldMeta.AsField(input); // pass through result.AddField(field); // pass through
return true;
} }
else if (fieldMeta.IsCellField()) else if (field.IsFieldCell())
{ {
output = fieldMeta.AsField(this->Worklet.ProcessCellField(input)); return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetValidCellIds(), result);
} }
else else
{ {
return false; return false;
} }
result.AddField(output);
return true;
} }
} }
} }

@ -46,11 +46,10 @@ public:
vtkm::filter::PolicyBase<DerivedPolicy> policy); vtkm::filter::PolicyBase<DerivedPolicy> policy);
//Map a new field onto the resulting dataset after running the filter //Map a new field onto the resulting dataset after running the filter
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase<DerivedPolicy>);
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private: private:
vtkm::Id Stride; vtkm::Id Stride;

@ -58,28 +58,34 @@ inline VTKM_CONT vtkm::cont::DataSet MaskPoints::DoExecute(
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
inline VTKM_CONT bool MaskPoints::DoMapField(vtkm::cont::DataSet& result, inline VTKM_CONT bool MaskPoints::MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase<DerivedPolicy> policy)
vtkm::filter::PolicyBase<DerivedPolicy> policy)
{ {
// point data is copied as is because it was not collapsed // point data is copied as is because it was not collapsed
if (fieldMeta.IsPointField()) if (field.IsFieldPoint())
{ {
if (this->CompactPoints) if (this->CompactPoints)
{ {
return this->Compactor.DoMapField(result, input, fieldMeta, policy); return this->Compactor.MapFieldOntoOutput(result, field, policy);
} }
else else
{ {
result.AddField(fieldMeta.AsField(input)); result.AddField(field);
return true; return true;
} }
} }
else if (field.IsFieldGlobal())
// cell data does not apply {
return false; result.AddField(field);
return true;
}
else
{
// cell data does not apply
return false;
}
} }
} }
} }

@ -33,11 +33,10 @@ public:
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData, VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData,
vtkm::filter::PolicyBase<Policy> policy); vtkm::filter::PolicyBase<Policy> policy);
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase<DerivedPolicy> policy);
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private: private:
std::vector<vtkm::Id> NumOfBins; std::vector<vtkm::Id> NumOfBins;

@ -57,11 +57,10 @@ inline VTKM_CONT vtkm::cont::DataSet NDEntropy::DoExecute(
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
inline VTKM_CONT bool NDEntropy::DoMapField(vtkm::cont::DataSet&, inline VTKM_CONT bool NDEntropy::MapFieldOntoOutput(vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>&, const vtkm::cont::Field&,
const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase<DerivedPolicy>)
vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
return false; return false;
} }

@ -51,11 +51,10 @@ public:
VTKM_CONT VTKM_CONT
vtkm::Range GetDataRange(size_t fieldIdx); vtkm::Range GetDataRange(size_t fieldIdx);
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase<DerivedPolicy> policy);
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private: private:
std::vector<vtkm::Id> NumOfBins; std::vector<vtkm::Id> NumOfBins;

@ -78,11 +78,10 @@ inline VTKM_CONT vtkm::cont::DataSet NDHistogram::DoExecute(const vtkm::cont::Da
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
inline VTKM_CONT bool NDHistogram::DoMapField(vtkm::cont::DataSet&, inline VTKM_CONT bool NDHistogram::MapFieldOntoOutput(vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>&, const vtkm::cont::Field&,
const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase<DerivedPolicy>)
vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
return false; return false;
} }

@ -56,13 +56,10 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
//Map a new field onto the resulting dataset after running the filter template <typename DerivedPolicy>
//this call is only valid VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
template <typename T, typename StorageType, typename DerivedPolicy> const vtkm::cont::Field& field,
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, vtkm::filter::PolicyBase<DerivedPolicy> policy);
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private: private:
vtkm::worklet::Streamline Worklet; vtkm::worklet::Streamline Worklet;

@ -90,11 +90,10 @@ inline VTKM_CONT vtkm::cont::DataSet Pathline::DoExecute(
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
inline VTKM_CONT bool Pathline::DoMapField(vtkm::cont::DataSet&, inline VTKM_CONT bool Pathline::MapFieldOntoOutput(vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>&, const vtkm::cont::Field&,
const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase<DerivedPolicy>)
vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
return false; return false;
} }

@ -29,7 +29,12 @@ public:
vtkm::filter::PolicyBase<DerivedPolicy> policy); vtkm::filter::PolicyBase<DerivedPolicy> policy);
//Map a new field onto the resulting dataset after running the filter //Map a new field onto the resulting dataset after running the filter
//this call is only valid //this call is only valid after calling DoExecute.
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>);
template <typename T, typename StorageType, typename DerivedPolicy> template <typename T, typename StorageType, typename DerivedPolicy>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::ArrayHandle<T, StorageType>& input,
@ -43,6 +48,8 @@ private:
} }
} // vtkm::filter } // vtkm::filter
#ifndef vtk_m_filter_Probe_hxx
#include <vtkm/filter/Probe.hxx> #include <vtkm/filter/Probe.hxx>
#endif
#endif // vtk_m_filter_Probe_h #endif // vtk_m_filter_Probe_h

@ -10,6 +10,10 @@
#ifndef vtk_m_filter_Probe_hxx #ifndef vtk_m_filter_Probe_hxx
#define vtk_m_filter_Probe_hxx #define vtk_m_filter_Probe_hxx
#include <vtkm/filter/Probe.h>
#include <vtkm/filter/MapFieldPermutation.h>
namespace vtkm namespace vtkm
{ {
namespace filter namespace filter
@ -43,27 +47,44 @@ VTKM_CONT inline vtkm::cont::DataSet Probe::DoExecute(
return output; return output;
} }
template <typename DerivedPolicy>
VTKM_CONT inline bool Probe::MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy> policy)
{
if (field.IsFieldPoint())
{
// If the field is a point field, then we need to do a custom interpolation of the points.
// In this case, we need to call the superclass's MapFieldOntoOutput, which will in turn
// call our DoMapField.
return this->FilterDataSet<Probe>::MapFieldOntoOutput(result, field, policy);
}
else if (field.IsFieldCell())
{
return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetCellIds(), result);
}
else if (field.IsFieldGlobal())
{
result.AddField(field);
return true;
}
else
{
return false;
}
}
template <typename T, typename StorageType, typename DerivedPolicy> template <typename T, typename StorageType, typename DerivedPolicy>
VTKM_CONT inline bool Probe::DoMapField(vtkm::cont::DataSet& result, VTKM_CONT inline bool Probe::DoMapField(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy>) vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
if (fieldMeta.IsPointField()) VTKM_ASSERT(fieldMeta.IsPointField());
{ auto fieldArray =
auto fieldArray = this->Worklet.ProcessPointField(input, typename DerivedPolicy::AllCellSetList());
this->Worklet.ProcessPointField(input, typename DerivedPolicy::AllCellSetList()); result.AddField(fieldMeta.AsField(fieldArray));
result.AddField(fieldMeta.AsField(fieldArray)); return true;
return true;
}
else if (fieldMeta.IsCellField())
{
auto fieldArray = this->Worklet.ProcessCellField(input);
result.AddField(fieldMeta.AsField(fieldArray));
return true;
}
return false;
} }
} }
} // vtkm::filter } // vtkm::filter

@ -54,11 +54,10 @@ public:
vtkm::filter::PolicyBase<DerivedPolicy> policy); vtkm::filter::PolicyBase<DerivedPolicy> policy);
//Map a new field onto the resulting dataset after running the filter //Map a new field onto the resulting dataset after running the filter
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase<DerivedPolicy> policy);
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private: private:
vtkm::FloatDefault FeatureAngle; vtkm::FloatDefault FeatureAngle;
@ -67,6 +66,8 @@ private:
} }
} // namespace vtkm::filter } // namespace vtkm::filter
#ifndef vtk_m_filter_SplitSharpEdges_hxx
#include <vtkm/filter/SplitSharpEdges.hxx> #include <vtkm/filter/SplitSharpEdges.hxx>
#endif
#endif // vtk_m_filter_SplitSharpEdges_h #endif // vtk_m_filter_SplitSharpEdges_h

@ -10,12 +10,15 @@
#ifndef vtk_m_filter_SplitSharpEdges_hxx #ifndef vtk_m_filter_SplitSharpEdges_hxx
#define vtk_m_filter_SplitSharpEdges_hxx #define vtk_m_filter_SplitSharpEdges_hxx
#include <vtkm/filter/SplitSharpEdges.h>
#include <vtkm/cont/ArrayHandlePermutation.h> #include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/CellSetExplicit.h> #include <vtkm/cont/CellSetExplicit.h>
#include <vtkm/cont/CoordinateSystem.h> #include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/DynamicCellSet.h> #include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/filter/MapFieldPermutation.h>
namespace vtkm namespace vtkm
{ {
namespace filter namespace filter
@ -56,23 +59,18 @@ inline VTKM_CONT vtkm::cont::DataSet SplitSharpEdges::DoExecute(
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
inline VTKM_CONT bool SplitSharpEdges::DoMapField( inline VTKM_CONT bool SplitSharpEdges::MapFieldOntoOutput(vtkm::cont::DataSet& result,
vtkm::cont::DataSet& result, const vtkm::cont::Field& field,
const vtkm::cont::ArrayHandle<T, StorageType>& input, vtkm::filter::PolicyBase<DerivedPolicy>)
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
if (fieldMeta.IsPointField()) if (field.IsFieldPoint())
{ {
// We copy the input handle to the result dataset, reusing the metadata return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetNewPointsIdArray(), result);
vtkm::cont::ArrayHandle<T> out = this->Worklet.ProcessPointField(input);
result.AddField(fieldMeta.AsField(out));
return true;
} }
else if (fieldMeta.IsCellField()) else if (field.IsFieldCell() || field.IsFieldGlobal())
{ {
result.AddField(fieldMeta.AsField(input)); result.AddField(field); // pass through
return true; return true;
} }
else else

@ -49,13 +49,10 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
//Map a new field onto the resulting dataset after running the filter template <typename DerivedPolicy>
//this call is only valid VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
template <typename T, typename StorageType, typename DerivedPolicy> const vtkm::cont::Field& field,
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, vtkm::filter::PolicyBase<DerivedPolicy> policy);
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private: private:
vtkm::Id NumberOfSteps; vtkm::Id NumberOfSteps;
@ -66,6 +63,8 @@ private:
} }
} // namespace vtkm::filter } // namespace vtkm::filter
#ifndef vtk_m_filter_StreamSurface_hxx
#include <vtkm/filter/StreamSurface.hxx> #include <vtkm/filter/StreamSurface.hxx>
#endif
#endif // vtk_m_filter_StreamSurface_h #endif // vtk_m_filter_StreamSurface_h

@ -11,6 +11,8 @@
#ifndef vtk_m_filter_StreamSurface_hxx #ifndef vtk_m_filter_StreamSurface_hxx
#define vtk_m_filter_StreamSurface_hxx #define vtk_m_filter_StreamSurface_hxx
#include <vtkm/filter/StreamSurface.h>
#include <vtkm/cont/ArrayCopy.h> #include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandleIndex.h> #include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/ErrorFilterExecution.h> #include <vtkm/cont/ErrorFilterExecution.h>
@ -79,11 +81,10 @@ inline VTKM_CONT vtkm::cont::DataSet StreamSurface::DoExecute(
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
inline VTKM_CONT bool StreamSurface::DoMapField(vtkm::cont::DataSet&, inline VTKM_CONT bool StreamSurface::MapFieldOntoOutput(vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>&, const vtkm::cont::Field&,
const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase<DerivedPolicy>)
vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
return false; return false;
} }

@ -48,13 +48,10 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
//Map a new field onto the resulting dataset after running the filter template <typename DerivedPolicy>
//this call is only valid VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
template <typename T, typename StorageType, typename DerivedPolicy> const vtkm::cont::Field& field,
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, vtkm::filter::PolicyBase<DerivedPolicy> policy);
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private: private:
vtkm::Id NumberOfSteps; vtkm::Id NumberOfSteps;
@ -65,6 +62,8 @@ private:
} }
} // namespace vtkm::filter } // namespace vtkm::filter
#ifndef vtk_m_filter_Streamline_hxx
#include <vtkm/filter/Streamline.hxx> #include <vtkm/filter/Streamline.hxx>
#endif
#endif // vtk_m_filter_Streamline_h #endif // vtk_m_filter_Streamline_h

@ -10,6 +10,8 @@
#ifndef vtk_m_filter_Streamline_hxx #ifndef vtk_m_filter_Streamline_hxx
#define vtk_m_filter_Streamline_hxx #define vtk_m_filter_Streamline_hxx
#include <vtkm/filter/Streamline.h>
#include <vtkm/cont/ArrayCopy.h> #include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandleIndex.h> #include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/ErrorFilterExecution.h> #include <vtkm/cont/ErrorFilterExecution.h>
@ -80,11 +82,10 @@ inline VTKM_CONT vtkm::cont::DataSet Streamline::DoExecute(
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
inline VTKM_CONT bool Streamline::DoMapField(vtkm::cont::DataSet&, inline VTKM_CONT bool Streamline::MapFieldOntoOutput(vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>&, const vtkm::cont::Field&,
const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase<DerivedPolicy>)
vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
return false; return false;
} }

@ -30,11 +30,10 @@ public:
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
// Map new field onto the resulting dataset after running the filter // Map new field onto the resulting dataset after running the filter
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase<DerivedPolicy> policy);
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private: private:
vtkm::worklet::Tetrahedralize Worklet; vtkm::worklet::Tetrahedralize Worklet;
@ -42,6 +41,8 @@ private:
} }
} // namespace vtkm::filter } // namespace vtkm::filter
#ifndef vtk_m_filter_Tetrahedralize_hxx
#include <vtkm/filter/Tetrahedralize.hxx> #include <vtkm/filter/Tetrahedralize.hxx>
#endif
#endif // vtk_m_filter_Tetrahedralize_h #endif // vtk_m_filter_Tetrahedralize_h

@ -11,6 +11,10 @@
#ifndef vtk_m_filter_Tetrahedralize_hxx #ifndef vtk_m_filter_Tetrahedralize_hxx
#define vtk_m_filter_Tetrahedralize_hxx #define vtk_m_filter_Tetrahedralize_hxx
#include <vtkm/filter/Tetrahedralize.h>
#include <vtkm/filter/MapFieldPermutation.h>
namespace namespace
{ {
struct DeduceCellSet struct DeduceCellSet
@ -59,30 +63,33 @@ inline VTKM_CONT vtkm::cont::DataSet Tetrahedralize::DoExecute(
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
inline VTKM_CONT bool Tetrahedralize::DoMapField( inline VTKM_CONT bool Tetrahedralize::MapFieldOntoOutput(vtkm::cont::DataSet& result,
vtkm::cont::DataSet& result, const vtkm::cont::Field& field,
const vtkm::cont::ArrayHandle<T, StorageType>& input, vtkm::filter::PolicyBase<DerivedPolicy>)
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
// point data is copied as is because it was not collapsed if (field.IsFieldPoint())
if (fieldMeta.IsPointField())
{ {
result.AddField(fieldMeta.AsField(input)); // point data is copied as is because it was not collapsed
result.AddField(field);
return true; return true;
} }
else if (field.IsFieldCell())
// cell data must be scattered to the cells created per input cell
if (fieldMeta.IsCellField())
{ {
vtkm::cont::ArrayHandle<T> output = this->Worklet.ProcessCellField(input); // cell data must be scattered to the cells created per input cell
vtkm::cont::ArrayHandle<vtkm::Id> permutation =
result.AddField(fieldMeta.AsField(output)); this->Worklet.GetOutCellScatter().GetOutputToInputMap();
return vtkm::filter::MapFieldPermutation(field, permutation, result);
}
else if (field.IsFieldGlobal())
{
result.AddField(field);
return true; return true;
} }
else
return false; {
return false;
}
} }
} }
} }

@ -10,10 +10,32 @@
#define vtkm_filter_Threshold_cxx #define vtkm_filter_Threshold_cxx
#include <vtkm/filter/Threshold.h> #include <vtkm/filter/Threshold.h>
#include <vtkm/filter/MapFieldPermutation.h>
namespace vtkm namespace vtkm
{ {
namespace filter namespace filter
{ {
VTKM_FILTER_EXPORT bool Threshold::MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field)
{
if (field.IsFieldPoint() || field.IsFieldGlobal())
{
//we copy the input handle to the result dataset, reusing the metadata
result.AddField(field);
return true;
}
else if (field.IsFieldCell())
{
return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetValidCellIds(), result);
}
else
{
return false;
}
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(Threshold); VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(Threshold);
} }

@ -52,29 +52,16 @@ public:
vtkm::filter::PolicyBase<DerivedPolicy> policy); vtkm::filter::PolicyBase<DerivedPolicy> policy);
//Map a new field onto the resulting dataset after running the filter //Map a new field onto the resulting dataset after running the filter
//this call is only valid //this call is only valid after DoExecute is called
template <typename T, typename StorageType, typename DerivedPolicy> VTKM_FILTER_EXPORT VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, const vtkm::cont::Field& field);
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta, template <typename DerivedPolicy>
vtkm::filter::PolicyBase<DerivedPolicy>) VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
if (fieldMeta.IsPointField()) return this->MapFieldOntoOutput(result, field);
{
//we copy the input handle to the result dataset, reusing the metadata
result.AddField(fieldMeta.AsField(input));
return true;
}
else if (fieldMeta.IsCellField())
{
vtkm::cont::ArrayHandle<T> out = this->Worklet.ProcessCellField(input);
result.AddField(fieldMeta.AsField(out));
return true;
}
else
{
return false;
}
} }
private: private:

@ -58,13 +58,10 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy> policy); vtkm::filter::PolicyBase<DerivedPolicy> policy);
//Map a new field onto the resulting dataset after running the filter template <typename DerivedPolicy>
//this call is only valid VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
template <typename T, typename StorageType, typename DerivedPolicy> const vtkm::cont::Field& field,
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, vtkm::filter::PolicyBase<DerivedPolicy>);
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private: private:
double LowerValue; double LowerValue;

@ -187,29 +187,35 @@ inline VTKM_CONT vtkm::cont::DataSet ThresholdPoints::DoExecute(
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
inline VTKM_CONT bool ThresholdPoints::DoMapField( inline VTKM_CONT bool ThresholdPoints::MapFieldOntoOutput(
vtkm::cont::DataSet& result, vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy> policy) vtkm::filter::PolicyBase<DerivedPolicy> policy)
{ {
// point data is copied as is because it was not collapsed // point data is copied as is because it was not collapsed
if (fieldMeta.IsPointField()) if (field.IsFieldPoint())
{ {
if (this->CompactPoints) if (this->CompactPoints)
{ {
return this->Compactor.DoMapField(result, input, fieldMeta, policy); return this->Compactor.MapFieldOntoOutput(result, field, policy);
} }
else else
{ {
result.AddField(fieldMeta.AsField(input)); result.AddField(field);
return true; return true;
} }
} }
else if (field.IsFieldGlobal())
// cell data does not apply {
return false; result.AddField(field);
return true;
}
else
{
// cell data does not apply
return false;
}
} }
} }
} }

@ -30,11 +30,10 @@ public:
vtkm::filter::PolicyBase<DerivedPolicy> policy); vtkm::filter::PolicyBase<DerivedPolicy> policy);
// Map new field onto the resulting dataset after running the filter // Map new field onto the resulting dataset after running the filter
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase<DerivedPolicy> policy);
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private: private:
vtkm::worklet::Triangulate Worklet; vtkm::worklet::Triangulate Worklet;
@ -42,6 +41,8 @@ private:
} }
} // namespace vtkm::filter } // namespace vtkm::filter
#ifndef vtk_m_filter_Triangulate_hxx
#include <vtkm/filter/Triangulate.hxx> #include <vtkm/filter/Triangulate.hxx>
#endif
#endif // vtk_m_filter_Triangulate_h #endif // vtk_m_filter_Triangulate_h

@ -10,16 +10,20 @@
#ifndef vtk_m_filter_Triangulate_hxx #ifndef vtk_m_filter_Triangulate_hxx
#define vtk_m_filter_Triangulate_hxx #define vtk_m_filter_Triangulate_hxx
#include <vtkm/filter/Triangulate.h>
#include <vtkm/filter/MapFieldPermutation.h>
namespace namespace
{ {
class DeduceCellSet class DeduceCellSet
{ {
mutable vtkm::worklet::Triangulate Worklet; vtkm::worklet::Triangulate& Worklet;
vtkm::cont::CellSetSingleType<>& OutCellSet; vtkm::cont::CellSetSingleType<>& OutCellSet;
public: public:
DeduceCellSet(vtkm::worklet::Triangulate worklet, vtkm::cont::CellSetSingleType<>& outCellSet) DeduceCellSet(vtkm::worklet::Triangulate& worklet, vtkm::cont::CellSetSingleType<>& outCellSet)
: Worklet(worklet) : Worklet(worklet)
, OutCellSet(outCellSet) , OutCellSet(outCellSet)
{ {
@ -81,29 +85,33 @@ inline VTKM_CONT vtkm::cont::DataSet Triangulate::DoExecute(
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
inline VTKM_CONT bool Triangulate::DoMapField(vtkm::cont::DataSet& result, inline VTKM_CONT bool Triangulate::MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase<DerivedPolicy>)
vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
// point data is copied as is because it was not collapsed if (field.IsFieldPoint())
if (fieldMeta.IsPointField())
{ {
result.AddField(fieldMeta.AsField(input)); // point data is copied as is because it was not collapsed
result.AddField(field);
return true; return true;
} }
else if (field.IsFieldCell())
// cell data must be scattered to the cells created per input cell
if (fieldMeta.IsCellField())
{ {
vtkm::cont::ArrayHandle<T> output = this->Worklet.ProcessCellField(input); // cell data must be scattered to the cells created per input cell
vtkm::cont::ArrayHandle<vtkm::Id> permutation =
result.AddField(fieldMeta.AsField(output)); this->Worklet.GetOutCellScatter().GetOutputToInputMap();
return vtkm::filter::MapFieldPermutation(field, permutation, result);
}
else if (field.IsFieldGlobal())
{
result.AddField(field);
return true; return true;
} }
else
return false; {
return false;
}
} }
} }
} }

@ -43,12 +43,11 @@ public:
vtkm::filter::PolicyBase<Policy> policy); vtkm::filter::PolicyBase<Policy> policy);
//Map a new field onto the resulting dataset after running the filter //Map a new field onto the resulting dataset after running the filter
//this call is only valid //this call is only valid after DoExecute is called
template <typename T, typename StorageType, typename Policy> template <typename DerivedPolicy>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase<DerivedPolicy> policy);
vtkm::filter::PolicyBase<Policy> policy);
private: private:
vtkm::worklet::Tube Worklet; vtkm::worklet::Tube Worklet;
@ -59,6 +58,8 @@ private:
} }
} // namespace vtkm::filter } // namespace vtkm::filter
#ifndef vtk_m_filter_Tube_hxx
#include <vtkm/filter/Tube.hxx> #include <vtkm/filter/Tube.hxx>
#endif
#endif // vtk_m_filter_Tube_h #endif // vtk_m_filter_Tube_h

@ -10,10 +10,13 @@
#ifndef vtk_m_filter_Tube_hxx #ifndef vtk_m_filter_Tube_hxx
#define vtk_m_filter_Tube_hxx #define vtk_m_filter_Tube_hxx
#include <vtkm/filter/Tube.h>
#include <vtkm/cont/ArrayCopy.h> #include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandleIndex.h> #include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/ErrorFilterExecution.h> #include <vtkm/cont/ErrorFilterExecution.h>
#include <vtkm/filter/MapFieldPermutation.h>
#include <vtkm/filter/PolicyBase.h> #include <vtkm/filter/PolicyBase.h>
namespace vtkm namespace vtkm
@ -51,24 +54,30 @@ inline VTKM_CONT vtkm::cont::DataSet Tube::DoExecute(const vtkm::cont::DataSet&
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
inline VTKM_CONT bool Tube::DoMapField(vtkm::cont::DataSet& result, inline VTKM_CONT bool Tube::MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase<DerivedPolicy>)
vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
vtkm::cont::ArrayHandle<T> fieldArray; if (field.IsFieldPoint())
{
if (fieldMeta.IsPointField()) return vtkm::filter::MapFieldPermutation(
fieldArray = this->Worklet.ProcessPointField(input); field, this->Worklet.GetOutputPointSourceIndex(), result);
else if (fieldMeta.IsCellField()) }
fieldArray = this->Worklet.ProcessCellField(input); else if (field.IsFieldCell())
{
return vtkm::filter::MapFieldPermutation(
field, this->Worklet.GetOutputCellSourceIndex(), result);
}
else if (field.IsFieldGlobal())
{
result.AddField(field);
return true;
}
else else
{
return false; return false;
}
//use the same meta data as the input so we get the same field name, etc.
result.AddField(fieldMeta.AsField(fieldArray));
return true;
} }
} }
} // namespace vtkm::filter } // namespace vtkm::filter

@ -64,12 +64,11 @@ public:
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
//Map a new field onto the resulting dataset after running the filter //Map a new field onto the resulting dataset after running the filter
//this call is only valid //this call is only valid after calling DoExecute
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input, const vtkm::cont::Field& field,
const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase<DerivedPolicy> policy);
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private: private:
vtkm::worklet::VertexClustering Worklet; vtkm::worklet::VertexClustering Worklet;
@ -78,6 +77,8 @@ private:
} }
} // namespace vtkm::filter } // namespace vtkm::filter
#ifndef vtk_m_filter_VertexClustering_hxx
#include <vtkm/filter/VertexClustering.hxx> #include <vtkm/filter/VertexClustering.hxx>
#endif
#endif // vtk_m_filter_VertexClustering_h #endif // vtk_m_filter_VertexClustering_h

@ -10,6 +10,10 @@
#ifndef vtk_m_filter_VertexClustering_hxx #ifndef vtk_m_filter_VertexClustering_hxx
#define vtk_m_filter_VertexClustering_hxx #define vtk_m_filter_VertexClustering_hxx
#include <vtkm/filter/VertexClustering.h>
#include <vtkm/filter/MapFieldPermutation.h>
namespace vtkm namespace vtkm
{ {
namespace filter namespace filter
@ -43,32 +47,28 @@ inline VTKM_CONT vtkm::cont::DataSet VertexClustering::DoExecute(
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy> template <typename DerivedPolicy>
inline VTKM_CONT bool VertexClustering::DoMapField( inline VTKM_CONT bool VertexClustering::MapFieldOntoOutput(vtkm::cont::DataSet& result,
vtkm::cont::DataSet& result, const vtkm::cont::Field& field,
const vtkm::cont::ArrayHandle<T, StorageType>& input, vtkm::filter::PolicyBase<DerivedPolicy>)
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy>)
{ {
vtkm::cont::ArrayHandle<T> fieldArray; if (field.IsFieldPoint())
if (fieldMeta.IsPointField())
{ {
fieldArray = this->Worklet.ProcessPointField(input); return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetPointIdMap(), result);
} }
else if (fieldMeta.IsCellField()) else if (field.IsFieldCell())
{ {
fieldArray = this->Worklet.ProcessCellField(input); return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetCellIdMap(), result);
}
else if (field.IsFieldGlobal())
{
result.AddField(field);
return true;
} }
else else
{ {
return false; return false;
} }
//use the same meta data as the input so we get the same field name, etc.
result.AddField(fieldMeta.AsField(fieldArray));
return true;
} }
} }
} }

@ -41,13 +41,13 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
//Map a new field onto the resulting dataset after running the filter template <typename DerivedPolicy>
//this call is only valid VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet&,
template <typename T, typename StorageType, typename DerivedPolicy> const vtkm::cont::Field&,
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, vtkm::filter::PolicyBase<DerivedPolicy>)
const vtkm::cont::ArrayHandle<T, StorageType>& input, {
const vtkm::filter::FieldMetadata& fieldMeta, return false;
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); }
private: private:
vtkm::Float64 rate; vtkm::Float64 rate;

@ -56,16 +56,6 @@ inline VTKM_CONT vtkm::cont::DataSet ZFPCompressor1D::DoExecute(
dataset.AddField(vtkm::cont::make_FieldPoint("compressed", compressed)); dataset.AddField(vtkm::cont::make_FieldPoint("compressed", compressed));
return dataset; return dataset;
} }
//-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy>
inline VTKM_CONT bool ZFPCompressor1D::DoMapField(vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>&,
const vtkm::filter::FieldMetadata&,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
return false;
}
} }
} // namespace vtkm::filter } // namespace vtkm::filter
#endif #endif

@ -41,13 +41,13 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
//Map a new field onto the resulting dataset after running the filter template <typename DerivedPolicy>
//this call is only valid VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet&,
template <typename T, typename StorageType, typename DerivedPolicy> const vtkm::cont::Field&,
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, vtkm::filter::PolicyBase<DerivedPolicy>)
const vtkm::cont::ArrayHandle<T, StorageType>& input, {
const vtkm::filter::FieldMetadata& fieldMeta, return false;
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); }
private: private:
vtkm::Float64 rate; vtkm::Float64 rate;

@ -62,16 +62,6 @@ inline VTKM_CONT vtkm::cont::DataSet ZFPCompressor2D::DoExecute(
return dataset; return dataset;
} }
//-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy>
inline VTKM_CONT bool ZFPCompressor2D::DoMapField(vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>&,
const vtkm::filter::FieldMetadata&,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
return false;
}
} }
} // namespace vtkm::filter } // namespace vtkm::filter
#endif #endif

@ -40,13 +40,13 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
//Map a new field onto the resulting dataset after running the filter template <typename DerivedPolicy>
//this call is only valid VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet&,
template <typename T, typename StorageType, typename DerivedPolicy> const vtkm::cont::Field&,
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, vtkm::filter::PolicyBase<DerivedPolicy>)
const vtkm::cont::ArrayHandle<T, StorageType>& input, {
const vtkm::filter::FieldMetadata& fieldMeta, return false;
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); }
private: private:
vtkm::Float64 rate; vtkm::Float64 rate;

@ -62,16 +62,6 @@ inline VTKM_CONT vtkm::cont::DataSet ZFPCompressor3D::DoExecute(
return dataset; return dataset;
} }
//-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy>
inline VTKM_CONT bool ZFPCompressor3D::DoMapField(vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>&,
const vtkm::filter::FieldMetadata&,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
return false;
}
} }
} // namespace vtkm::filter } // namespace vtkm::filter
#endif #endif

@ -48,13 +48,13 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
//Map a new field onto the resulting dataset after running the filter template <typename DerivedPolicy>
//this call is only valid VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet&,
template <typename T, typename StorageType, typename DerivedPolicy> const vtkm::cont::Field&,
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, vtkm::filter::PolicyBase<DerivedPolicy>)
const vtkm::cont::ArrayHandle<T, StorageType>& input, {
const vtkm::filter::FieldMetadata& fieldMeta, return false;
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); }
private: private:
vtkm::Float64 rate; vtkm::Float64 rate;

@ -53,16 +53,6 @@ inline VTKM_CONT vtkm::cont::DataSet ZFPDecompressor1D::DoExecute(
dataset.AddField(vtkm::cont::make_FieldPoint("decompressed", decompress)); dataset.AddField(vtkm::cont::make_FieldPoint("decompressed", decompress));
return dataset; return dataset;
} }
//-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy>
inline VTKM_CONT bool ZFPDecompressor1D::DoMapField(vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>&,
const vtkm::filter::FieldMetadata&,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
return false;
}
} }
} // namespace vtkm::filter } // namespace vtkm::filter
#endif #endif

@ -48,13 +48,13 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
//Map a new field onto the resulting dataset after running the filter template <typename DerivedPolicy>
//this call is only valid VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet&,
template <typename T, typename StorageType, typename DerivedPolicy> const vtkm::cont::Field&,
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, vtkm::filter::PolicyBase<DerivedPolicy>)
const vtkm::cont::ArrayHandle<T, StorageType>& input, {
const vtkm::filter::FieldMetadata& fieldMeta, return false;
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); }
private: private:
vtkm::Float64 rate; vtkm::Float64 rate;

@ -58,16 +58,6 @@ inline VTKM_CONT vtkm::cont::DataSet ZFPDecompressor2D::DoExecute(
dataset.AddField(vtkm::cont::make_FieldPoint("decompressed", decompress)); dataset.AddField(vtkm::cont::make_FieldPoint("decompressed", decompress));
return dataset; return dataset;
} }
//-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy>
inline VTKM_CONT bool ZFPDecompressor2D::DoMapField(vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>&,
const vtkm::filter::FieldMetadata&,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
return false;
}
} }
} // namespace vtkm::filter } // namespace vtkm::filter
#endif #endif

@ -48,13 +48,13 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
//Map a new field onto the resulting dataset after running the filter template <typename DerivedPolicy>
//this call is only valid VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet&,
template <typename T, typename StorageType, typename DerivedPolicy> const vtkm::cont::Field&,
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, vtkm::filter::PolicyBase<DerivedPolicy>)
const vtkm::cont::ArrayHandle<T, StorageType>& input, {
const vtkm::filter::FieldMetadata& fieldMeta, return false;
const vtkm::filter::PolicyBase<DerivedPolicy>& policy); }
private: private:
vtkm::Float64 rate; vtkm::Float64 rate;

@ -57,16 +57,6 @@ inline VTKM_CONT vtkm::cont::DataSet ZFPDecompressor3D::DoExecute(
dataset.AddField(vtkm::cont::make_FieldPoint("decompressed", decompress)); dataset.AddField(vtkm::cont::make_FieldPoint("decompressed", decompress));
return dataset; return dataset;
} }
//-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy>
inline VTKM_CONT bool ZFPDecompressor3D::DoMapField(vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>&,
const vtkm::filter::FieldMetadata&,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
return false;
}
} }
} // namespace vtkm::filter } // namespace vtkm::filter
#endif #endif

@ -39,6 +39,8 @@ set(unit_tests
UnitTestImageMedianFilter.cxx UnitTestImageMedianFilter.cxx
UnitTestLagrangianFilter.cxx UnitTestLagrangianFilter.cxx
UnitTestLagrangianStructuresFilter.cxx UnitTestLagrangianStructuresFilter.cxx
UnitTestMapFieldMergeAverage.cxx
UnitTestMapFieldPermutation.cxx
UnitTestMaskFilter.cxx UnitTestMaskFilter.cxx
UnitTestMaskPointsFilter.cxx UnitTestMaskPointsFilter.cxx
UnitTestMeshQualityFilter.cxx UnitTestMeshQualityFilter.cxx

@ -0,0 +1,151 @@
//============================================================================
// 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/filter/MapFieldMergeAverage.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/Field.h>
#include <vtkm/cont/testing/Testing.h>
namespace
{
constexpr vtkm::Id ARRAY_SIZE = 26;
constexpr vtkm::Id3 ARRAY3_DIM = { 3, 3, 3 };
constexpr vtkm::Id REDUCED_SIZE = 7;
vtkm::worklet::Keys<vtkm::Id> MakeKeys(vtkm::Id originalArraySize)
{
vtkm::cont::ArrayHandle<vtkm::Id> keyArray;
keyArray.Allocate(originalArraySize);
{
auto portal = keyArray.WritePortal();
for (vtkm::Id i = 0; i < originalArraySize; ++i)
{
portal.Set(i, i % REDUCED_SIZE);
}
}
return vtkm::worklet::Keys<vtkm::Id>(keyArray);
}
// Make an array of the expected output of mapping the given array using the keys returned from
// MakeKeys but with a different mechanism.
template <typename T, typename S>
vtkm::cont::ArrayHandle<T> MakeExpectedOutput(const vtkm::cont::ArrayHandle<T, S>& inputArray)
{
using ComponentType = typename vtkm::VecTraits<T>::ComponentType;
auto inputPortal = inputArray.ReadPortal();
vtkm::cont::ArrayHandle<T> outputArray;
outputArray.Allocate(REDUCED_SIZE);
auto outputPortal = outputArray.WritePortal();
for (vtkm::Id reducedI = 0; reducedI < REDUCED_SIZE; ++reducedI)
{
T sum = vtkm::TypeTraits<T>::ZeroInitialization();
ComponentType num = 0;
for (vtkm::Id fullI = reducedI; fullI < inputArray.GetNumberOfValues(); fullI += REDUCED_SIZE)
{
sum = static_cast<T>(sum + inputPortal.Get(fullI));
num = static_cast<ComponentType>(num + ComponentType(1));
}
outputPortal.Set(reducedI, sum / T(num));
}
return outputArray;
}
template <typename T, typename S>
void TryArray(const vtkm::cont::ArrayHandle<T, S>& inputArray)
{
std::cout << "Input" << std::endl;
vtkm::cont::printSummary_ArrayHandle(inputArray, std::cout);
vtkm::cont::Field::Association association =
((sizeof(T) < 8) ? vtkm::cont::Field::Association::POINTS
: vtkm::cont::Field::Association::CELL_SET);
vtkm::cont::Field inputField("my-array", association, inputArray);
vtkm::worklet::Keys<vtkm::Id> keys = MakeKeys(inputArray.GetNumberOfValues());
vtkm::cont::ArrayHandle<T> expectedOutputArray = MakeExpectedOutput(inputArray);
std::cout << "Expected output" << std::endl;
vtkm::cont::printSummary_ArrayHandle(expectedOutputArray, std::cout);
vtkm::cont::Field outputField;
bool result = vtkm::filter::MapFieldMergeAverage(inputField, keys, outputField);
VTKM_TEST_ASSERT(result, "Could not map the array.");
VTKM_TEST_ASSERT(outputField.GetAssociation() == association);
VTKM_TEST_ASSERT(outputField.GetName() == "my-array");
vtkm::cont::ArrayHandle<T> outputArray;
outputField.GetData().CopyTo(outputArray);
std::cout << "Actual output" << std::endl;
vtkm::cont::printSummary_ArrayHandle(outputArray, std::cout);
VTKM_TEST_ASSERT(test_equal_portals(expectedOutputArray.ReadPortal(), outputArray.ReadPortal()));
}
template <typename T>
void TryType(T)
{
vtkm::cont::ArrayHandle<T> inputArray;
inputArray.Allocate(ARRAY_SIZE);
SetPortal(inputArray.WritePortal());
TryArray(inputArray);
}
struct TryTypeFunctor
{
template <typename T>
void operator()(T x) const
{
TryType(x);
}
};
void TryCartesianProduct()
{
vtkm::cont::ArrayHandle<vtkm::FloatDefault> axes[3];
for (vtkm::IdComponent i = 0; i < 3; ++i)
{
axes[i].Allocate(ARRAY3_DIM[i]);
SetPortal(axes[i].WritePortal());
}
TryArray(vtkm::cont::make_ArrayHandleCartesianProduct(axes[0], axes[1], axes[2]));
}
void DoTest()
{
std::cout << "**** Test Basic Arrays *****" << std::endl;
vtkm::testing::Testing::TryTypes(TryTypeFunctor{});
std::cout << std::endl << "**** Test Uniform Point Coordiantes *****" << std::endl;
TryArray(vtkm::cont::ArrayHandleUniformPointCoordinates(ARRAY3_DIM));
std::cout << std::endl << "**** Test Cartesian Product *****" << std::endl;
TryCartesianProduct();
}
} // anonymous namespace
int UnitTestMapFieldMergeAverage(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(DoTest, argc, argv);
}

@ -0,0 +1,114 @@
//============================================================================
// 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/filter/MapFieldPermutation.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/Field.h>
#include <vtkm/cont/testing/Testing.h>
namespace
{
constexpr vtkm::Id ARRAY_SIZE = 26;
constexpr vtkm::Id3 ARRAY3_DIM = { 3, 3, 3 };
template <typename T, typename S>
void TryArray(const vtkm::cont::ArrayHandle<T, S>& inputArray)
{
std::cout << "Input" << std::endl;
vtkm::cont::printSummary_ArrayHandle(inputArray, std::cout);
vtkm::cont::Field::Association association =
((sizeof(T) < 8) ? vtkm::cont::Field::Association::POINTS
: vtkm::cont::Field::Association::CELL_SET);
vtkm::cont::Field inputField("my-array", association, inputArray);
vtkm::cont::ArrayHandle<vtkm::Id> permutationArray;
vtkm::cont::ArrayCopy(
vtkm::cont::make_ArrayHandleCounting<vtkm::Id>(0, 2, inputArray.GetNumberOfValues() / 2),
permutationArray);
vtkm::cont::ArrayHandle<T> expectedOutputArray;
vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandlePermutation(permutationArray, inputArray),
expectedOutputArray);
std::cout << "Expected output" << std::endl;
vtkm::cont::printSummary_ArrayHandle(expectedOutputArray, std::cout);
vtkm::cont::Field outputField;
bool result = vtkm::filter::MapFieldPermutation(inputField, permutationArray, outputField);
VTKM_TEST_ASSERT(result, "Could not permute the array.");
VTKM_TEST_ASSERT(outputField.GetAssociation() == association);
VTKM_TEST_ASSERT(outputField.GetName() == "my-array");
vtkm::cont::ArrayHandle<T> outputArray;
outputField.GetData().CopyTo(outputArray);
std::cout << "Actual output" << std::endl;
vtkm::cont::printSummary_ArrayHandle(outputArray, std::cout);
VTKM_TEST_ASSERT(test_equal_portals(expectedOutputArray.ReadPortal(), outputArray.ReadPortal()));
}
template <typename T>
void TryType(T)
{
vtkm::cont::ArrayHandle<T> inputArray;
inputArray.Allocate(ARRAY_SIZE);
SetPortal(inputArray.WritePortal());
TryArray(inputArray);
}
struct TryTypeFunctor
{
template <typename T>
void operator()(T x) const
{
TryType(x);
}
};
void TryCartesianProduct()
{
vtkm::cont::ArrayHandle<vtkm::FloatDefault> axes[3];
for (vtkm::IdComponent i = 0; i < 3; ++i)
{
axes[i].Allocate(ARRAY3_DIM[i]);
SetPortal(axes[i].WritePortal());
}
TryArray(vtkm::cont::make_ArrayHandleCartesianProduct(axes[0], axes[1], axes[2]));
}
void DoTest()
{
std::cout << "**** Test Basic Arrays *****" << std::endl;
vtkm::testing::Testing::TryTypes(TryTypeFunctor{});
std::cout << std::endl << "**** Test Uniform Point Coordiantes *****" << std::endl;
TryArray(vtkm::cont::ArrayHandleUniformPointCoordinates(ARRAY3_DIM));
std::cout << std::endl << "**** Test Cartesian Product *****" << std::endl;
TryCartesianProduct();
}
} // anonymous namespace
int UnitTestMapFieldPermutation(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(DoTest, argc, argv);
}

@ -82,12 +82,20 @@ const std::vector<vtkm::Float32>& GetExpectedPointData()
const std::vector<vtkm::Float32>& GetExpectedCellData() const std::vector<vtkm::Float32>& GetExpectedCellData()
{ {
static std::vector<vtkm::Float32> expected = { static std::vector<vtkm::Float32> expected = {
0.0f, 0.7f, 0.7f, 0.7f, 1.4f, 1.4f, 1.4f, 0.0f, 0.0f, 2.1f, 2.8f, 2.8f, 2.8f, 3.5f, 0.0f, 0.7f, 0.7f, 0.7f, 1.4f, 1.4f,
3.5f, 3.5f, 0.0f, 0.0f, 2.1f, 2.8f, 2.8f, 2.8f, 3.5f, 3.5f, 3.5f, 0.0f, 0.0f, 2.1f, 1.4f, vtkm::Nan32(), vtkm::Nan32(), 2.1f, 2.8f, 2.8f,
2.8f, 2.8f, 2.8f, 3.5f, 3.5f, 3.5f, 0.0f, 0.0f, 4.2f, 4.9f, 4.9f, 4.9f, 5.6f, 5.6f, 2.8f, 3.5f, 3.5f, 3.5f, vtkm::Nan32(), vtkm::Nan32(),
5.6f, 0.0f, 0.0f, 4.2f, 4.9f, 4.9f, 4.9f, 5.6f, 5.6f, 5.6f, 0.0f, 0.0f, 4.2f, 4.9f, 2.1f, 2.8f, 2.8f, 2.8f, 3.5f, 3.5f,
4.9f, 4.9f, 5.6f, 5.6f, 5.6f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 3.5f, vtkm::Nan32(), vtkm::Nan32(), 2.1f, 2.8f, 2.8f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f 2.8f, 3.5f, 3.5f, 3.5f, vtkm::Nan32(), vtkm::Nan32(),
4.2f, 4.9f, 4.9f, 4.9f, 5.6f, 5.6f,
5.6f, vtkm::Nan32(), vtkm::Nan32(), 4.2f, 4.9f, 4.9f,
4.9f, 5.6f, 5.6f, 5.6f, vtkm::Nan32(), vtkm::Nan32(),
4.2f, 4.9f, 4.9f, 4.9f, 5.6f, 5.6f,
5.6f, vtkm::Nan32(), vtkm::Nan32(), vtkm::Nan32(), vtkm::Nan32(), vtkm::Nan32(),
vtkm::Nan32(), vtkm::Nan32(), vtkm::Nan32(), vtkm::Nan32(), vtkm::Nan32(), vtkm::Nan32(),
vtkm::Nan32(), vtkm::Nan32(), vtkm::Nan32(), vtkm::Nan32(), vtkm::Nan32(), vtkm::Nan32(),
vtkm::Nan32(), vtkm::Nan32(), vtkm::Nan32()
}; };
return expected; return expected;
} }

@ -548,20 +548,22 @@ struct TestEqualImpl
return this->DoIt(matrix1, matrix2, tolerance, vtkm::TypeTraitsVectorTag()); return this->DoIt(matrix1, matrix2, tolerance, vtkm::TypeTraitsVectorTag());
} }
VTKM_EXEC_CONT bool DoIt(T1 scalar1, VTKM_EXEC_CONT bool DoIt(vtkm::Float64 value1,
T2 scalar2, vtkm::Float64 value2,
vtkm::Float64 tolerance, vtkm::Float64 tolerance) const
vtkm::TypeTraitsScalarTag) const
{ {
// If you get a compiler error here, it means you are comparing a scalar to // Handle non-finites. Normally, non-finites are never "equal" to each other (for valid
// a vector, in which case the types are non-comparable. // mathematical reasons), but for testing purposes if the two values are the same type of
VTKM_STATIC_ASSERT_MSG((std::is_same<typename vtkm::TypeTraits<T2>::DimensionalityTag, // non-finite, then they are the same in the sense that they gave the same result.
vtkm::TypeTraitsScalarTag>::type::value), if (vtkm::IsNan(value1) && vtkm::IsNan(value2))
"Trying to compare a scalar with a vector."); {
return true;
// Do all comparisons using 64-bit floats. }
vtkm::Float64 value1 = vtkm::Float64(scalar1); if (vtkm::IsInf(value1) && vtkm::IsInf(value2) &&
vtkm::Float64 value2 = vtkm::Float64(scalar2); (vtkm::IsNegative(value1) == vtkm::IsNegative(value2)))
{
return true;
}
if (vtkm::Abs(value1 - value2) <= tolerance) if (vtkm::Abs(value1 - value2) <= tolerance)
{ {
@ -596,6 +598,22 @@ struct TestEqualImpl
} }
} }
VTKM_EXEC_CONT bool DoIt(T1 scalar1,
T2 scalar2,
vtkm::Float64 tolerance,
vtkm::TypeTraitsScalarTag) const
{
// If you get a compiler error here, it means you are comparing a scalar to
// a vector, in which case the types are non-comparable.
VTKM_STATIC_ASSERT_MSG((std::is_same<typename vtkm::TypeTraits<T2>::DimensionalityTag,
vtkm::TypeTraitsScalarTag>::type::value),
"Trying to compare a scalar with a vector.");
// Do all comparisons using 64-bit floats.
return DoIt(
static_cast<vtkm::Float64>(scalar1), static_cast<vtkm::Float64>(scalar2), tolerance);
}
VTKM_EXEC_CONT bool operator()(T1 value1, T2 value2, vtkm::Float64 tolerance) const VTKM_EXEC_CONT bool operator()(T1 value1, T2 value2, vtkm::Float64 tolerance) const
{ {
return this->DoIt( return this->DoIt(

@ -72,11 +72,8 @@ struct AverageByKey
/// This method uses an existing \c Keys object to collected values by those keys and find /// This method uses an existing \c Keys object to collected values by those keys and find
/// the average of those groups. /// the average of those groups.
/// ///
template <typename KeyType, template <typename ValueType, typename InValuesStorage, typename OutAveragesStorage>
typename ValueType, VTKM_CONT static void Run(const vtkm::worklet::internal::KeysBase& keys,
typename InValuesStorage,
typename OutAveragesStorage>
VTKM_CONT static void Run(const vtkm::worklet::Keys<KeyType>& keys,
const vtkm::cont::ArrayHandle<ValueType, InValuesStorage>& inValues, const vtkm::cont::ArrayHandle<ValueType, InValuesStorage>& inValues,
vtkm::cont::ArrayHandle<ValueType, OutAveragesStorage>& outAverages) vtkm::cont::ArrayHandle<ValueType, OutAveragesStorage>& outAverages)
{ {
@ -90,9 +87,9 @@ struct AverageByKey
/// This method uses an existing \c Keys object to collected values by those keys and find /// This method uses an existing \c Keys object to collected values by those keys and find
/// the average of those groups. /// the average of those groups.
/// ///
template <typename KeyType, typename ValueType, typename InValuesStorage> template <typename ValueType, typename InValuesStorage>
VTKM_CONT static vtkm::cont::ArrayHandle<ValueType> Run( VTKM_CONT static vtkm::cont::ArrayHandle<ValueType> Run(
const vtkm::worklet::Keys<KeyType>& keys, const vtkm::worklet::internal::KeysBase& keys,
const vtkm::cont::ArrayHandle<ValueType, InValuesStorage>& inValues) const vtkm::cont::ArrayHandle<ValueType, InValuesStorage>& inValues)
{ {

@ -901,6 +901,11 @@ public:
return result; return result;
} }
vtkm::cont::ArrayHandle<vtkm::Id> GetCellMapOutputToInput() const
{
return this->CellMapOutputToInput;
}
private: private:
internal::ClipTables ClipTablesInstance; internal::ClipTables ClipTablesInstance;
vtkm::cont::ArrayHandle<EdgeInterpolation> EdgePointsInterpolation; vtkm::cont::ArrayHandle<EdgeInterpolation> EdgePointsInterpolation;

@ -84,6 +84,9 @@ public:
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool GetMergeDuplicatePoints() const { return this->SharedState.MergeDuplicatePoints; } bool GetMergeDuplicatePoints() const { return this->SharedState.MergeDuplicatePoints; }
//----------------------------------------------------------------------------
vtkm::cont::ArrayHandle<vtkm::Id> GetCellIdMap() const { return this->SharedState.CellIdMap; }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
template <typename ValueType, template <typename ValueType,
typename CellSetType, typename CellSetType,

@ -953,6 +953,8 @@ public:
} }
} }
vtkm::cont::ArrayHandle<vtkm::Id> GetCellIdMap() const { return this->CellIdMap; }
private: private:
vtkm::cont::ArrayHandle<vtkm::Id> CellIdMap; vtkm::cont::ArrayHandle<vtkm::Id> CellIdMap;
bool PassPolyData; bool PassPolyData;

@ -168,6 +168,8 @@ public:
return result; return result;
} }
vtkm::cont::ArrayHandle<vtkm::Id> GetValidCellIds() const { return this->ValidCellIds; }
private: private:
vtkm::cont::ArrayHandle<vtkm::Id> ValidCellIds; vtkm::cont::ArrayHandle<vtkm::Id> ValidCellIds;
}; };

@ -30,6 +30,8 @@
#include <vtkm/cont/arg/TransportTagKeysIn.h> #include <vtkm/cont/arg/TransportTagKeysIn.h>
#include <vtkm/cont/arg/TypeCheckTagKeys.h> #include <vtkm/cont/arg/TypeCheckTagKeys.h>
#include <vtkm/worklet/internal/DispatcherBase.h>
#include <vtkm/worklet/StableSortIndices.h> #include <vtkm/worklet/StableSortIndices.h>
#include <vtkm/worklet/vtkm_worklet_export.h> #include <vtkm/worklet/vtkm_worklet_export.h>
@ -40,6 +42,83 @@ namespace vtkm
namespace worklet namespace worklet
{ {
namespace internal
{
class VTKM_WORKLET_EXPORT KeysBase
{
public:
KeysBase(const KeysBase&) = default;
KeysBase& operator=(const KeysBase&) = default;
~KeysBase() = default;
VTKM_CONT
vtkm::Id GetInputRange() const { return this->Counts.GetNumberOfValues(); }
VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::Id> GetSortedValuesMap() const { return this->SortedValuesMap; }
VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::Id> GetOffsets() const { return this->Offsets; }
VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::IdComponent> GetCounts() const { return this->Counts; }
VTKM_CONT
vtkm::Id GetNumberOfValues() const { return this->SortedValuesMap.GetNumberOfValues(); }
template <typename Device>
struct ExecutionTypes
{
using IdPortal =
typename vtkm::cont::ArrayHandle<vtkm::Id>::template ExecutionTypes<Device>::PortalConst;
using IdComponentPortal = typename vtkm::cont::ArrayHandle<
vtkm::IdComponent>::template ExecutionTypes<Device>::PortalConst;
using Lookup = vtkm::exec::internal::ReduceByKeyLookupBase<IdPortal, IdComponentPortal>;
};
template <typename Device>
VTKM_CONT typename ExecutionTypes<Device>::Lookup PrepareForInput(Device device,
vtkm::cont::Token& token) const
{
return
typename ExecutionTypes<Device>::Lookup(this->SortedValuesMap.PrepareForInput(device, token),
this->Offsets.PrepareForInput(device, token),
this->Counts.PrepareForInput(device, token));
}
template <typename Device>
VTKM_CONT VTKM_DEPRECATED(1.6, "PrepareForInput now requires a vtkm::cont::Token object.")
typename ExecutionTypes<Device>::Lookup PrepareForInput(Device device) const
{
vtkm::cont::Token token;
return this->PrepareForInput(device, token);
}
VTKM_CONT
bool operator==(const vtkm::worklet::internal::KeysBase& other) const
{
return ((this->SortedValuesMap == other.SortedValuesMap) && (this->Offsets == other.Offsets) &&
(this->Counts == other.Counts));
}
VTKM_CONT
bool operator!=(const vtkm::worklet::internal::KeysBase& other) const
{
return !(*this == other);
}
protected:
KeysBase() = default;
vtkm::cont::ArrayHandle<vtkm::Id> SortedValuesMap;
vtkm::cont::ArrayHandle<vtkm::Id> Offsets;
vtkm::cont::ArrayHandle<vtkm::IdComponent> Counts;
};
} // namespace internal
/// Select the type of sort for BuildArrays calls. Unstable sorting is faster /// Select the type of sort for BuildArrays calls. Unstable sorting is faster
/// but will not produce consistent ordering for equal keys. Stable sorting /// but will not produce consistent ordering for equal keys. Stable sorting
/// is slower, but keeps equal keys in their original order. /// is slower, but keeps equal keys in their original order.
@ -67,7 +146,7 @@ enum class KeysSortType
/// creating a different \c Keys structure for each \c Invoke. /// creating a different \c Keys structure for each \c Invoke.
/// ///
template <typename T> template <typename T>
class VTKM_ALWAYS_EXPORT Keys class VTKM_ALWAYS_EXPORT Keys : public internal::KeysBase
{ {
public: public:
using KeyType = T; using KeyType = T;
@ -110,24 +189,9 @@ public:
KeysSortType sort, KeysSortType sort,
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()); vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny());
VTKM_CONT
vtkm::Id GetInputRange() const { return this->UniqueKeys.GetNumberOfValues(); }
VTKM_CONT VTKM_CONT
KeyArrayHandleType GetUniqueKeys() const { return this->UniqueKeys; } KeyArrayHandleType GetUniqueKeys() const { return this->UniqueKeys; }
VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::Id> GetSortedValuesMap() const { return this->SortedValuesMap; }
VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::Id> GetOffsets() const { return this->Offsets; }
VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::IdComponent> GetCounts() const { return this->Counts; }
VTKM_CONT
vtkm::Id GetNumberOfValues() const { return this->SortedValuesMap.GetNumberOfValues(); }
template <typename Device> template <typename Device>
struct ExecutionTypes struct ExecutionTypes
{ {
@ -173,9 +237,6 @@ public:
private: private:
/// @cond NONE /// @cond NONE
KeyArrayHandleType UniqueKeys; KeyArrayHandleType UniqueKeys;
vtkm::cont::ArrayHandle<vtkm::Id> SortedValuesMap;
vtkm::cont::ArrayHandle<vtkm::Id> Offsets;
vtkm::cont::ArrayHandle<vtkm::IdComponent> Counts;
template <typename KeyArrayType> template <typename KeyArrayType>
VTKM_CONT void BuildArraysInternal(KeyArrayType& keys, vtkm::cont::DeviceAdapterId device); VTKM_CONT void BuildArraysInternal(KeyArrayType& keys, vtkm::cont::DeviceAdapterId device);
@ -189,6 +250,9 @@ private:
template <typename T> template <typename T>
VTKM_CONT Keys<T>::Keys() = default; VTKM_CONT Keys<T>::Keys() = default;
namespace internal
{
template <typename KeyType> template <typename KeyType>
inline auto SchedulingRange(const vtkm::worklet::Keys<KeyType>& inputDomain) inline auto SchedulingRange(const vtkm::worklet::Keys<KeyType>& inputDomain)
-> decltype(inputDomain.GetInputRange()) -> decltype(inputDomain.GetInputRange())
@ -202,6 +266,19 @@ inline auto SchedulingRange(const vtkm::worklet::Keys<KeyType>* const inputDomai
{ {
return inputDomain->GetInputRange(); return inputDomain->GetInputRange();
} }
inline auto SchedulingRange(const vtkm::worklet::internal::KeysBase& inputDomain)
-> decltype(inputDomain.GetInputRange())
{
return inputDomain.GetInputRange();
}
inline auto SchedulingRange(const vtkm::worklet::internal::KeysBase* const inputDomain)
-> decltype(inputDomain->GetInputRange())
{
return inputDomain->GetInputRange();
}
} // namespace internal
} }
} // namespace vtkm::worklet } // namespace vtkm::worklet
@ -218,15 +295,16 @@ namespace arg
{ {
template <typename KeyType> template <typename KeyType>
struct TypeCheck<vtkm::cont::arg::TypeCheckTagKeys, vtkm::worklet::Keys<KeyType>> struct TypeCheck<vtkm::cont::arg::TypeCheckTagKeys, KeyType>
{ {
static constexpr bool value = true; static constexpr bool value =
std::is_base_of<vtkm::worklet::internal::KeysBase, typename std::decay<KeyType>::type>::value;
}; };
template <typename KeyType, typename Device> template <typename KeyType, typename Device>
struct Transport<vtkm::cont::arg::TransportTagKeysIn, vtkm::worklet::Keys<KeyType>, Device> struct Transport<vtkm::cont::arg::TransportTagKeysIn, KeyType, Device>
{ {
using ContObjectType = vtkm::worklet::Keys<KeyType>; using ContObjectType = KeyType;
using ExecObjectType = typename ContObjectType::template ExecutionTypes<Device>::Lookup; using ExecObjectType = typename ContObjectType::template ExecutionTypes<Device>::Lookup;
VTKM_CONT VTKM_CONT
@ -264,9 +342,8 @@ struct Transport<vtkm::cont::arg::TransportTagKeyedValuesIn, ArrayHandleType, De
using ExecObjectType = typename GroupedArrayType::template ExecutionTypes<Device>::PortalConst; using ExecObjectType = typename GroupedArrayType::template ExecutionTypes<Device>::PortalConst;
template <typename KeyType>
VTKM_CONT ExecObjectType operator()(const ContObjectType& object, VTKM_CONT ExecObjectType operator()(const ContObjectType& object,
const vtkm::worklet::Keys<KeyType>& keys, const vtkm::worklet::internal::KeysBase& keys,
vtkm::Id, vtkm::Id,
vtkm::Id, vtkm::Id,
vtkm::cont::Token& token) const vtkm::cont::Token& token) const
@ -300,9 +377,8 @@ struct Transport<vtkm::cont::arg::TransportTagKeyedValuesInOut, ArrayHandleType,
using ExecObjectType = typename GroupedArrayType::template ExecutionTypes<Device>::Portal; using ExecObjectType = typename GroupedArrayType::template ExecutionTypes<Device>::Portal;
template <typename KeyType>
VTKM_CONT ExecObjectType operator()(ContObjectType object, VTKM_CONT ExecObjectType operator()(ContObjectType object,
const vtkm::worklet::Keys<KeyType>& keys, const vtkm::worklet::internal::KeysBase& keys,
vtkm::Id, vtkm::Id,
vtkm::Id, vtkm::Id,
vtkm::cont::Token& token) const vtkm::cont::Token& token) const
@ -336,9 +412,8 @@ struct Transport<vtkm::cont::arg::TransportTagKeyedValuesOut, ArrayHandleType, D
using ExecObjectType = typename GroupedArrayType::template ExecutionTypes<Device>::Portal; using ExecObjectType = typename GroupedArrayType::template ExecutionTypes<Device>::Portal;
template <typename KeyType>
VTKM_CONT ExecObjectType operator()(ContObjectType object, VTKM_CONT ExecObjectType operator()(ContObjectType object,
const vtkm::worklet::Keys<KeyType>& keys, const vtkm::worklet::internal::KeysBase& keys,
vtkm::Id, vtkm::Id,
vtkm::Id, vtkm::Id,
vtkm::cont::Token& token) const vtkm::cont::Token& token) const

@ -58,6 +58,8 @@ public:
return result; return result;
} }
vtkm::cont::ArrayHandle<vtkm::Id> GetValidCellIds() const { return this->ValidCellIds; }
private: private:
vtkm::cont::ArrayHandle<vtkm::Id> ValidCellIds; vtkm::cont::ArrayHandle<vtkm::Id> ValidCellIds;
}; };

@ -473,6 +473,8 @@ public:
return outArray; return outArray;
} }
vtkm::worklet::Keys<vtkm::Id> GetMergeKeys() const { return this->MergeKeys; }
private: private:
vtkm::worklet::Keys<vtkm::Id> MergeKeys; vtkm::worklet::Keys<vtkm::Id> MergeKeys;
vtkm::cont::ArrayHandle<vtkm::Id> PointInputToOutputMap; vtkm::cont::ArrayHandle<vtkm::Id> PointInputToOutputMap;

@ -257,6 +257,8 @@ public:
return result; return result;
} }
vtkm::cont::ArrayHandle<vtkm::Id> GetCellIds() const { return this->CellIds; }
//============================================================================ //============================================================================
struct HiddenPointsWorklet : public WorkletMapField struct HiddenPointsWorklet : public WorkletMapField
{ {

@ -166,6 +166,8 @@ struct RemoveDegenerateCells
return result; return result;
} }
vtkm::cont::ArrayHandle<vtkm::Id> GetValidCellIds() const { return this->ValidCellIds; }
private: private:
vtkm::cont::ArrayHandle<vtkm::Id> ValidCellIds; vtkm::cont::ArrayHandle<vtkm::Id> ValidCellIds;
}; };

@ -239,6 +239,11 @@ public:
return outArray; return outArray;
} }
const vtkm::worklet::ScatterCounting& GetPointScatter() const
{
return *this->PointScatter.get();
}
private: private:
vtkm::cont::ArrayHandle<vtkm::IdComponent> MaskArray; vtkm::cont::ArrayHandle<vtkm::IdComponent> MaskArray;

@ -516,6 +516,8 @@ public:
return result; return result;
} }
vtkm::cont::ArrayHandle<vtkm::Id> GetNewPointsIdArray() const { return this->NewPointsIdArray; }
private: private:
vtkm::cont::ArrayHandle<vtkm::Id> NewPointsIdArray; vtkm::cont::ArrayHandle<vtkm::Id> NewPointsIdArray;
}; };

@ -45,7 +45,7 @@ public:
}; };
Tetrahedralize() Tetrahedralize()
: OutCellsPerCell() : OutCellScatter(vtkm::cont::ArrayHandle<vtkm::IdComponent>{})
{ {
} }
@ -54,14 +54,20 @@ public:
vtkm::cont::CellSetSingleType<> Run(const CellSetType& cellSet) vtkm::cont::CellSetSingleType<> Run(const CellSetType& cellSet)
{ {
TetrahedralizeExplicit worklet; TetrahedralizeExplicit worklet;
return worklet.Run(cellSet, this->OutCellsPerCell); vtkm::cont::ArrayHandle<vtkm::IdComponent> outCellsPerCell;
vtkm::cont::CellSetSingleType<> result = worklet.Run(cellSet, outCellsPerCell);
this->OutCellScatter = DistributeCellData::MakeScatter(outCellsPerCell);
return result;
} }
// Tetrahedralize structured data set, save number of tetra cells per input // Tetrahedralize structured data set, save number of tetra cells per input
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<3>& cellSet) vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<3>& cellSet)
{ {
TetrahedralizeStructured worklet; TetrahedralizeStructured worklet;
return worklet.Run(cellSet, this->OutCellsPerCell); vtkm::cont::ArrayHandle<vtkm::IdComponent> outCellsPerCell;
vtkm::cont::CellSetSingleType<> result = worklet.Run(cellSet, outCellsPerCell);
this->OutCellScatter = DistributeCellData::MakeScatter(outCellsPerCell);
return result;
} }
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<2>&) vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<2>&)
@ -76,15 +82,16 @@ public:
{ {
vtkm::cont::ArrayHandle<T> output; vtkm::cont::ArrayHandle<T> output;
vtkm::worklet::DispatcherMapField<DistributeCellData> dispatcher( vtkm::worklet::DispatcherMapField<DistributeCellData> dispatcher(this->OutCellScatter);
DistributeCellData::MakeScatter(this->OutCellsPerCell));
dispatcher.Invoke(input, output); dispatcher.Invoke(input, output);
return output; return output;
} }
DistributeCellData::ScatterType GetOutCellScatter() const { return this->OutCellScatter; }
private: private:
vtkm::cont::ArrayHandle<vtkm::IdComponent> OutCellsPerCell; DistributeCellData::ScatterType OutCellScatter;
}; };
} }
} // namespace vtkm::worklet } // namespace vtkm::worklet

@ -185,6 +185,8 @@ public:
return result; return result;
} }
vtkm::cont::ArrayHandle<vtkm::Id> GetValidCellIds() const { return this->ValidCellIds; }
private: private:
vtkm::cont::ArrayHandle<vtkm::Id> ValidCellIds; vtkm::cont::ArrayHandle<vtkm::Id> ValidCellIds;
}; };

@ -44,7 +44,7 @@ public:
}; };
Triangulate() Triangulate()
: OutCellsPerCell() : OutCellScatter(vtkm::cont::ArrayHandle<vtkm::IdComponent>{})
{ {
} }
@ -53,14 +53,20 @@ public:
vtkm::cont::CellSetSingleType<> Run(const CellSetType& cellSet) vtkm::cont::CellSetSingleType<> Run(const CellSetType& cellSet)
{ {
TriangulateExplicit worklet; TriangulateExplicit worklet;
return worklet.Run(cellSet, this->OutCellsPerCell); vtkm::cont::ArrayHandle<vtkm::IdComponent> outCellsPerCell;
vtkm::cont::CellSetSingleType<> result = worklet.Run(cellSet, outCellsPerCell);
this->OutCellScatter = DistributeCellData::MakeScatter(outCellsPerCell);
return result;
} }
// Triangulate structured data set, save number of triangulated cells per input // Triangulate structured data set, save number of triangulated cells per input
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<2>& cellSet) vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<2>& cellSet)
{ {
TriangulateStructured worklet; TriangulateStructured worklet;
return worklet.Run(cellSet, this->OutCellsPerCell); vtkm::cont::ArrayHandle<vtkm::IdComponent> outCellsPerCell;
vtkm::cont::CellSetSingleType<> result = worklet.Run(cellSet, outCellsPerCell);
this->OutCellScatter = DistributeCellData::MakeScatter(outCellsPerCell);
return result;
} }
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<3>&) vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<3>&)
@ -75,15 +81,16 @@ public:
{ {
vtkm::cont::ArrayHandle<ValueType> output; vtkm::cont::ArrayHandle<ValueType> output;
vtkm::worklet::DispatcherMapField<DistributeCellData> dispatcher( vtkm::worklet::DispatcherMapField<DistributeCellData> dispatcher(this->OutCellScatter);
DistributeCellData::MakeScatter(this->OutCellsPerCell));
dispatcher.Invoke(input, output); dispatcher.Invoke(input, output);
return output; return output;
} }
DistributeCellData::ScatterType GetOutCellScatter() const { return this->OutCellScatter; }
private: private:
vtkm::cont::ArrayHandle<vtkm::IdComponent> OutCellsPerCell; DistributeCellData::ScatterType OutCellScatter;
}; };
} }
} // namespace vtkm::worklet } // namespace vtkm::worklet

@ -628,6 +628,15 @@ public:
return output; return output;
} }
vtkm::cont::ArrayHandle<vtkm::Id> GetOutputCellSourceIndex() const
{
return this->OutputCellSourceIndex;
}
vtkm::cont::ArrayHandle<vtkm::Id> GetOutputPointSourceIndex() const
{
return this->OutputPointSourceIndex;
}
private: private:
bool Capping; bool Capping;
vtkm::Id NumSides; vtkm::Id NumSides;

@ -122,10 +122,6 @@ vtkm::cont::ArrayHandle<T> copyFromVec(vtkm::cont::ArrayHandle<vtkm::Vec<T, N>>
struct VertexClustering struct VertexClustering
{ {
using PointIdMapType = vtkm::cont::ArrayHandlePermutation<
vtkm::cont::ArrayHandleView<vtkm::cont::ArrayHandle<vtkm::Id>>,
vtkm::cont::ArrayHandle<vtkm::Id>>;
struct GridInfo struct GridInfo
{ {
vtkm::Id3 dim; vtkm::Id3 dim;
@ -383,8 +379,7 @@ public:
// For mapping properties, this map will select an arbitrary point from // For mapping properties, this map will select an arbitrary point from
// the cluster: // the cluster:
this->PointIdMap = this->PointIdMap = internal::ConcretePermutationArray(keysView, keys.GetSortedValuesMap());
vtkm::cont::make_ArrayHandlePermutation(keysView, keys.GetSortedValuesMap());
// Compute representative points from each cluster (may not match the // Compute representative points from each cluster (may not match the
// PointIdMap indexing) // PointIdMap indexing)
@ -548,8 +543,11 @@ public:
return internal::ConcretePermutationArray(this->CellIdMap, input); return internal::ConcretePermutationArray(this->CellIdMap, input);
} }
vtkm::cont::ArrayHandle<vtkm::Id> GetPointIdMap() const { return this->PointIdMap; }
vtkm::cont::ArrayHandle<vtkm::Id> GetCellIdMap() const { return this->CellIdMap; }
private: private:
PointIdMapType PointIdMap; vtkm::cont::ArrayHandle<vtkm::Id> PointIdMap;
vtkm::cont::ArrayHandle<vtkm::Id> CellIdMap; vtkm::cont::ArrayHandle<vtkm::Id> CellIdMap;
}; // struct VertexClustering }; // struct VertexClustering
} }

@ -128,6 +128,9 @@ void TryKeyType(KeyType)
vtkm::cont::ArrayCopy(keyArray, sortedKeys); vtkm::cont::ArrayCopy(keyArray, sortedKeys);
vtkm::worklet::Keys<KeyType> keys(sortedKeys); vtkm::worklet::Keys<KeyType> keys(sortedKeys);
vtkm::cont::printSummary_ArrayHandle(keys.GetUniqueKeys(), std::cout);
vtkm::cont::printSummary_ArrayHandle(keys.GetOffsets(), std::cout);
vtkm::cont::printSummary_ArrayHandle(keys.GetCounts(), std::cout);
vtkm::cont::ArrayHandle<KeyType> valuesToModify; vtkm::cont::ArrayHandle<KeyType> valuesToModify;
valuesToModify.Allocate(ARRAY_SIZE); valuesToModify.Allocate(ARRAY_SIZE);