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;
}
template <typename T, typename StorageType, typename DerivedPolicy>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>&,
const vtkm::filter::FieldMetadata&,
vtkm::filter::PolicyBase<DerivedPolicy>)
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet&,
const vtkm::cont::Field&,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
return false;
}

@ -84,6 +84,7 @@ public:
VTKM_CONT bool IsFieldCell() const { return this->FieldAssociation == Association::CELL_SET; }
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(); }

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

@ -33,13 +33,13 @@ class ThreadIndicesReduceByKey : public vtkm::exec::arg::ThreadIndicesBasic
using Superclass = vtkm::exec::arg::ThreadIndicesBasic;
public:
template <typename P1, typename P2, typename P3>
template <typename P1, typename P2>
VTKM_EXEC ThreadIndicesReduceByKey(
vtkm::Id threadIndex,
vtkm::Id inIndex,
vtkm::IdComponent visitIndex,
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)
, ValueOffset(keyLookup.Offsets.Get(inIndex))
, NumberOfValues(keyLookup.Counts.Get(inIndex))

@ -24,6 +24,34 @@ namespace exec
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.
///
/// A WorkletReduceByKey needs several arrays to map the current output object
@ -31,28 +59,19 @@ namespace internal
/// state.
///
template <typename KeyPortalType, typename IdPortalType, typename IdComponentPortalType>
struct ReduceByKeyLookup : vtkm::cont::ExecutionObjectBase
struct ReduceByKeyLookup : ReduceByKeyLookupBase<IdPortalType, IdComponentPortalType>
{
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;
IdPortalType SortedValuesMap;
IdPortalType Offsets;
IdComponentPortalType Counts;
VTKM_EXEC_CONT
ReduceByKeyLookup(const KeyPortalType& uniqueKeys,
const IdPortalType& sortedValuesMap,
const IdPortalType& offsets,
const IdComponentPortalType& counts)
: UniqueKeys(uniqueKeys)
, SortedValuesMap(sortedValuesMap)
, Offsets(offsets)
, Counts(counts)
: ReduceByKeyLookupBase<IdPortalType, IdComponentPortalType>(sortedValuesMap, offsets, counts)
, UniqueKeys(uniqueKeys)
{
}

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

@ -12,6 +12,9 @@
#include <vtkm/filter/CleanGrid.h>
#include <vtkm/filter/CleanGrid.hxx>
#include <vtkm/filter/MapFieldMergeAverage.h>
#include <vtkm/filter/MapFieldPermutation.h>
namespace vtkm
{
namespace filter
@ -116,6 +119,46 @@ vtkm::cont::DataSet CleanGrid::GenerateOutput(const vtkm::cont::DataSet& inData,
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);
}

@ -87,40 +87,15 @@ public:
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData,
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>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<ValueType, Storage>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<Policy>)
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
if (fieldMeta.IsPointField() && (this->GetCompactPointFields() || this->GetMergePoints()))
{
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;
return this->MapFieldOntoOutput(result, field);
}
private:

@ -14,6 +14,8 @@
#include <vtkm/filter/vtkm_filter_export.h>
#include <vtkm/filter/FilterDataSetWithField.h>
#include <vtkm/filter/MapFieldPermutation.h>
#include <vtkm/worklet/Clip.h>
namespace vtkm
@ -46,6 +48,35 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta,
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.
//This call is only valid after Execute has been called.
template <typename T, typename StorageType, typename DerivedPolicy>
@ -54,20 +85,11 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta,
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())
{
output = this->Worklet.ProcessPointField(input);
}
else if (fieldMeta.IsCellField())
{
output = this->Worklet.ProcessCellField(input);
}
else
{
return false;
}
vtkm::cont::ArrayHandle<T> output;
output = this->Worklet.ProcessPointField(input);
//use the same meta data as the input so we get the same field name, etc.
result.AddField(fieldMeta.AsField(output));

@ -14,6 +14,7 @@
#include <vtkm/cont/ImplicitFunctionHandle.h>
#include <vtkm/filter/FilterDataSet.h>
#include <vtkm/filter/MapFieldPermutation.h>
#include <vtkm/worklet/Clip.h>
namespace vtkm
@ -43,6 +44,36 @@ public:
vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
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.
//This call is only valid after Execute has been called.
template <typename T, typename StorageType, typename DerivedPolicy>
@ -51,24 +82,14 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta,
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())
{
output = this->Worklet.ProcessPointField(input);
}
else if (fieldMeta.IsCellField())
{
output = this->Worklet.ProcessCellField(input);
}
else
{
return false;
}
vtkm::cont::ArrayHandle<T> output;
output = this->Worklet.ProcessPointField(input);
//use the same meta data as the input so we get the same field name, etc.
result.AddField(fieldMeta.AsField(output));
return true;
}

@ -14,6 +14,8 @@
#include <vtkm/filter/vtkm_filter_export.h>
#include <vtkm/filter/FilterDataSetWithField.h>
#include <vtkm/filter/MapFieldPermutation.h>
#include <vtkm/worklet/Contour.h>
namespace vtkm
@ -111,6 +113,35 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta,
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
//this call is only valid
template <typename T, typename StorageType, typename DerivedPolicy>
@ -119,20 +150,12 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
// All other conditions should be handled by MapFieldOntoOutput directly.
VTKM_ASSERT(fieldMeta.IsPointField());
vtkm::cont::ArrayHandle<T> fieldArray;
if (fieldMeta.IsPointField())
{
fieldArray = this->Worklet.ProcessPointField(input);
}
else if (fieldMeta.IsCellField())
{
fieldArray = this->Worklet.ProcessCellField(input);
}
else
{
return false;
}
fieldArray = this->Worklet.ProcessPointField(input);
//use the same meta data as the input so we get the same field name, etc.
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);
}

@ -15,6 +15,7 @@
#include <vtkm/filter/CleanGrid.h>
#include <vtkm/filter/FilterDataSet.h>
#include <vtkm/filter/MapFieldPermutation.h>
#include <vtkm/worklet/ExternalFaces.h>
namespace vtkm
@ -59,35 +60,15 @@ public:
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
//Map a new field onto the resulting dataset after running the filter
//this call is only valid
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;
}
VTKM_FILTER_EXPORT VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field);
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:

@ -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
#define vtk_m_filter_ExtractGeometry_h
#include <vtkm/filter/vtkm_filter_export.h>
#include <vtkm/cont/ImplicitFunctionHandle.h>
#include <vtkm/filter/FilterDataSet.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
/// 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:
//currently the ExtractGeometry filter only works on scalar data.
using SupportedTypes = TypeListScalarAll;
VTKM_CONT
ExtractGeometry();
VTKM_FILTER_EXPORT VTKM_CONT ExtractGeometry();
// Set the volume of interest to extract
void SetImplicitFunction(const vtkm::cont::ImplicitFunctionHandle& func)
@ -83,12 +84,16 @@ public:
vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
//Map a new field onto the resulting dataset after running the filter
template <typename T, typename StorageType, typename DerivedPolicy>
bool DoMapField(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
VTKM_FILTER_EXPORT VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field);
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:
bool ExtractInside;
@ -97,6 +102,10 @@ private:
vtkm::cont::ImplicitFunctionHandle Function;
vtkm::worklet::ExtractGeometry Worklet;
};
#ifndef vtkm_filter_ExtractGeometry_cxx
VTKM_FILTER_EXPORT_EXECUTE_METHOD(ExtractGeometry);
#endif
}
} // namespace vtkm::filter

@ -65,15 +65,6 @@ namespace vtkm
namespace filter
{
//-----------------------------------------------------------------------------
inline VTKM_CONT ExtractGeometry::ExtractGeometry()
: vtkm::filter::FilterDataSet<ExtractGeometry>()
, ExtractInside(true)
, ExtractBoundaryCells(false)
, ExtractOnlyBoundaryCells(false)
{
}
//-----------------------------------------------------------------------------
template <typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::DataSet ExtractGeometry::DoExecute(
@ -101,34 +92,6 @@ inline VTKM_CONT vtkm::cont::DataSet ExtractGeometry::DoExecute(
output.SetCellSet(outCells);
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);
//Map a new field onto the resulting dataset after running the filter
template <typename T, typename StorageType, typename DerivedPolicy>
bool DoMapField(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
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>);
private:
bool ExtractInside;

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

@ -10,6 +10,8 @@
#define vtkm_filter_ExtractStructured_cxx
#include <vtkm/filter/ExtractStructured.h>
#include <vtkm/filter/MapFieldPermutation.h>
namespace vtkm
{
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);

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

@ -10,6 +10,7 @@
#ifndef vtk_m_filter_ExtractStructured_hxx
#define vtk_m_filter_ExtractStructured_hxx
#include <vtkm/filter/ExtractStructured.h>
namespace vtkm
{
@ -36,6 +37,14 @@ inline VTKM_CONT vtkm::cont::DataSet ExtractStructured::DoExecute(
vtkm::cont::DataSet output;
output.SetCellSet(vtkm::cont::DynamicCellSet(cellset));
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;
}
}

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

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

@ -79,11 +79,10 @@ public:
vtkm::filter::PolicyBase<DerivedPolicy> policy);
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);
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private:
vtkm::Id rank;

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

@ -67,12 +67,11 @@ public:
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
//Map a new field onto the resulting dataset after running the filter
//this call is only valid
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);
//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> policy);
private:
vtkm::FloatDefault StepSize;

@ -155,14 +155,21 @@ inline VTKM_CONT vtkm::cont::DataSet LagrangianStructures::DoExecute(
}
//-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy>
inline VTKM_CONT bool LagrangianStructures::DoMapField(
vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>&,
const vtkm::filter::FieldMetadata&,
template <typename DerivedPolicy>
inline VTKM_CONT bool LagrangianStructures::MapFieldOntoOutput(
vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
return false;
if (field.IsFieldGlobal())
{
result.AddField(field);
return true;
}
else
{
return false;
}
}
}
} // 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);
//Map a new field onto the resulting dataset after running the filter
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);
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private:
vtkm::Id Stride;

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

@ -46,11 +46,10 @@ public:
vtkm::filter::PolicyBase<DerivedPolicy> policy);
//Map a new field onto the resulting dataset after running the filter
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);
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>);
private:
vtkm::Id Stride;

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

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

@ -51,11 +51,10 @@ public:
VTKM_CONT
vtkm::Range GetDataRange(size_t fieldIdx);
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);
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private:
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>
inline VTKM_CONT bool NDHistogram::DoMapField(vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>&,
const vtkm::filter::FieldMetadata&,
vtkm::filter::PolicyBase<DerivedPolicy>)
template <typename DerivedPolicy>
inline VTKM_CONT bool NDHistogram::MapFieldOntoOutput(vtkm::cont::DataSet&,
const vtkm::cont::Field&,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
return false;
}

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

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

@ -29,7 +29,12 @@ public:
vtkm::filter::PolicyBase<DerivedPolicy> policy);
//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>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
@ -43,6 +48,8 @@ private:
}
} // vtkm::filter
#ifndef vtk_m_filter_Probe_hxx
#include <vtkm/filter/Probe.hxx>
#endif
#endif // vtk_m_filter_Probe_h

@ -10,6 +10,10 @@
#ifndef vtk_m_filter_Probe_hxx
#define vtk_m_filter_Probe_hxx
#include <vtkm/filter/Probe.h>
#include <vtkm/filter/MapFieldPermutation.h>
namespace vtkm
{
namespace filter
@ -43,27 +47,44 @@ VTKM_CONT inline vtkm::cont::DataSet Probe::DoExecute(
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>
VTKM_CONT inline bool Probe::DoMapField(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
if (fieldMeta.IsPointField())
{
auto fieldArray =
this->Worklet.ProcessPointField(input, typename DerivedPolicy::AllCellSetList());
result.AddField(fieldMeta.AsField(fieldArray));
return true;
}
else if (fieldMeta.IsCellField())
{
auto fieldArray = this->Worklet.ProcessCellField(input);
result.AddField(fieldMeta.AsField(fieldArray));
return true;
}
return false;
VTKM_ASSERT(fieldMeta.IsPointField());
auto fieldArray =
this->Worklet.ProcessPointField(input, typename DerivedPolicy::AllCellSetList());
result.AddField(fieldMeta.AsField(fieldArray));
return true;
}
}
} // vtkm::filter

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

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

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

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

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

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

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

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

@ -10,10 +10,32 @@
#define vtkm_filter_Threshold_cxx
#include <vtkm/filter/Threshold.h>
#include <vtkm/filter/MapFieldPermutation.h>
namespace vtkm
{
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);
}

@ -52,29 +52,16 @@ public:
vtkm::filter::PolicyBase<DerivedPolicy> policy);
//Map a new field onto the resulting dataset after running the filter
//this call is only valid
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>)
//this call is only valid after DoExecute is called
VTKM_FILTER_EXPORT VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field);
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
if (fieldMeta.IsPointField())
{
//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;
}
return this->MapFieldOntoOutput(result, field);
}
private:

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

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

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

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

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

@ -10,10 +10,13 @@
#ifndef vtk_m_filter_Tube_hxx
#define vtk_m_filter_Tube_hxx
#include <vtkm/filter/Tube.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/ErrorFilterExecution.h>
#include <vtkm/filter/MapFieldPermutation.h>
#include <vtkm/filter/PolicyBase.h>
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>
inline VTKM_CONT bool Tube::DoMapField(vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy>)
template <typename DerivedPolicy>
inline VTKM_CONT bool Tube::MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
vtkm::cont::ArrayHandle<T> fieldArray;
if (fieldMeta.IsPointField())
fieldArray = this->Worklet.ProcessPointField(input);
else if (fieldMeta.IsCellField())
fieldArray = this->Worklet.ProcessCellField(input);
if (field.IsFieldPoint())
{
return vtkm::filter::MapFieldPermutation(
field, this->Worklet.GetOutputPointSourceIndex(), result);
}
else if (field.IsFieldCell())
{
return vtkm::filter::MapFieldPermutation(
field, this->Worklet.GetOutputCellSourceIndex(), result);
}
else if (field.IsFieldGlobal())
{
result.AddField(field);
return true;
}
else
{
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

@ -64,12 +64,11 @@ public:
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
//Map a new field onto the resulting dataset after running the filter
//this call is only valid
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);
//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> policy);
private:
vtkm::worklet::VertexClustering Worklet;
@ -78,6 +77,8 @@ private:
}
} // namespace vtkm::filter
#ifndef vtk_m_filter_VertexClustering_hxx
#include <vtkm/filter/VertexClustering.hxx>
#endif
#endif // vtk_m_filter_VertexClustering_h

@ -10,6 +10,10 @@
#ifndef vtk_m_filter_VertexClustering_hxx
#define vtk_m_filter_VertexClustering_hxx
#include <vtkm/filter/VertexClustering.h>
#include <vtkm/filter/MapFieldPermutation.h>
namespace vtkm
{
namespace filter
@ -43,32 +47,28 @@ inline VTKM_CONT vtkm::cont::DataSet VertexClustering::DoExecute(
}
//-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy>
inline VTKM_CONT bool VertexClustering::DoMapField(
vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy>)
template <typename DerivedPolicy>
inline VTKM_CONT bool VertexClustering::MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
vtkm::cont::ArrayHandle<T> fieldArray;
if (fieldMeta.IsPointField())
if (field.IsFieldPoint())
{
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
{
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::PolicyBase<DerivedPolicy>& policy);
//Map a new field onto the resulting dataset after running the filter
//this call is only valid
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,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet&,
const vtkm::cont::Field&,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
return false;
}
private:
vtkm::Float64 rate;

@ -56,16 +56,6 @@ inline VTKM_CONT vtkm::cont::DataSet ZFPCompressor1D::DoExecute(
dataset.AddField(vtkm::cont::make_FieldPoint("compressed", compressed));
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
#endif

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

@ -62,16 +62,6 @@ inline VTKM_CONT vtkm::cont::DataSet ZFPCompressor2D::DoExecute(
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
#endif

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

@ -62,16 +62,6 @@ inline VTKM_CONT vtkm::cont::DataSet ZFPCompressor3D::DoExecute(
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
#endif

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

@ -53,16 +53,6 @@ inline VTKM_CONT vtkm::cont::DataSet ZFPDecompressor1D::DoExecute(
dataset.AddField(vtkm::cont::make_FieldPoint("decompressed", decompress));
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
#endif

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

@ -58,16 +58,6 @@ inline VTKM_CONT vtkm::cont::DataSet ZFPDecompressor2D::DoExecute(
dataset.AddField(vtkm::cont::make_FieldPoint("decompressed", decompress));
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
#endif

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

@ -57,16 +57,6 @@ inline VTKM_CONT vtkm::cont::DataSet ZFPDecompressor3D::DoExecute(
dataset.AddField(vtkm::cont::make_FieldPoint("decompressed", decompress));
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
#endif

@ -39,6 +39,8 @@ set(unit_tests
UnitTestImageMedianFilter.cxx
UnitTestLagrangianFilter.cxx
UnitTestLagrangianStructuresFilter.cxx
UnitTestMapFieldMergeAverage.cxx
UnitTestMapFieldPermutation.cxx
UnitTestMaskFilter.cxx
UnitTestMaskPointsFilter.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()
{
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,
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,
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,
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,
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,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
0.0f, 0.7f, 0.7f, 0.7f, 1.4f, 1.4f,
1.4f, vtkm::Nan32(), vtkm::Nan32(), 2.1f, 2.8f, 2.8f,
2.8f, 3.5f, 3.5f, 3.5f, vtkm::Nan32(), vtkm::Nan32(),
2.1f, 2.8f, 2.8f, 2.8f, 3.5f, 3.5f,
3.5f, vtkm::Nan32(), vtkm::Nan32(), 2.1f, 2.8f, 2.8f,
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;
}

@ -548,20 +548,22 @@ struct TestEqualImpl
return this->DoIt(matrix1, matrix2, tolerance, vtkm::TypeTraitsVectorTag());
}
VTKM_EXEC_CONT bool DoIt(T1 scalar1,
T2 scalar2,
vtkm::Float64 tolerance,
vtkm::TypeTraitsScalarTag) const
VTKM_EXEC_CONT bool DoIt(vtkm::Float64 value1,
vtkm::Float64 value2,
vtkm::Float64 tolerance) 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.
vtkm::Float64 value1 = vtkm::Float64(scalar1);
vtkm::Float64 value2 = vtkm::Float64(scalar2);
// Handle non-finites. Normally, non-finites are never "equal" to each other (for valid
// mathematical reasons), but for testing purposes if the two values are the same type of
// non-finite, then they are the same in the sense that they gave the same result.
if (vtkm::IsNan(value1) && vtkm::IsNan(value2))
{
return true;
}
if (vtkm::IsInf(value1) && vtkm::IsInf(value2) &&
(vtkm::IsNegative(value1) == vtkm::IsNegative(value2)))
{
return true;
}
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
{
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
/// the average of those groups.
///
template <typename KeyType,
typename ValueType,
typename InValuesStorage,
typename OutAveragesStorage>
VTKM_CONT static void Run(const vtkm::worklet::Keys<KeyType>& keys,
template <typename ValueType, typename InValuesStorage, typename OutAveragesStorage>
VTKM_CONT static void Run(const vtkm::worklet::internal::KeysBase& keys,
const vtkm::cont::ArrayHandle<ValueType, InValuesStorage>& inValues,
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
/// 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(
const vtkm::worklet::Keys<KeyType>& keys,
const vtkm::worklet::internal::KeysBase& keys,
const vtkm::cont::ArrayHandle<ValueType, InValuesStorage>& inValues)
{

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

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

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

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

@ -30,6 +30,8 @@
#include <vtkm/cont/arg/TransportTagKeysIn.h>
#include <vtkm/cont/arg/TypeCheckTagKeys.h>
#include <vtkm/worklet/internal/DispatcherBase.h>
#include <vtkm/worklet/StableSortIndices.h>
#include <vtkm/worklet/vtkm_worklet_export.h>
@ -40,6 +42,83 @@ namespace vtkm
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
/// but will not produce consistent ordering for equal keys. Stable sorting
/// 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.
///
template <typename T>
class VTKM_ALWAYS_EXPORT Keys
class VTKM_ALWAYS_EXPORT Keys : public internal::KeysBase
{
public:
using KeyType = T;
@ -110,24 +189,9 @@ public:
KeysSortType sort,
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny());
VTKM_CONT
vtkm::Id GetInputRange() const { return this->UniqueKeys.GetNumberOfValues(); }
VTKM_CONT
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>
struct ExecutionTypes
{
@ -173,9 +237,6 @@ public:
private:
/// @cond NONE
KeyArrayHandleType UniqueKeys;
vtkm::cont::ArrayHandle<vtkm::Id> SortedValuesMap;
vtkm::cont::ArrayHandle<vtkm::Id> Offsets;
vtkm::cont::ArrayHandle<vtkm::IdComponent> Counts;
template <typename KeyArrayType>
VTKM_CONT void BuildArraysInternal(KeyArrayType& keys, vtkm::cont::DeviceAdapterId device);
@ -189,6 +250,9 @@ private:
template <typename T>
VTKM_CONT Keys<T>::Keys() = default;
namespace internal
{
template <typename KeyType>
inline auto SchedulingRange(const vtkm::worklet::Keys<KeyType>& inputDomain)
-> decltype(inputDomain.GetInputRange())
@ -202,6 +266,19 @@ inline auto SchedulingRange(const vtkm::worklet::Keys<KeyType>* const inputDomai
{
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
@ -218,15 +295,16 @@ namespace arg
{
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>
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;
VTKM_CONT
@ -264,9 +342,8 @@ struct Transport<vtkm::cont::arg::TransportTagKeyedValuesIn, ArrayHandleType, De
using ExecObjectType = typename GroupedArrayType::template ExecutionTypes<Device>::PortalConst;
template <typename KeyType>
VTKM_CONT ExecObjectType operator()(const ContObjectType& object,
const vtkm::worklet::Keys<KeyType>& keys,
const vtkm::worklet::internal::KeysBase& keys,
vtkm::Id,
vtkm::Id,
vtkm::cont::Token& token) const
@ -300,9 +377,8 @@ struct Transport<vtkm::cont::arg::TransportTagKeyedValuesInOut, ArrayHandleType,
using ExecObjectType = typename GroupedArrayType::template ExecutionTypes<Device>::Portal;
template <typename KeyType>
VTKM_CONT ExecObjectType operator()(ContObjectType object,
const vtkm::worklet::Keys<KeyType>& keys,
const vtkm::worklet::internal::KeysBase& keys,
vtkm::Id,
vtkm::Id,
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;
template <typename KeyType>
VTKM_CONT ExecObjectType operator()(ContObjectType object,
const vtkm::worklet::Keys<KeyType>& keys,
const vtkm::worklet::internal::KeysBase& keys,
vtkm::Id,
vtkm::Id,
vtkm::cont::Token& token) const

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

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

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

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

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

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

@ -45,7 +45,7 @@ public:
};
Tetrahedralize()
: OutCellsPerCell()
: OutCellScatter(vtkm::cont::ArrayHandle<vtkm::IdComponent>{})
{
}
@ -54,14 +54,20 @@ public:
vtkm::cont::CellSetSingleType<> Run(const CellSetType& cellSet)
{
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
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<3>& cellSet)
{
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>&)
@ -76,15 +82,16 @@ public:
{
vtkm::cont::ArrayHandle<T> output;
vtkm::worklet::DispatcherMapField<DistributeCellData> dispatcher(
DistributeCellData::MakeScatter(this->OutCellsPerCell));
vtkm::worklet::DispatcherMapField<DistributeCellData> dispatcher(this->OutCellScatter);
dispatcher.Invoke(input, output);
return output;
}
DistributeCellData::ScatterType GetOutCellScatter() const { return this->OutCellScatter; }
private:
vtkm::cont::ArrayHandle<vtkm::IdComponent> OutCellsPerCell;
DistributeCellData::ScatterType OutCellScatter;
};
}
} // namespace vtkm::worklet

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

@ -44,7 +44,7 @@ public:
};
Triangulate()
: OutCellsPerCell()
: OutCellScatter(vtkm::cont::ArrayHandle<vtkm::IdComponent>{})
{
}
@ -53,14 +53,20 @@ public:
vtkm::cont::CellSetSingleType<> Run(const CellSetType& cellSet)
{
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
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<2>& cellSet)
{
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>&)
@ -75,15 +81,16 @@ public:
{
vtkm::cont::ArrayHandle<ValueType> output;
vtkm::worklet::DispatcherMapField<DistributeCellData> dispatcher(
DistributeCellData::MakeScatter(this->OutCellsPerCell));
vtkm::worklet::DispatcherMapField<DistributeCellData> dispatcher(this->OutCellScatter);
dispatcher.Invoke(input, output);
return output;
}
DistributeCellData::ScatterType GetOutCellScatter() const { return this->OutCellScatter; }
private:
vtkm::cont::ArrayHandle<vtkm::IdComponent> OutCellsPerCell;
DistributeCellData::ScatterType OutCellScatter;
};
}
} // namespace vtkm::worklet

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

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

@ -128,6 +128,9 @@ void TryKeyType(KeyType)
vtkm::cont::ArrayCopy(keyArray, 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;
valuesToModify.Allocate(ARRAY_SIZE);