diff --git a/examples/game_of_life/GameOfLife.cxx b/examples/game_of_life/GameOfLife.cxx index 21c8a3f2d..09736cdd5 100644 --- a/examples/game_of_life/GameOfLife.cxx +++ b/examples/game_of_life/GameOfLife.cxx @@ -133,11 +133,10 @@ public: return output; } - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet&, - const vtkm::cont::ArrayHandle&, - const vtkm::filter::FieldMetadata&, - vtkm::filter::PolicyBase) + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet&, + const vtkm::cont::Field&, + vtkm::filter::PolicyBase) { return false; } diff --git a/vtkm/cont/Field.h b/vtkm/cont/Field.h index 661624924..20396905d 100644 --- a/vtkm/cont/Field.h +++ b/vtkm/cont/Field.h @@ -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(); } diff --git a/vtkm/cont/arg/TypeCheckTagKeys.h b/vtkm/cont/arg/TypeCheckTagKeys.h index 39c0f1c34..07b984d4e 100644 --- a/vtkm/cont/arg/TypeCheckTagKeys.h +++ b/vtkm/cont/arg/TypeCheckTagKeys.h @@ -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 -struct TypeCheck -{ - 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 diff --git a/vtkm/exec/arg/ThreadIndicesReduceByKey.h b/vtkm/exec/arg/ThreadIndicesReduceByKey.h index 2af9bd598..cedee477e 100644 --- a/vtkm/exec/arg/ThreadIndicesReduceByKey.h +++ b/vtkm/exec/arg/ThreadIndicesReduceByKey.h @@ -33,13 +33,13 @@ class ThreadIndicesReduceByKey : public vtkm::exec::arg::ThreadIndicesBasic using Superclass = vtkm::exec::arg::ThreadIndicesBasic; public: - template + template VTKM_EXEC ThreadIndicesReduceByKey( vtkm::Id threadIndex, vtkm::Id inIndex, vtkm::IdComponent visitIndex, vtkm::Id outIndex, - const vtkm::exec::internal::ReduceByKeyLookup& keyLookup) + const vtkm::exec::internal::ReduceByKeyLookupBase& keyLookup) : Superclass(threadIndex, inIndex, visitIndex, outIndex) , ValueOffset(keyLookup.Offsets.Get(inIndex)) , NumberOfValues(keyLookup.Counts.Get(inIndex)) diff --git a/vtkm/exec/internal/ReduceByKeyLookup.h b/vtkm/exec/internal/ReduceByKeyLookup.h index 0e687bc36..7111b71fb 100644 --- a/vtkm/exec/internal/ReduceByKeyLookup.h +++ b/vtkm/exec/internal/ReduceByKeyLookup.h @@ -24,6 +24,34 @@ namespace exec namespace internal { +/// A superclass of `ReduceBykeyLookup` that can be used when no key values are provided. +/// +template +struct ReduceByKeyLookupBase +{ + VTKM_STATIC_ASSERT((std::is_same::value)); + VTKM_STATIC_ASSERT( + (std::is_same::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 -struct ReduceByKeyLookup : vtkm::cont::ExecutionObjectBase +struct ReduceByKeyLookup : ReduceByKeyLookupBase { using KeyType = typename KeyPortalType::ValueType; - VTKM_STATIC_ASSERT((std::is_same::value)); - VTKM_STATIC_ASSERT( - (std::is_same::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(sortedValuesMap, offsets, counts) + , UniqueKeys(uniqueKeys) { } diff --git a/vtkm/filter/CMakeLists.txt b/vtkm/filter/CMakeLists.txt index 631314d61..d00bf0697 100644 --- a/vtkm/filter/CMakeLists.txt +++ b/vtkm/filter/CMakeLists.txt @@ -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 diff --git a/vtkm/filter/CleanGrid.cxx b/vtkm/filter/CleanGrid.cxx index 19448cfa8..5fb40064c 100644 --- a/vtkm/filter/CleanGrid.cxx +++ b/vtkm/filter/CleanGrid.cxx @@ -12,6 +12,9 @@ #include #include +#include +#include + 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); } diff --git a/vtkm/filter/CleanGrid.h b/vtkm/filter/CleanGrid.h index 879d1ed3e..99f48b13c 100644 --- a/vtkm/filter/CleanGrid.h +++ b/vtkm/filter/CleanGrid.h @@ -87,40 +87,15 @@ public: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData, vtkm::filter::PolicyBase policy); + VTKM_FILTER_EXPORT + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field); - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase) + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase) { - if (fieldMeta.IsPointField() && (this->GetCompactPointFields() || this->GetMergePoints())) - { - vtkm::cont::ArrayHandle 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: diff --git a/vtkm/filter/ClipWithField.h b/vtkm/filter/ClipWithField.h index e6817d767..5477b2504 100644 --- a/vtkm/filter/ClipWithField.h +++ b/vtkm/filter/ClipWithField.h @@ -14,6 +14,8 @@ #include #include +#include + #include namespace vtkm @@ -46,6 +48,35 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase 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::MapFieldOntoOutput(result, field, policy); + } + else if (field.IsFieldCell()) + { + // Use the precompiled field permutation function. + vtkm::cont::ArrayHandle 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 @@ -54,20 +85,11 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase) { - vtkm::cont::ArrayHandle 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 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)); diff --git a/vtkm/filter/ClipWithImplicitFunction.h b/vtkm/filter/ClipWithImplicitFunction.h index 457e99448..087c6e159 100644 --- a/vtkm/filter/ClipWithImplicitFunction.h +++ b/vtkm/filter/ClipWithImplicitFunction.h @@ -14,6 +14,7 @@ #include #include +#include #include namespace vtkm @@ -43,6 +44,36 @@ public: vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, vtkm::filter::PolicyBase policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase 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::MapFieldOntoOutput( + result, field, policy); + } + else if (field.IsFieldCell()) + { + // Use the precompiled field permutation function. + vtkm::cont::ArrayHandle 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 @@ -51,24 +82,14 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase) { - vtkm::cont::ArrayHandle 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 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; } diff --git a/vtkm/filter/Contour.h b/vtkm/filter/Contour.h index 75b2fe0e3..5ea89fc9d 100644 --- a/vtkm/filter/Contour.h +++ b/vtkm/filter/Contour.h @@ -14,6 +14,8 @@ #include #include +#include + #include namespace vtkm @@ -111,6 +113,35 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase 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::MapFieldOntoOutput(result, field, policy); + } + else if (field.IsFieldCell()) + { + // Use the precompiled field permutation function. + vtkm::cont::ArrayHandle 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 @@ -119,20 +150,12 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase) { + // All other conditions should be handled by MapFieldOntoOutput directly. + VTKM_ASSERT(fieldMeta.IsPointField()); + vtkm::cont::ArrayHandle 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)); diff --git a/vtkm/filter/ExternalFaces.cxx b/vtkm/filter/ExternalFaces.cxx index caafe4f06..9a61b92f4 100644 --- a/vtkm/filter/ExternalFaces.cxx +++ b/vtkm/filter/ExternalFaces.cxx @@ -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); } diff --git a/vtkm/filter/ExternalFaces.h b/vtkm/filter/ExternalFaces.h index 10d1a960e..8f4a6007a 100644 --- a/vtkm/filter/ExternalFaces.h +++ b/vtkm/filter/ExternalFaces.h @@ -15,6 +15,7 @@ #include #include +#include #include namespace vtkm @@ -59,35 +60,15 @@ public: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, vtkm::filter::PolicyBase policy); - //Map a new field onto the resulting dataset after running the filter - //this call is only valid - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase 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 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 + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase) + { + return this->MapFieldOntoOutput(result, field); } private: diff --git a/vtkm/filter/ExtractGeometry.cxx b/vtkm/filter/ExtractGeometry.cxx new file mode 100644 index 000000000..b54bc7152 --- /dev/null +++ b/vtkm/filter/ExtractGeometry.cxx @@ -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 + +#include + +namespace vtkm +{ +namespace filter +{ + +//----------------------------------------------------------------------------- +VTKM_FILTER_EXPORT ExtractGeometry::ExtractGeometry() + : vtkm::filter::FilterDataSet() + , 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 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 diff --git a/vtkm/filter/ExtractGeometry.h b/vtkm/filter/ExtractGeometry.h index 204f3de0d..c4bc93c56 100644 --- a/vtkm/filter/ExtractGeometry.h +++ b/vtkm/filter/ExtractGeometry.h @@ -11,6 +11,8 @@ #ifndef vtk_m_filter_ExtractGeometry_h #define vtk_m_filter_ExtractGeometry_h +#include + #include #include #include @@ -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 +class VTKM_ALWAYS_EXPORT ExtractGeometry : public vtkm::filter::FilterDataSet { 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& policy); - //Map a new field onto the resulting dataset after running the filter - template - bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase& policy); + VTKM_FILTER_EXPORT VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field); + + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase) + { + 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 diff --git a/vtkm/filter/ExtractGeometry.hxx b/vtkm/filter/ExtractGeometry.hxx index 273c43e01..4ff4b0964 100644 --- a/vtkm/filter/ExtractGeometry.hxx +++ b/vtkm/filter/ExtractGeometry.hxx @@ -65,15 +65,6 @@ namespace vtkm namespace filter { -//----------------------------------------------------------------------------- -inline VTKM_CONT ExtractGeometry::ExtractGeometry() - : vtkm::filter::FilterDataSet() - , ExtractInside(true) - , ExtractBoundaryCells(false) - , ExtractOnlyBoundaryCells(false) -{ -} - //----------------------------------------------------------------------------- template 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 -inline VTKM_CONT bool ExtractGeometry::DoMapField( - vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase&) -{ - 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; -} } } diff --git a/vtkm/filter/ExtractPoints.h b/vtkm/filter/ExtractPoints.h index 6f0388066..30fc8ea26 100644 --- a/vtkm/filter/ExtractPoints.h +++ b/vtkm/filter/ExtractPoints.h @@ -64,11 +64,10 @@ public: vtkm::filter::PolicyBase policy); //Map a new field onto the resulting dataset after running the filter - template - bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase); private: bool ExtractInside; diff --git a/vtkm/filter/ExtractPoints.hxx b/vtkm/filter/ExtractPoints.hxx index b06c49900..1d3f4b0a4 100644 --- a/vtkm/filter/ExtractPoints.hxx +++ b/vtkm/filter/ExtractPoints.hxx @@ -65,29 +65,35 @@ inline vtkm::cont::DataSet ExtractPoints::DoExecute(const vtkm::cont::DataSet& i } //----------------------------------------------------------------------------- -template -inline VTKM_CONT bool ExtractPoints::DoMapField( +template +inline VTKM_CONT bool ExtractPoints::MapFieldOntoOutput( vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::cont::Field& field, vtkm::filter::PolicyBase 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; + } } } } diff --git a/vtkm/filter/ExtractStructured.cxx b/vtkm/filter/ExtractStructured.cxx index 3b1c6a1b4..9aee477b4 100644 --- a/vtkm/filter/ExtractStructured.cxx +++ b/vtkm/filter/ExtractStructured.cxx @@ -10,6 +10,8 @@ #define vtkm_filter_ExtractStructured_cxx #include +#include + 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); diff --git a/vtkm/filter/ExtractStructured.h b/vtkm/filter/ExtractStructured.h index 0b9eb0b16..41d330f0f 100644 --- a/vtkm/filter/ExtractStructured.h +++ b/vtkm/filter/ExtractStructured.h @@ -87,31 +87,27 @@ public: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, vtkm::filter::PolicyBase policy); - // Map new field onto the resulting dataset after running the filter - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase) + VTKM_FILTER_EXPORT VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field); + + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase) { - if (fieldMeta.IsPointField()) - { - vtkm::cont::ArrayHandle 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 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 + VTKM_CONT void PostExecute(const vtkm::cont::PartitionedDataSet& input, + vtkm::cont::PartitionedDataSet& output, + const vtkm::filter::PolicyBase&) + { + this->PostExecute(input, output); } private: @@ -120,6 +116,9 @@ private: bool IncludeBoundary; bool IncludeOffset; vtkm::worklet::ExtractStructured Worklet; + + vtkm::cont::ArrayHandle CellFieldMap; + vtkm::cont::ArrayHandle 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 +#endif #endif // vtk_m_filter_ExtractStructured_h diff --git a/vtkm/filter/ExtractStructured.hxx b/vtkm/filter/ExtractStructured.hxx index 4546a09a6..106e1759e 100644 --- a/vtkm/filter/ExtractStructured.hxx +++ b/vtkm/filter/ExtractStructured.hxx @@ -10,6 +10,7 @@ #ifndef vtk_m_filter_ExtractStructured_hxx #define vtk_m_filter_ExtractStructured_hxx +#include 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; } } diff --git a/vtkm/filter/GhostCellRemove.h b/vtkm/filter/GhostCellRemove.h index fec19e99d..84806fc5c 100644 --- a/vtkm/filter/GhostCellRemove.h +++ b/vtkm/filter/GhostCellRemove.h @@ -63,12 +63,11 @@ public: vtkm::filter::PolicyBase policy); //Map a new field onto the resulting dataset after running the filter - //this call is only valid - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + //this call is only valid after DoExecute is run + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase policy); private: bool RemoveAll; diff --git a/vtkm/filter/GhostCellRemove.hxx b/vtkm/filter/GhostCellRemove.hxx index 044cc1f19..c64e0bd1d 100644 --- a/vtkm/filter/GhostCellRemove.hxx +++ b/vtkm/filter/GhostCellRemove.hxx @@ -19,6 +19,7 @@ #include #include +#include #include namespace @@ -360,23 +361,24 @@ inline VTKM_CONT vtkm::cont::DataSet GhostCellRemove::DoExecute( } //----------------------------------------------------------------------------- -template -inline VTKM_CONT bool GhostCellRemove::DoMapField( - vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase) +template +VTKM_CONT bool GhostCellRemove::MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase) { - 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 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 diff --git a/vtkm/filter/Lagrangian.h b/vtkm/filter/Lagrangian.h index 06d1819bf..628eed5b9 100644 --- a/vtkm/filter/Lagrangian.h +++ b/vtkm/filter/Lagrangian.h @@ -79,11 +79,10 @@ public: vtkm::filter::PolicyBase policy); - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase policy); private: vtkm::Id rank; diff --git a/vtkm/filter/Lagrangian.hxx b/vtkm/filter/Lagrangian.hxx index f1fe23d17..e6bfeb489 100644 --- a/vtkm/filter/Lagrangian.hxx +++ b/vtkm/filter/Lagrangian.hxx @@ -326,13 +326,20 @@ inline VTKM_CONT vtkm::cont::DataSet Lagrangian::DoExecute( } //--------------------------------------------------------------------------- -template -inline VTKM_CONT bool Lagrangian::DoMapField(vtkm::cont::DataSet&, - const vtkm::cont::ArrayHandle&, - const vtkm::filter::FieldMetadata&, - const vtkm::filter::PolicyBase) +template +inline VTKM_CONT bool Lagrangian::MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase) { - return false; + if (field.IsFieldGlobal()) + { + result.AddField(field); + return true; + } + else + { + return false; + } } } } // namespace vtkm::filter diff --git a/vtkm/filter/LagrangianStructures.h b/vtkm/filter/LagrangianStructures.h index 146ee859c..f3b59ccd3 100644 --- a/vtkm/filter/LagrangianStructures.h +++ b/vtkm/filter/LagrangianStructures.h @@ -67,12 +67,11 @@ public: const vtkm::filter::PolicyBase& policy); //Map a new field onto the resulting dataset after running the filter - //this call is only valid - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + //this call is only valid after calling DoExecute + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase policy); private: vtkm::FloatDefault StepSize; diff --git a/vtkm/filter/LagrangianStructures.hxx b/vtkm/filter/LagrangianStructures.hxx index f98b2bb5f..22deda787 100644 --- a/vtkm/filter/LagrangianStructures.hxx +++ b/vtkm/filter/LagrangianStructures.hxx @@ -155,14 +155,21 @@ inline VTKM_CONT vtkm::cont::DataSet LagrangianStructures::DoExecute( } //----------------------------------------------------------------------------- -template -inline VTKM_CONT bool LagrangianStructures::DoMapField( - vtkm::cont::DataSet&, - const vtkm::cont::ArrayHandle&, - const vtkm::filter::FieldMetadata&, +template +inline VTKM_CONT bool LagrangianStructures::MapFieldOntoOutput( + vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, vtkm::filter::PolicyBase) { - return false; + if (field.IsFieldGlobal()) + { + result.AddField(field); + return true; + } + else + { + return false; + } } } } // namespace vtkm::filter diff --git a/vtkm/filter/MapFieldMergeAverage.cxx b/vtkm/filter/MapFieldMergeAverage.cxx new file mode 100644 index 000000000..c275ae8df --- /dev/null +++ b/vtkm/filter/MapFieldMergeAverage.cxx @@ -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 + +#include + +#include + +#include + +namespace +{ + +struct DoMapFieldMerge +{ + bool CalledMap = false; + + template + void operator()(const vtkm::cont::ArrayHandle& inputArray, + const vtkm::worklet::internal::KeysBase& keys, + vtkm::cont::VariantArrayHandle& output) + { + vtkm::cont::ArrayHandle 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().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; +} diff --git a/vtkm/filter/MapFieldMergeAverage.h b/vtkm/filter/MapFieldMergeAverage.h new file mode 100644 index 000000000..29e5ad579 --- /dev/null +++ b/vtkm/filter/MapFieldMergeAverage.h @@ -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 +#include +#include + +#include + +#include + +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 diff --git a/vtkm/filter/MapFieldPermutation.cxx b/vtkm/filter/MapFieldPermutation.cxx new file mode 100644 index 000000000..d7948fae6 --- /dev/null +++ b/vtkm/filter/MapFieldPermutation.cxx @@ -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 + +#include +#include +#include + +#include + +#include + +#include + +namespace +{ + +template +struct MapPermutationWorklet : vtkm::worklet::WorkletMapField +{ + T InvalidValue; + + explicit MapPermutationWorklet(T invalidValue) + : InvalidValue(invalidValue) + { + } + + using ControlSignature = void(FieldIn permutationIndex, WholeArrayIn input, FieldOut output); + + template + 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 +T CastInvalidValue(vtkm::Float64 invalidValue) +{ + using ComponentType = typename vtkm::VecTraits::BaseComponentType; + + if (std::is_same::NumericTag>::value) + { + // Casting to integer types + if (vtkm::IsFinite(invalidValue)) + { + return T(static_cast(invalidValue)); + } + else if (vtkm::IsInf(invalidValue) && (invalidValue > 0)) + { + return T(std::numeric_limits::max()); + } + else + { + return T(std::numeric_limits::min()); + } + } + else + { + // Not an integer type. Assume can be directly cast + return T(static_cast(invalidValue)); + } +} + +struct DoMapFieldPermutation +{ + bool CalledMap = false; + + template + void operator()(const vtkm::cont::ArrayHandle& inputArray, + const vtkm::cont::ArrayHandle& permutation, + vtkm::cont::VariantArrayHandle& output, + vtkm::Float64 invalidValue) + { + vtkm::cont::ArrayHandle outputArray; + MapPermutationWorklet worklet(CastInvalidValue(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& permutation, + vtkm::cont::Field& outputField, + vtkm::Float64 invalidValue) +{ + vtkm::cont::VariantArrayHandle outputArray; + DoMapFieldPermutation functor; + inputField.GetData().ResetTypes().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& 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; +} diff --git a/vtkm/filter/MapFieldPermutation.h b/vtkm/filter/MapFieldPermutation.h new file mode 100644 index 000000000..7a4fc168c --- /dev/null +++ b/vtkm/filter/MapFieldPermutation.h @@ -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 +#include +#include + +#include + +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& permutation, + vtkm::cont::Field& outputField, + vtkm::Float64 invalidValue = vtkm::Nan()); + +/// \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& permutation, + vtkm::cont::DataSet& outputData, + vtkm::Float64 invalidValue = vtkm::Nan()); +} +} // namespace vtkm::filter + +#endif //vtk_m_filter_MapFieldPermutation_h diff --git a/vtkm/filter/Mask.h b/vtkm/filter/Mask.h index d3530edb8..2eb870495 100644 --- a/vtkm/filter/Mask.h +++ b/vtkm/filter/Mask.h @@ -45,11 +45,10 @@ public: vtkm::filter::PolicyBase policy); //Map a new field onto the resulting dataset after running the filter - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase policy); private: vtkm::Id Stride; diff --git a/vtkm/filter/Mask.hxx b/vtkm/filter/Mask.hxx index 4bb583704..e5b240e40 100644 --- a/vtkm/filter/Mask.hxx +++ b/vtkm/filter/Mask.hxx @@ -10,6 +10,8 @@ #ifndef vtk_m_filter_Mask_hxx #define vtk_m_filter_Mask_hxx +#include + namespace { @@ -66,29 +68,24 @@ inline VTKM_CONT vtkm::cont::DataSet Mask::DoExecute(const vtkm::cont::DataSet& } //----------------------------------------------------------------------------- -template -inline VTKM_CONT bool Mask::DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase) +template +inline VTKM_CONT bool Mask::MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase) { - 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; } } } diff --git a/vtkm/filter/MaskPoints.h b/vtkm/filter/MaskPoints.h index a58e609b0..39c61a750 100644 --- a/vtkm/filter/MaskPoints.h +++ b/vtkm/filter/MaskPoints.h @@ -46,11 +46,10 @@ public: vtkm::filter::PolicyBase policy); //Map a new field onto the resulting dataset after running the filter - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase); private: vtkm::Id Stride; diff --git a/vtkm/filter/MaskPoints.hxx b/vtkm/filter/MaskPoints.hxx index 1134aef6f..2b15775eb 100644 --- a/vtkm/filter/MaskPoints.hxx +++ b/vtkm/filter/MaskPoints.hxx @@ -58,28 +58,34 @@ inline VTKM_CONT vtkm::cont::DataSet MaskPoints::DoExecute( } //----------------------------------------------------------------------------- -template -inline VTKM_CONT bool MaskPoints::DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy) +template +inline VTKM_CONT bool MaskPoints::MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase 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; + } } } } diff --git a/vtkm/filter/NDEntropy.h b/vtkm/filter/NDEntropy.h index d8a32b64d..37336e45e 100644 --- a/vtkm/filter/NDEntropy.h +++ b/vtkm/filter/NDEntropy.h @@ -33,11 +33,10 @@ public: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData, vtkm::filter::PolicyBase policy); - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase policy); private: std::vector NumOfBins; diff --git a/vtkm/filter/NDEntropy.hxx b/vtkm/filter/NDEntropy.hxx index 90c43f4fd..59cfbdde1 100644 --- a/vtkm/filter/NDEntropy.hxx +++ b/vtkm/filter/NDEntropy.hxx @@ -57,11 +57,10 @@ inline VTKM_CONT vtkm::cont::DataSet NDEntropy::DoExecute( } //----------------------------------------------------------------------------- -template -inline VTKM_CONT bool NDEntropy::DoMapField(vtkm::cont::DataSet&, - const vtkm::cont::ArrayHandle&, - const vtkm::filter::FieldMetadata&, - vtkm::filter::PolicyBase) +template +inline VTKM_CONT bool NDEntropy::MapFieldOntoOutput(vtkm::cont::DataSet&, + const vtkm::cont::Field&, + vtkm::filter::PolicyBase) { return false; } diff --git a/vtkm/filter/NDHistogram.h b/vtkm/filter/NDHistogram.h index a716c49a3..2b8cb0e45 100644 --- a/vtkm/filter/NDHistogram.h +++ b/vtkm/filter/NDHistogram.h @@ -51,11 +51,10 @@ public: VTKM_CONT vtkm::Range GetDataRange(size_t fieldIdx); - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase policy); private: std::vector NumOfBins; diff --git a/vtkm/filter/NDHistogram.hxx b/vtkm/filter/NDHistogram.hxx index dd457af3a..ac65022b8 100644 --- a/vtkm/filter/NDHistogram.hxx +++ b/vtkm/filter/NDHistogram.hxx @@ -78,11 +78,10 @@ inline VTKM_CONT vtkm::cont::DataSet NDHistogram::DoExecute(const vtkm::cont::Da } //----------------------------------------------------------------------------- -template -inline VTKM_CONT bool NDHistogram::DoMapField(vtkm::cont::DataSet&, - const vtkm::cont::ArrayHandle&, - const vtkm::filter::FieldMetadata&, - vtkm::filter::PolicyBase) +template +inline VTKM_CONT bool NDHistogram::MapFieldOntoOutput(vtkm::cont::DataSet&, + const vtkm::cont::Field&, + vtkm::filter::PolicyBase) { return false; } diff --git a/vtkm/filter/Pathline.h b/vtkm/filter/Pathline.h index f56cec9b6..7dbf582a5 100644 --- a/vtkm/filter/Pathline.h +++ b/vtkm/filter/Pathline.h @@ -56,13 +56,10 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::PolicyBase& policy); - //Map a new field onto the resulting dataset after running the filter - //this call is only valid - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase policy); private: vtkm::worklet::Streamline Worklet; diff --git a/vtkm/filter/Pathline.hxx b/vtkm/filter/Pathline.hxx index f70cbf741..83ec68499 100644 --- a/vtkm/filter/Pathline.hxx +++ b/vtkm/filter/Pathline.hxx @@ -90,11 +90,10 @@ inline VTKM_CONT vtkm::cont::DataSet Pathline::DoExecute( } //----------------------------------------------------------------------------- -template -inline VTKM_CONT bool Pathline::DoMapField(vtkm::cont::DataSet&, - const vtkm::cont::ArrayHandle&, - const vtkm::filter::FieldMetadata&, - vtkm::filter::PolicyBase) +template +inline VTKM_CONT bool Pathline::MapFieldOntoOutput(vtkm::cont::DataSet&, + const vtkm::cont::Field&, + vtkm::filter::PolicyBase) { return false; } diff --git a/vtkm/filter/Probe.h b/vtkm/filter/Probe.h index 224277f79..db8e90728 100644 --- a/vtkm/filter/Probe.h +++ b/vtkm/filter/Probe.h @@ -29,7 +29,12 @@ public: vtkm::filter::PolicyBase 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 + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase); + template VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, const vtkm::cont::ArrayHandle& input, @@ -43,6 +48,8 @@ private: } } // vtkm::filter +#ifndef vtk_m_filter_Probe_hxx #include +#endif #endif // vtk_m_filter_Probe_h diff --git a/vtkm/filter/Probe.hxx b/vtkm/filter/Probe.hxx index dbaa1f14b..e7266f3e5 100644 --- a/vtkm/filter/Probe.hxx +++ b/vtkm/filter/Probe.hxx @@ -10,6 +10,10 @@ #ifndef vtk_m_filter_Probe_hxx #define vtk_m_filter_Probe_hxx +#include + +#include + namespace vtkm { namespace filter @@ -43,27 +47,44 @@ VTKM_CONT inline vtkm::cont::DataSet Probe::DoExecute( return output; } +template +VTKM_CONT inline bool Probe::MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase 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::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 VTKM_CONT inline bool Probe::DoMapField(vtkm::cont::DataSet& result, const vtkm::cont::ArrayHandle& input, const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase) { - 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 diff --git a/vtkm/filter/SplitSharpEdges.h b/vtkm/filter/SplitSharpEdges.h index f311d548e..24f8b938b 100644 --- a/vtkm/filter/SplitSharpEdges.h +++ b/vtkm/filter/SplitSharpEdges.h @@ -54,11 +54,10 @@ public: vtkm::filter::PolicyBase policy); //Map a new field onto the resulting dataset after running the filter - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase policy); private: vtkm::FloatDefault FeatureAngle; @@ -67,6 +66,8 @@ private: } } // namespace vtkm::filter +#ifndef vtk_m_filter_SplitSharpEdges_hxx #include +#endif #endif // vtk_m_filter_SplitSharpEdges_h diff --git a/vtkm/filter/SplitSharpEdges.hxx b/vtkm/filter/SplitSharpEdges.hxx index 6b2015848..7f28b0b55 100644 --- a/vtkm/filter/SplitSharpEdges.hxx +++ b/vtkm/filter/SplitSharpEdges.hxx @@ -10,12 +10,15 @@ #ifndef vtk_m_filter_SplitSharpEdges_hxx #define vtk_m_filter_SplitSharpEdges_hxx +#include #include #include #include #include +#include + namespace vtkm { namespace filter @@ -56,23 +59,18 @@ inline VTKM_CONT vtkm::cont::DataSet SplitSharpEdges::DoExecute( } //----------------------------------------------------------------------------- -template -inline VTKM_CONT bool SplitSharpEdges::DoMapField( - vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase) +template +inline VTKM_CONT bool SplitSharpEdges::MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase) { - if (fieldMeta.IsPointField()) + if (field.IsFieldPoint()) { - // We copy the input handle to the result dataset, reusing the metadata - vtkm::cont::ArrayHandle 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 diff --git a/vtkm/filter/StreamSurface.h b/vtkm/filter/StreamSurface.h index f6b03a72a..4e7a39210 100644 --- a/vtkm/filter/StreamSurface.h +++ b/vtkm/filter/StreamSurface.h @@ -49,13 +49,10 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::PolicyBase& policy); - //Map a new field onto the resulting dataset after running the filter - //this call is only valid - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase policy); private: vtkm::Id NumberOfSteps; @@ -66,6 +63,8 @@ private: } } // namespace vtkm::filter +#ifndef vtk_m_filter_StreamSurface_hxx #include +#endif #endif // vtk_m_filter_StreamSurface_h diff --git a/vtkm/filter/StreamSurface.hxx b/vtkm/filter/StreamSurface.hxx index 64917fc5c..6bc5b08e6 100644 --- a/vtkm/filter/StreamSurface.hxx +++ b/vtkm/filter/StreamSurface.hxx @@ -11,6 +11,8 @@ #ifndef vtk_m_filter_StreamSurface_hxx #define vtk_m_filter_StreamSurface_hxx +#include + #include #include #include @@ -79,11 +81,10 @@ inline VTKM_CONT vtkm::cont::DataSet StreamSurface::DoExecute( } //----------------------------------------------------------------------------- -template -inline VTKM_CONT bool StreamSurface::DoMapField(vtkm::cont::DataSet&, - const vtkm::cont::ArrayHandle&, - const vtkm::filter::FieldMetadata&, - vtkm::filter::PolicyBase) +template +inline VTKM_CONT bool StreamSurface::MapFieldOntoOutput(vtkm::cont::DataSet&, + const vtkm::cont::Field&, + vtkm::filter::PolicyBase) { return false; } diff --git a/vtkm/filter/Streamline.h b/vtkm/filter/Streamline.h index bb47c9d7f..9d2f78b08 100644 --- a/vtkm/filter/Streamline.h +++ b/vtkm/filter/Streamline.h @@ -48,13 +48,10 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::PolicyBase& policy); - //Map a new field onto the resulting dataset after running the filter - //this call is only valid - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase policy); private: vtkm::Id NumberOfSteps; @@ -65,6 +62,8 @@ private: } } // namespace vtkm::filter +#ifndef vtk_m_filter_Streamline_hxx #include +#endif #endif // vtk_m_filter_Streamline_h diff --git a/vtkm/filter/Streamline.hxx b/vtkm/filter/Streamline.hxx index 8635c3967..c936b0a0e 100644 --- a/vtkm/filter/Streamline.hxx +++ b/vtkm/filter/Streamline.hxx @@ -10,6 +10,8 @@ #ifndef vtk_m_filter_Streamline_hxx #define vtk_m_filter_Streamline_hxx +#include + #include #include #include @@ -80,11 +82,10 @@ inline VTKM_CONT vtkm::cont::DataSet Streamline::DoExecute( } //----------------------------------------------------------------------------- -template -inline VTKM_CONT bool Streamline::DoMapField(vtkm::cont::DataSet&, - const vtkm::cont::ArrayHandle&, - const vtkm::filter::FieldMetadata&, - vtkm::filter::PolicyBase) +template +inline VTKM_CONT bool Streamline::MapFieldOntoOutput(vtkm::cont::DataSet&, + const vtkm::cont::Field&, + vtkm::filter::PolicyBase) { return false; } diff --git a/vtkm/filter/Tetrahedralize.h b/vtkm/filter/Tetrahedralize.h index 37d18c193..0653b685f 100644 --- a/vtkm/filter/Tetrahedralize.h +++ b/vtkm/filter/Tetrahedralize.h @@ -30,11 +30,10 @@ public: const vtkm::filter::PolicyBase& policy); // Map new field onto the resulting dataset after running the filter - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase policy); private: vtkm::worklet::Tetrahedralize Worklet; @@ -42,6 +41,8 @@ private: } } // namespace vtkm::filter +#ifndef vtk_m_filter_Tetrahedralize_hxx #include +#endif #endif // vtk_m_filter_Tetrahedralize_h diff --git a/vtkm/filter/Tetrahedralize.hxx b/vtkm/filter/Tetrahedralize.hxx index 2508adc8b..64398c658 100644 --- a/vtkm/filter/Tetrahedralize.hxx +++ b/vtkm/filter/Tetrahedralize.hxx @@ -11,6 +11,10 @@ #ifndef vtk_m_filter_Tetrahedralize_hxx #define vtk_m_filter_Tetrahedralize_hxx +#include + +#include + namespace { struct DeduceCellSet @@ -59,30 +63,33 @@ inline VTKM_CONT vtkm::cont::DataSet Tetrahedralize::DoExecute( } //----------------------------------------------------------------------------- -template -inline VTKM_CONT bool Tetrahedralize::DoMapField( - vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase) +template +inline VTKM_CONT bool Tetrahedralize::MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase) { - // 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 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 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; + } } } } diff --git a/vtkm/filter/Threshold.cxx b/vtkm/filter/Threshold.cxx index bb4b5b904..595bf70d7 100644 --- a/vtkm/filter/Threshold.cxx +++ b/vtkm/filter/Threshold.cxx @@ -10,10 +10,32 @@ #define vtkm_filter_Threshold_cxx #include +#include + 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); } diff --git a/vtkm/filter/Threshold.h b/vtkm/filter/Threshold.h index 18f47409f..685ec3754 100644 --- a/vtkm/filter/Threshold.h +++ b/vtkm/filter/Threshold.h @@ -52,29 +52,16 @@ public: vtkm::filter::PolicyBase policy); //Map a new field onto the resulting dataset after running the filter - //this call is only valid - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase) + //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 + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase) { - 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 out = this->Worklet.ProcessCellField(input); - result.AddField(fieldMeta.AsField(out)); - return true; - } - else - { - return false; - } + return this->MapFieldOntoOutput(result, field); } private: diff --git a/vtkm/filter/ThresholdPoints.h b/vtkm/filter/ThresholdPoints.h index 3efb01211..d30f164f3 100644 --- a/vtkm/filter/ThresholdPoints.h +++ b/vtkm/filter/ThresholdPoints.h @@ -58,13 +58,10 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase policy); - //Map a new field onto the resulting dataset after running the filter - //this call is only valid - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase); private: double LowerValue; diff --git a/vtkm/filter/ThresholdPoints.hxx b/vtkm/filter/ThresholdPoints.hxx index ada6c8a5f..97f2f08c3 100644 --- a/vtkm/filter/ThresholdPoints.hxx +++ b/vtkm/filter/ThresholdPoints.hxx @@ -187,29 +187,35 @@ inline VTKM_CONT vtkm::cont::DataSet ThresholdPoints::DoExecute( } //----------------------------------------------------------------------------- -template -inline VTKM_CONT bool ThresholdPoints::DoMapField( +template +inline VTKM_CONT bool ThresholdPoints::MapFieldOntoOutput( vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::cont::Field& field, vtkm::filter::PolicyBase 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; + } } } } diff --git a/vtkm/filter/Triangulate.h b/vtkm/filter/Triangulate.h index 50ff62dd7..c3b3eefcb 100644 --- a/vtkm/filter/Triangulate.h +++ b/vtkm/filter/Triangulate.h @@ -30,11 +30,10 @@ public: vtkm::filter::PolicyBase policy); // Map new field onto the resulting dataset after running the filter - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase policy); private: vtkm::worklet::Triangulate Worklet; @@ -42,6 +41,8 @@ private: } } // namespace vtkm::filter +#ifndef vtk_m_filter_Triangulate_hxx #include +#endif #endif // vtk_m_filter_Triangulate_h diff --git a/vtkm/filter/Triangulate.hxx b/vtkm/filter/Triangulate.hxx index abccdbd93..bd1ae667d 100644 --- a/vtkm/filter/Triangulate.hxx +++ b/vtkm/filter/Triangulate.hxx @@ -10,16 +10,20 @@ #ifndef vtk_m_filter_Triangulate_hxx #define vtk_m_filter_Triangulate_hxx +#include + +#include + 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 -inline VTKM_CONT bool Triangulate::DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase) +template +inline VTKM_CONT bool Triangulate::MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase) { - // 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 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 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; + } } } } diff --git a/vtkm/filter/Tube.h b/vtkm/filter/Tube.h index b52f1815c..66be4cc9b 100644 --- a/vtkm/filter/Tube.h +++ b/vtkm/filter/Tube.h @@ -43,12 +43,11 @@ public: vtkm::filter::PolicyBase policy); //Map a new field onto the resulting dataset after running the filter - //this call is only valid - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + //this call is only valid after DoExecute is called + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase policy); private: vtkm::worklet::Tube Worklet; @@ -59,6 +58,8 @@ private: } } // namespace vtkm::filter +#ifndef vtk_m_filter_Tube_hxx #include +#endif #endif // vtk_m_filter_Tube_h diff --git a/vtkm/filter/Tube.hxx b/vtkm/filter/Tube.hxx index 3a31e7db6..3d94c038f 100644 --- a/vtkm/filter/Tube.hxx +++ b/vtkm/filter/Tube.hxx @@ -10,10 +10,13 @@ #ifndef vtk_m_filter_Tube_hxx #define vtk_m_filter_Tube_hxx +#include + #include #include #include +#include #include namespace vtkm @@ -51,24 +54,30 @@ inline VTKM_CONT vtkm::cont::DataSet Tube::DoExecute(const vtkm::cont::DataSet& } //----------------------------------------------------------------------------- -template -inline VTKM_CONT bool Tube::DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase) +template +inline VTKM_CONT bool Tube::MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase) { - vtkm::cont::ArrayHandle 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 diff --git a/vtkm/filter/VertexClustering.h b/vtkm/filter/VertexClustering.h index 6b35fb6cb..645f3bb20 100644 --- a/vtkm/filter/VertexClustering.h +++ b/vtkm/filter/VertexClustering.h @@ -64,12 +64,11 @@ public: const vtkm::filter::PolicyBase& policy); //Map a new field onto the resulting dataset after running the filter - //this call is only valid - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + //this call is only valid after calling DoExecute + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase policy); private: vtkm::worklet::VertexClustering Worklet; @@ -78,6 +77,8 @@ private: } } // namespace vtkm::filter +#ifndef vtk_m_filter_VertexClustering_hxx #include +#endif #endif // vtk_m_filter_VertexClustering_h diff --git a/vtkm/filter/VertexClustering.hxx b/vtkm/filter/VertexClustering.hxx index 20d9592da..f1fce0943 100644 --- a/vtkm/filter/VertexClustering.hxx +++ b/vtkm/filter/VertexClustering.hxx @@ -10,6 +10,10 @@ #ifndef vtk_m_filter_VertexClustering_hxx #define vtk_m_filter_VertexClustering_hxx +#include + +#include + namespace vtkm { namespace filter @@ -43,32 +47,28 @@ inline VTKM_CONT vtkm::cont::DataSet VertexClustering::DoExecute( } //----------------------------------------------------------------------------- -template -inline VTKM_CONT bool VertexClustering::DoMapField( - vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase) +template +inline VTKM_CONT bool VertexClustering::MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase) { - vtkm::cont::ArrayHandle 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; } } } diff --git a/vtkm/filter/ZFPCompressor1D.h b/vtkm/filter/ZFPCompressor1D.h index 6a4d2f516..b0224f6c9 100644 --- a/vtkm/filter/ZFPCompressor1D.h +++ b/vtkm/filter/ZFPCompressor1D.h @@ -41,13 +41,13 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::PolicyBase& policy); - //Map a new field onto the resulting dataset after running the filter - //this call is only valid - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase& policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet&, + const vtkm::cont::Field&, + vtkm::filter::PolicyBase) + { + return false; + } private: vtkm::Float64 rate; diff --git a/vtkm/filter/ZFPCompressor1D.hxx b/vtkm/filter/ZFPCompressor1D.hxx index 1ec782d78..1c22fa865 100644 --- a/vtkm/filter/ZFPCompressor1D.hxx +++ b/vtkm/filter/ZFPCompressor1D.hxx @@ -56,16 +56,6 @@ inline VTKM_CONT vtkm::cont::DataSet ZFPCompressor1D::DoExecute( dataset.AddField(vtkm::cont::make_FieldPoint("compressed", compressed)); return dataset; } - -//----------------------------------------------------------------------------- -template -inline VTKM_CONT bool ZFPCompressor1D::DoMapField(vtkm::cont::DataSet&, - const vtkm::cont::ArrayHandle&, - const vtkm::filter::FieldMetadata&, - const vtkm::filter::PolicyBase&) -{ - return false; -} } } // namespace vtkm::filter #endif diff --git a/vtkm/filter/ZFPCompressor2D.h b/vtkm/filter/ZFPCompressor2D.h index 936fed699..6ebcc83c6 100644 --- a/vtkm/filter/ZFPCompressor2D.h +++ b/vtkm/filter/ZFPCompressor2D.h @@ -41,13 +41,13 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::PolicyBase& policy); - //Map a new field onto the resulting dataset after running the filter - //this call is only valid - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase& policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet&, + const vtkm::cont::Field&, + vtkm::filter::PolicyBase) + { + return false; + } private: vtkm::Float64 rate; diff --git a/vtkm/filter/ZFPCompressor2D.hxx b/vtkm/filter/ZFPCompressor2D.hxx index 6e65a74c3..23aeeda09 100644 --- a/vtkm/filter/ZFPCompressor2D.hxx +++ b/vtkm/filter/ZFPCompressor2D.hxx @@ -62,16 +62,6 @@ inline VTKM_CONT vtkm::cont::DataSet ZFPCompressor2D::DoExecute( return dataset; } - -//----------------------------------------------------------------------------- -template -inline VTKM_CONT bool ZFPCompressor2D::DoMapField(vtkm::cont::DataSet&, - const vtkm::cont::ArrayHandle&, - const vtkm::filter::FieldMetadata&, - const vtkm::filter::PolicyBase&) -{ - return false; -} } } // namespace vtkm::filter #endif diff --git a/vtkm/filter/ZFPCompressor3D.h b/vtkm/filter/ZFPCompressor3D.h index 169ea84b1..575f055e1 100644 --- a/vtkm/filter/ZFPCompressor3D.h +++ b/vtkm/filter/ZFPCompressor3D.h @@ -40,13 +40,13 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::PolicyBase& policy); - //Map a new field onto the resulting dataset after running the filter - //this call is only valid - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase& policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet&, + const vtkm::cont::Field&, + vtkm::filter::PolicyBase) + { + return false; + } private: vtkm::Float64 rate; diff --git a/vtkm/filter/ZFPCompressor3D.hxx b/vtkm/filter/ZFPCompressor3D.hxx index ebe344f01..303855862 100644 --- a/vtkm/filter/ZFPCompressor3D.hxx +++ b/vtkm/filter/ZFPCompressor3D.hxx @@ -62,16 +62,6 @@ inline VTKM_CONT vtkm::cont::DataSet ZFPCompressor3D::DoExecute( return dataset; } - -//----------------------------------------------------------------------------- -template -inline VTKM_CONT bool ZFPCompressor3D::DoMapField(vtkm::cont::DataSet&, - const vtkm::cont::ArrayHandle&, - const vtkm::filter::FieldMetadata&, - const vtkm::filter::PolicyBase&) -{ - return false; -} } } // namespace vtkm::filter #endif diff --git a/vtkm/filter/ZFPDecompressor1D.h b/vtkm/filter/ZFPDecompressor1D.h index c3aa2c27f..2fdad1ed2 100644 --- a/vtkm/filter/ZFPDecompressor1D.h +++ b/vtkm/filter/ZFPDecompressor1D.h @@ -48,13 +48,13 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::PolicyBase& policy); - //Map a new field onto the resulting dataset after running the filter - //this call is only valid - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase& policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet&, + const vtkm::cont::Field&, + vtkm::filter::PolicyBase) + { + return false; + } private: vtkm::Float64 rate; diff --git a/vtkm/filter/ZFPDecompressor1D.hxx b/vtkm/filter/ZFPDecompressor1D.hxx index 17956c8d4..e38c68da8 100644 --- a/vtkm/filter/ZFPDecompressor1D.hxx +++ b/vtkm/filter/ZFPDecompressor1D.hxx @@ -53,16 +53,6 @@ inline VTKM_CONT vtkm::cont::DataSet ZFPDecompressor1D::DoExecute( dataset.AddField(vtkm::cont::make_FieldPoint("decompressed", decompress)); return dataset; } - -//----------------------------------------------------------------------------- -template -inline VTKM_CONT bool ZFPDecompressor1D::DoMapField(vtkm::cont::DataSet&, - const vtkm::cont::ArrayHandle&, - const vtkm::filter::FieldMetadata&, - const vtkm::filter::PolicyBase&) -{ - return false; -} } } // namespace vtkm::filter #endif diff --git a/vtkm/filter/ZFPDecompressor2D.h b/vtkm/filter/ZFPDecompressor2D.h index a6c1b3719..4df980b53 100644 --- a/vtkm/filter/ZFPDecompressor2D.h +++ b/vtkm/filter/ZFPDecompressor2D.h @@ -48,13 +48,13 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::PolicyBase& policy); - //Map a new field onto the resulting dataset after running the filter - //this call is only valid - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase& policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet&, + const vtkm::cont::Field&, + vtkm::filter::PolicyBase) + { + return false; + } private: vtkm::Float64 rate; diff --git a/vtkm/filter/ZFPDecompressor2D.hxx b/vtkm/filter/ZFPDecompressor2D.hxx index a001fc0f7..f89db102c 100644 --- a/vtkm/filter/ZFPDecompressor2D.hxx +++ b/vtkm/filter/ZFPDecompressor2D.hxx @@ -58,16 +58,6 @@ inline VTKM_CONT vtkm::cont::DataSet ZFPDecompressor2D::DoExecute( dataset.AddField(vtkm::cont::make_FieldPoint("decompressed", decompress)); return dataset; } - -//----------------------------------------------------------------------------- -template -inline VTKM_CONT bool ZFPDecompressor2D::DoMapField(vtkm::cont::DataSet&, - const vtkm::cont::ArrayHandle&, - const vtkm::filter::FieldMetadata&, - const vtkm::filter::PolicyBase&) -{ - return false; -} } } // namespace vtkm::filter #endif diff --git a/vtkm/filter/ZFPDecompressor3D.h b/vtkm/filter/ZFPDecompressor3D.h index 3f50ba871..6c84384c3 100644 --- a/vtkm/filter/ZFPDecompressor3D.h +++ b/vtkm/filter/ZFPDecompressor3D.h @@ -48,13 +48,13 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::PolicyBase& policy); - //Map a new field onto the resulting dataset after running the filter - //this call is only valid - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase& policy); + template + VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet&, + const vtkm::cont::Field&, + vtkm::filter::PolicyBase) + { + return false; + } private: vtkm::Float64 rate; diff --git a/vtkm/filter/ZFPDecompressor3D.hxx b/vtkm/filter/ZFPDecompressor3D.hxx index 6d5c0b13b..cf3183dce 100644 --- a/vtkm/filter/ZFPDecompressor3D.hxx +++ b/vtkm/filter/ZFPDecompressor3D.hxx @@ -57,16 +57,6 @@ inline VTKM_CONT vtkm::cont::DataSet ZFPDecompressor3D::DoExecute( dataset.AddField(vtkm::cont::make_FieldPoint("decompressed", decompress)); return dataset; } - -//----------------------------------------------------------------------------- -template -inline VTKM_CONT bool ZFPDecompressor3D::DoMapField(vtkm::cont::DataSet&, - const vtkm::cont::ArrayHandle&, - const vtkm::filter::FieldMetadata&, - const vtkm::filter::PolicyBase&) -{ - return false; -} } } // namespace vtkm::filter #endif diff --git a/vtkm/filter/testing/CMakeLists.txt b/vtkm/filter/testing/CMakeLists.txt index 607dc7ed7..d1181398a 100644 --- a/vtkm/filter/testing/CMakeLists.txt +++ b/vtkm/filter/testing/CMakeLists.txt @@ -39,6 +39,8 @@ set(unit_tests UnitTestImageMedianFilter.cxx UnitTestLagrangianFilter.cxx UnitTestLagrangianStructuresFilter.cxx + UnitTestMapFieldMergeAverage.cxx + UnitTestMapFieldPermutation.cxx UnitTestMaskFilter.cxx UnitTestMaskPointsFilter.cxx UnitTestMeshQualityFilter.cxx diff --git a/vtkm/filter/testing/UnitTestMapFieldMergeAverage.cxx b/vtkm/filter/testing/UnitTestMapFieldMergeAverage.cxx new file mode 100644 index 000000000..eac7f8ba2 --- /dev/null +++ b/vtkm/filter/testing/UnitTestMapFieldMergeAverage.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 + +#include +#include +#include +#include +#include + +#include + +namespace +{ + +constexpr vtkm::Id ARRAY_SIZE = 26; +constexpr vtkm::Id3 ARRAY3_DIM = { 3, 3, 3 }; +constexpr vtkm::Id REDUCED_SIZE = 7; + +vtkm::worklet::Keys MakeKeys(vtkm::Id originalArraySize) +{ + vtkm::cont::ArrayHandle 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(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 +vtkm::cont::ArrayHandle MakeExpectedOutput(const vtkm::cont::ArrayHandle& inputArray) +{ + using ComponentType = typename vtkm::VecTraits::ComponentType; + + auto inputPortal = inputArray.ReadPortal(); + + vtkm::cont::ArrayHandle outputArray; + outputArray.Allocate(REDUCED_SIZE); + auto outputPortal = outputArray.WritePortal(); + + for (vtkm::Id reducedI = 0; reducedI < REDUCED_SIZE; ++reducedI) + { + T sum = vtkm::TypeTraits::ZeroInitialization(); + ComponentType num = 0; + for (vtkm::Id fullI = reducedI; fullI < inputArray.GetNumberOfValues(); fullI += REDUCED_SIZE) + { + sum = static_cast(sum + inputPortal.Get(fullI)); + num = static_cast(num + ComponentType(1)); + } + outputPortal.Set(reducedI, sum / T(num)); + } + + return outputArray; +} + +template +void TryArray(const vtkm::cont::ArrayHandle& 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 keys = MakeKeys(inputArray.GetNumberOfValues()); + + vtkm::cont::ArrayHandle 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 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 +void TryType(T) +{ + vtkm::cont::ArrayHandle inputArray; + inputArray.Allocate(ARRAY_SIZE); + SetPortal(inputArray.WritePortal()); + TryArray(inputArray); +} + +struct TryTypeFunctor +{ + template + void operator()(T x) const + { + TryType(x); + } +}; + +void TryCartesianProduct() +{ + vtkm::cont::ArrayHandle 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); +} diff --git a/vtkm/filter/testing/UnitTestMapFieldPermutation.cxx b/vtkm/filter/testing/UnitTestMapFieldPermutation.cxx new file mode 100644 index 000000000..c71e78de0 --- /dev/null +++ b/vtkm/filter/testing/UnitTestMapFieldPermutation.cxx @@ -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 + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace +{ + +constexpr vtkm::Id ARRAY_SIZE = 26; +constexpr vtkm::Id3 ARRAY3_DIM = { 3, 3, 3 }; + +template +void TryArray(const vtkm::cont::ArrayHandle& 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 permutationArray; + vtkm::cont::ArrayCopy( + vtkm::cont::make_ArrayHandleCounting(0, 2, inputArray.GetNumberOfValues() / 2), + permutationArray); + + vtkm::cont::ArrayHandle 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 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 +void TryType(T) +{ + vtkm::cont::ArrayHandle inputArray; + inputArray.Allocate(ARRAY_SIZE); + SetPortal(inputArray.WritePortal()); + TryArray(inputArray); +} + +struct TryTypeFunctor +{ + template + void operator()(T x) const + { + TryType(x); + } +}; + +void TryCartesianProduct() +{ + vtkm::cont::ArrayHandle 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); +} diff --git a/vtkm/filter/testing/UnitTestProbe.cxx b/vtkm/filter/testing/UnitTestProbe.cxx index 2cdc6bdb2..a5a7a6bcc 100644 --- a/vtkm/filter/testing/UnitTestProbe.cxx +++ b/vtkm/filter/testing/UnitTestProbe.cxx @@ -82,12 +82,20 @@ const std::vector& GetExpectedPointData() const std::vector& GetExpectedCellData() { static std::vector 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; } diff --git a/vtkm/testing/Testing.h b/vtkm/testing/Testing.h index 45a0efaa0..7c66ce681 100644 --- a/vtkm/testing/Testing.h +++ b/vtkm/testing/Testing.h @@ -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::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::DimensionalityTag, + vtkm::TypeTraitsScalarTag>::type::value), + "Trying to compare a scalar with a vector."); + + // Do all comparisons using 64-bit floats. + return DoIt( + static_cast(scalar1), static_cast(scalar2), tolerance); + } + VTKM_EXEC_CONT bool operator()(T1 value1, T2 value2, vtkm::Float64 tolerance) const { return this->DoIt( diff --git a/vtkm/worklet/AverageByKey.h b/vtkm/worklet/AverageByKey.h index 7f27e3e2c..4b1fbb510 100644 --- a/vtkm/worklet/AverageByKey.h +++ b/vtkm/worklet/AverageByKey.h @@ -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 - VTKM_CONT static void Run(const vtkm::worklet::Keys& keys, + template + VTKM_CONT static void Run(const vtkm::worklet::internal::KeysBase& keys, const vtkm::cont::ArrayHandle& inValues, vtkm::cont::ArrayHandle& 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 + template VTKM_CONT static vtkm::cont::ArrayHandle Run( - const vtkm::worklet::Keys& keys, + const vtkm::worklet::internal::KeysBase& keys, const vtkm::cont::ArrayHandle& inValues) { diff --git a/vtkm/worklet/Clip.h b/vtkm/worklet/Clip.h index 38a1086ad..6197787da 100644 --- a/vtkm/worklet/Clip.h +++ b/vtkm/worklet/Clip.h @@ -901,6 +901,11 @@ public: return result; } + vtkm::cont::ArrayHandle GetCellMapOutputToInput() const + { + return this->CellMapOutputToInput; + } + private: internal::ClipTables ClipTablesInstance; vtkm::cont::ArrayHandle EdgePointsInterpolation; diff --git a/vtkm/worklet/Contour.h b/vtkm/worklet/Contour.h index 0e13588f1..c28c5ec09 100644 --- a/vtkm/worklet/Contour.h +++ b/vtkm/worklet/Contour.h @@ -84,6 +84,9 @@ public: //---------------------------------------------------------------------------- bool GetMergeDuplicatePoints() const { return this->SharedState.MergeDuplicatePoints; } + //---------------------------------------------------------------------------- + vtkm::cont::ArrayHandle GetCellIdMap() const { return this->SharedState.CellIdMap; } + //---------------------------------------------------------------------------- template GetCellIdMap() const { return this->CellIdMap; } + private: vtkm::cont::ArrayHandle CellIdMap; bool PassPolyData; diff --git a/vtkm/worklet/ExtractGeometry.h b/vtkm/worklet/ExtractGeometry.h index a4d9fd358..58698a49d 100644 --- a/vtkm/worklet/ExtractGeometry.h +++ b/vtkm/worklet/ExtractGeometry.h @@ -168,6 +168,8 @@ public: return result; } + vtkm::cont::ArrayHandle GetValidCellIds() const { return this->ValidCellIds; } + private: vtkm::cont::ArrayHandle ValidCellIds; }; diff --git a/vtkm/worklet/Keys.h b/vtkm/worklet/Keys.h index 86058168c..ab9b7841a 100644 --- a/vtkm/worklet/Keys.h +++ b/vtkm/worklet/Keys.h @@ -30,6 +30,8 @@ #include #include +#include + #include #include @@ -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 GetSortedValuesMap() const { return this->SortedValuesMap; } + + VTKM_CONT + vtkm::cont::ArrayHandle GetOffsets() const { return this->Offsets; } + + VTKM_CONT + vtkm::cont::ArrayHandle GetCounts() const { return this->Counts; } + + VTKM_CONT + vtkm::Id GetNumberOfValues() const { return this->SortedValuesMap.GetNumberOfValues(); } + + template + struct ExecutionTypes + { + using IdPortal = + typename vtkm::cont::ArrayHandle::template ExecutionTypes::PortalConst; + using IdComponentPortal = typename vtkm::cont::ArrayHandle< + vtkm::IdComponent>::template ExecutionTypes::PortalConst; + + using Lookup = vtkm::exec::internal::ReduceByKeyLookupBase; + }; + + template + VTKM_CONT typename ExecutionTypes::Lookup PrepareForInput(Device device, + vtkm::cont::Token& token) const + { + return + typename ExecutionTypes::Lookup(this->SortedValuesMap.PrepareForInput(device, token), + this->Offsets.PrepareForInput(device, token), + this->Counts.PrepareForInput(device, token)); + } + + template + VTKM_CONT VTKM_DEPRECATED(1.6, "PrepareForInput now requires a vtkm::cont::Token object.") + typename ExecutionTypes::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 SortedValuesMap; + vtkm::cont::ArrayHandle Offsets; + vtkm::cont::ArrayHandle 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 -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 GetSortedValuesMap() const { return this->SortedValuesMap; } - - VTKM_CONT - vtkm::cont::ArrayHandle GetOffsets() const { return this->Offsets; } - - VTKM_CONT - vtkm::cont::ArrayHandle GetCounts() const { return this->Counts; } - - VTKM_CONT - vtkm::Id GetNumberOfValues() const { return this->SortedValuesMap.GetNumberOfValues(); } - template struct ExecutionTypes { @@ -173,9 +237,6 @@ public: private: /// @cond NONE KeyArrayHandleType UniqueKeys; - vtkm::cont::ArrayHandle SortedValuesMap; - vtkm::cont::ArrayHandle Offsets; - vtkm::cont::ArrayHandle Counts; template VTKM_CONT void BuildArraysInternal(KeyArrayType& keys, vtkm::cont::DeviceAdapterId device); @@ -189,6 +250,9 @@ private: template VTKM_CONT Keys::Keys() = default; +namespace internal +{ + template inline auto SchedulingRange(const vtkm::worklet::Keys& inputDomain) -> decltype(inputDomain.GetInputRange()) @@ -202,6 +266,19 @@ inline auto SchedulingRange(const vtkm::worklet::Keys* 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 -struct TypeCheck> +struct TypeCheck { - static constexpr bool value = true; + static constexpr bool value = + std::is_base_of::type>::value; }; template -struct Transport, Device> +struct Transport { - using ContObjectType = vtkm::worklet::Keys; + using ContObjectType = KeyType; using ExecObjectType = typename ContObjectType::template ExecutionTypes::Lookup; VTKM_CONT @@ -264,9 +342,8 @@ struct Transport::PortalConst; - template VTKM_CONT ExecObjectType operator()(const ContObjectType& object, - const vtkm::worklet::Keys& keys, + const vtkm::worklet::internal::KeysBase& keys, vtkm::Id, vtkm::Id, vtkm::cont::Token& token) const @@ -300,9 +377,8 @@ struct Transport::Portal; - template VTKM_CONT ExecObjectType operator()(ContObjectType object, - const vtkm::worklet::Keys& keys, + const vtkm::worklet::internal::KeysBase& keys, vtkm::Id, vtkm::Id, vtkm::cont::Token& token) const @@ -336,9 +412,8 @@ struct Transport::Portal; - template VTKM_CONT ExecObjectType operator()(ContObjectType object, - const vtkm::worklet::Keys& keys, + const vtkm::worklet::internal::KeysBase& keys, vtkm::Id, vtkm::Id, vtkm::cont::Token& token) const diff --git a/vtkm/worklet/Mask.h b/vtkm/worklet/Mask.h index 3d7f74201..a41b15563 100644 --- a/vtkm/worklet/Mask.h +++ b/vtkm/worklet/Mask.h @@ -58,6 +58,8 @@ public: return result; } + vtkm::cont::ArrayHandle GetValidCellIds() const { return this->ValidCellIds; } + private: vtkm::cont::ArrayHandle ValidCellIds; }; diff --git a/vtkm/worklet/PointMerge.h b/vtkm/worklet/PointMerge.h index 939dde941..1575f1043 100644 --- a/vtkm/worklet/PointMerge.h +++ b/vtkm/worklet/PointMerge.h @@ -473,6 +473,8 @@ public: return outArray; } + vtkm::worklet::Keys GetMergeKeys() const { return this->MergeKeys; } + private: vtkm::worklet::Keys MergeKeys; vtkm::cont::ArrayHandle PointInputToOutputMap; diff --git a/vtkm/worklet/Probe.h b/vtkm/worklet/Probe.h index 3009d8e74..47c8a16b0 100644 --- a/vtkm/worklet/Probe.h +++ b/vtkm/worklet/Probe.h @@ -257,6 +257,8 @@ public: return result; } + vtkm::cont::ArrayHandle GetCellIds() const { return this->CellIds; } + //============================================================================ struct HiddenPointsWorklet : public WorkletMapField { diff --git a/vtkm/worklet/RemoveDegenerateCells.h b/vtkm/worklet/RemoveDegenerateCells.h index 3a86b2a58..0a3f5a3fd 100644 --- a/vtkm/worklet/RemoveDegenerateCells.h +++ b/vtkm/worklet/RemoveDegenerateCells.h @@ -166,6 +166,8 @@ struct RemoveDegenerateCells return result; } + vtkm::cont::ArrayHandle GetValidCellIds() const { return this->ValidCellIds; } + private: vtkm::cont::ArrayHandle ValidCellIds; }; diff --git a/vtkm/worklet/RemoveUnusedPoints.h b/vtkm/worklet/RemoveUnusedPoints.h index fa4b9dbca..1979da67d 100644 --- a/vtkm/worklet/RemoveUnusedPoints.h +++ b/vtkm/worklet/RemoveUnusedPoints.h @@ -239,6 +239,11 @@ public: return outArray; } + const vtkm::worklet::ScatterCounting& GetPointScatter() const + { + return *this->PointScatter.get(); + } + private: vtkm::cont::ArrayHandle MaskArray; diff --git a/vtkm/worklet/SplitSharpEdges.h b/vtkm/worklet/SplitSharpEdges.h index 819a0bafa..f9d686f03 100644 --- a/vtkm/worklet/SplitSharpEdges.h +++ b/vtkm/worklet/SplitSharpEdges.h @@ -516,6 +516,8 @@ public: return result; } + vtkm::cont::ArrayHandle GetNewPointsIdArray() const { return this->NewPointsIdArray; } + private: vtkm::cont::ArrayHandle NewPointsIdArray; }; diff --git a/vtkm/worklet/Tetrahedralize.h b/vtkm/worklet/Tetrahedralize.h index 881bfd57a..df9d8c60c 100644 --- a/vtkm/worklet/Tetrahedralize.h +++ b/vtkm/worklet/Tetrahedralize.h @@ -45,7 +45,7 @@ public: }; Tetrahedralize() - : OutCellsPerCell() + : OutCellScatter(vtkm::cont::ArrayHandle{}) { } @@ -54,14 +54,20 @@ public: vtkm::cont::CellSetSingleType<> Run(const CellSetType& cellSet) { TetrahedralizeExplicit worklet; - return worklet.Run(cellSet, this->OutCellsPerCell); + vtkm::cont::ArrayHandle 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 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 output; - vtkm::worklet::DispatcherMapField dispatcher( - DistributeCellData::MakeScatter(this->OutCellsPerCell)); + vtkm::worklet::DispatcherMapField dispatcher(this->OutCellScatter); dispatcher.Invoke(input, output); return output; } + DistributeCellData::ScatterType GetOutCellScatter() const { return this->OutCellScatter; } + private: - vtkm::cont::ArrayHandle OutCellsPerCell; + DistributeCellData::ScatterType OutCellScatter; }; } } // namespace vtkm::worklet diff --git a/vtkm/worklet/Threshold.h b/vtkm/worklet/Threshold.h index a9774af9b..cdcd4f8c8 100644 --- a/vtkm/worklet/Threshold.h +++ b/vtkm/worklet/Threshold.h @@ -185,6 +185,8 @@ public: return result; } + vtkm::cont::ArrayHandle GetValidCellIds() const { return this->ValidCellIds; } + private: vtkm::cont::ArrayHandle ValidCellIds; }; diff --git a/vtkm/worklet/Triangulate.h b/vtkm/worklet/Triangulate.h index 734698309..cc1f41a72 100644 --- a/vtkm/worklet/Triangulate.h +++ b/vtkm/worklet/Triangulate.h @@ -44,7 +44,7 @@ public: }; Triangulate() - : OutCellsPerCell() + : OutCellScatter(vtkm::cont::ArrayHandle{}) { } @@ -53,14 +53,20 @@ public: vtkm::cont::CellSetSingleType<> Run(const CellSetType& cellSet) { TriangulateExplicit worklet; - return worklet.Run(cellSet, this->OutCellsPerCell); + vtkm::cont::ArrayHandle 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 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 output; - vtkm::worklet::DispatcherMapField dispatcher( - DistributeCellData::MakeScatter(this->OutCellsPerCell)); + vtkm::worklet::DispatcherMapField dispatcher(this->OutCellScatter); dispatcher.Invoke(input, output); return output; } + DistributeCellData::ScatterType GetOutCellScatter() const { return this->OutCellScatter; } + private: - vtkm::cont::ArrayHandle OutCellsPerCell; + DistributeCellData::ScatterType OutCellScatter; }; } } // namespace vtkm::worklet diff --git a/vtkm/worklet/Tube.h b/vtkm/worklet/Tube.h index 22e2b906b..ce70e8a34 100644 --- a/vtkm/worklet/Tube.h +++ b/vtkm/worklet/Tube.h @@ -628,6 +628,15 @@ public: return output; } + vtkm::cont::ArrayHandle GetOutputCellSourceIndex() const + { + return this->OutputCellSourceIndex; + } + vtkm::cont::ArrayHandle GetOutputPointSourceIndex() const + { + return this->OutputPointSourceIndex; + } + private: bool Capping; vtkm::Id NumSides; diff --git a/vtkm/worklet/VertexClustering.h b/vtkm/worklet/VertexClustering.h index 792773e07..4e4a79cf6 100644 --- a/vtkm/worklet/VertexClustering.h +++ b/vtkm/worklet/VertexClustering.h @@ -122,10 +122,6 @@ vtkm::cont::ArrayHandle copyFromVec(vtkm::cont::ArrayHandle> struct VertexClustering { - using PointIdMapType = vtkm::cont::ArrayHandlePermutation< - vtkm::cont::ArrayHandleView>, - vtkm::cont::ArrayHandle>; - 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 GetPointIdMap() const { return this->PointIdMap; } + vtkm::cont::ArrayHandle GetCellIdMap() const { return this->CellIdMap; } + private: - PointIdMapType PointIdMap; + vtkm::cont::ArrayHandle PointIdMap; vtkm::cont::ArrayHandle CellIdMap; }; // struct VertexClustering } diff --git a/vtkm/worklet/testing/UnitTestWorkletReduceByKey.cxx b/vtkm/worklet/testing/UnitTestWorkletReduceByKey.cxx index d8a4e7187..98a82743d 100644 --- a/vtkm/worklet/testing/UnitTestWorkletReduceByKey.cxx +++ b/vtkm/worklet/testing/UnitTestWorkletReduceByKey.cxx @@ -128,6 +128,9 @@ void TryKeyType(KeyType) vtkm::cont::ArrayCopy(keyArray, sortedKeys); vtkm::worklet::Keys 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 valuesToModify; valuesToModify.Allocate(ARRAY_SIZE);