From 934732bb642f20b52362cc195c63417f45ebcc4d Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Mon, 3 Feb 2020 11:00:31 -0700 Subject: [PATCH 1/8] Add MapFieldPermutation function This function is compiled into the vtkm_filter library, so all filters can implement this type of mapping without providing their own version of compiling it. Because we only compile it once, we provide more types to convert. Hopefully the total compile time balances out. --- vtkm/filter/CMakeLists.txt | 2 + vtkm/filter/MapFieldPermutation.cxx | 73 +++++++++++ vtkm/filter/MapFieldPermutation.h | 72 +++++++++++ vtkm/filter/testing/CMakeLists.txt | 1 + .../testing/UnitTestMapFieldPermutation.cxx | 114 ++++++++++++++++++ 5 files changed, 262 insertions(+) create mode 100644 vtkm/filter/MapFieldPermutation.cxx create mode 100644 vtkm/filter/MapFieldPermutation.h create mode 100644 vtkm/filter/testing/UnitTestMapFieldPermutation.cxx diff --git a/vtkm/filter/CMakeLists.txt b/vtkm/filter/CMakeLists.txt index 631314d61..2b56dc0d3 100644 --- a/vtkm/filter/CMakeLists.txt +++ b/vtkm/filter/CMakeLists.txt @@ -45,6 +45,7 @@ set(headers ImageMedian.h Lagrangian.h LagrangianStructures.h + MapFieldPermutation.h Mask.h MaskPoints.h MeshQuality.h @@ -154,6 +155,7 @@ set(sources_device GradientScalar.cxx GradientUniformPoints.cxx GradientVector.cxx + MapFieldPermutation.cxx PointAverage.cxx Threshold.cxx VectorMagnitude.cxx diff --git a/vtkm/filter/MapFieldPermutation.cxx b/vtkm/filter/MapFieldPermutation.cxx new file mode 100644 index 000000000..ac3f24b5a --- /dev/null +++ b/vtkm/filter/MapFieldPermutation.cxx @@ -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. +//============================================================================ + +#include + +#include + +#include +#include +#include + +#include + +namespace +{ + +struct DoMapFieldPermutation +{ + bool CalledMap = false; + + template + void operator()(const vtkm::cont::ArrayHandle& inputArray, + const vtkm::cont::ArrayHandle& permutation, + vtkm::cont::VariantArrayHandle& output) + { + vtkm::cont::ArrayHandle outputArray; + vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandlePermutation(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::cont::VariantArrayHandle outputArray; + DoMapFieldPermutation functor; + inputField.GetData().ResetTypes().CastAndCall( + vtkm::filter::PolicyDefault::StorageList{}, functor, permutation, 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 MapFieldPermutation(const vtkm::cont::Field& inputField, + const vtkm::cont::ArrayHandle& permutation, + vtkm::cont::DataSet& outputData) +{ + vtkm::cont::Field outputField; + bool success = vtkm::filter::MapFieldPermutation(inputField, permutation, outputField); + 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..cd62d17d5 --- /dev/null +++ b/vtkm/filter/MapFieldPermutation.h @@ -0,0 +1,72 @@ +//============================================================================ +// 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. +/// +VTKM_FILTER_EXPORT VTKM_CONT bool MapFieldPermutation( + const vtkm::cont::Field& inputField, + const vtkm::cont::ArrayHandle& permutation, + vtkm::cont::Field& outputField); + +/// \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`. +/// +VTKM_FILTER_EXPORT VTKM_CONT bool MapFieldPermutation( + const vtkm::cont::Field& inputField, + const vtkm::cont::ArrayHandle& permutation, + vtkm::cont::DataSet& outputData); +} +} // namespace vtkm::filter + +#endif //vtk_m_filter_MapFieldPermutation_h diff --git a/vtkm/filter/testing/CMakeLists.txt b/vtkm/filter/testing/CMakeLists.txt index 607dc7ed7..f34cf59bc 100644 --- a/vtkm/filter/testing/CMakeLists.txt +++ b/vtkm/filter/testing/CMakeLists.txt @@ -39,6 +39,7 @@ set(unit_tests UnitTestImageMedianFilter.cxx UnitTestLagrangianFilter.cxx UnitTestLagrangianStructuresFilter.cxx + UnitTestMapFieldPermutation.cxx UnitTestMaskFilter.cxx UnitTestMaskPointsFilter.cxx UnitTestMeshQualityFilter.cxx 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); +} From b1f288aaeaa21e6db1ce5b2765e0829966f28658 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Mon, 3 Feb 2020 23:00:22 -0600 Subject: [PATCH 2/8] Add non-templated base class to Keys class. The only reason Keys has a template is so that it can hold a UniqueKeys array and provide the key for each group. If that is not needed and you want to implement a library function that takes a keys object, you can now grab the Keys superclass KeysBase. KeysBase is not templated, so you can pass it to a standard method in a library. --- vtkm/cont/arg/TypeCheckTagKeys.h | 10 +- vtkm/exec/arg/ThreadIndicesReduceByKey.h | 4 +- vtkm/exec/internal/ReduceByKeyLookup.h | 43 ++++-- vtkm/worklet/AverageByKey.h | 11 +- vtkm/worklet/Keys.h | 133 ++++++++++++++---- .../testing/UnitTestWorkletReduceByKey.cxx | 3 + 6 files changed, 146 insertions(+), 58 deletions(-) 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/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/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/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); From 2383a7fffd929066995cdfdf69806d616b3a6913 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Tue, 4 Feb 2020 21:36:34 -0600 Subject: [PATCH 3/8] Add MapFieldPermutation function This function is compiled into the vtkm_filter library, so all filters can implement this type of mapping without providing their own version of compiling it. Because we only compile it once, we provide more types to convert. Hopefully the total compile time balances out. --- vtkm/filter/CMakeLists.txt | 2 + vtkm/filter/MapFieldMergeAverage.cxx | 69 ++++++++ vtkm/filter/MapFieldMergeAverage.h | 73 +++++++++ vtkm/filter/testing/CMakeLists.txt | 1 + .../testing/UnitTestMapFieldMergeAverage.cxx | 151 ++++++++++++++++++ 5 files changed, 296 insertions(+) create mode 100644 vtkm/filter/MapFieldMergeAverage.cxx create mode 100644 vtkm/filter/MapFieldMergeAverage.h create mode 100644 vtkm/filter/testing/UnitTestMapFieldMergeAverage.cxx diff --git a/vtkm/filter/CMakeLists.txt b/vtkm/filter/CMakeLists.txt index 2b56dc0d3..977af9df4 100644 --- a/vtkm/filter/CMakeLists.txt +++ b/vtkm/filter/CMakeLists.txt @@ -45,6 +45,7 @@ set(headers ImageMedian.h Lagrangian.h LagrangianStructures.h + MapFieldMergeAverage.h MapFieldPermutation.h Mask.h MaskPoints.h @@ -155,6 +156,7 @@ set(sources_device GradientScalar.cxx GradientUniformPoints.cxx GradientVector.cxx + MapFieldMergeAverage.cxx MapFieldPermutation.cxx PointAverage.cxx Threshold.cxx 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/testing/CMakeLists.txt b/vtkm/filter/testing/CMakeLists.txt index f34cf59bc..d1181398a 100644 --- a/vtkm/filter/testing/CMakeLists.txt +++ b/vtkm/filter/testing/CMakeLists.txt @@ -39,6 +39,7 @@ set(unit_tests UnitTestImageMedianFilter.cxx UnitTestLagrangianFilter.cxx UnitTestLagrangianStructuresFilter.cxx + UnitTestMapFieldMergeAverage.cxx UnitTestMapFieldPermutation.cxx UnitTestMaskFilter.cxx UnitTestMaskPointsFilter.cxx diff --git a/vtkm/filter/testing/UnitTestMapFieldMergeAverage.cxx b/vtkm/filter/testing/UnitTestMapFieldMergeAverage.cxx new file mode 100644 index 000000000..b034f107a --- /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 = sum + inputPortal.Get(fullI); + num = 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); +} From 4a5dbb65dbb4eba201706f82373f046e37ba763d Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Tue, 4 Feb 2020 22:44:10 -0600 Subject: [PATCH 4/8] Convert CleanGrid (and dependents) to use precompiled field map --- vtkm/filter/CleanGrid.cxx | 43 ++++++++++++++++++++++++++++ vtkm/filter/CleanGrid.h | 39 +++++-------------------- vtkm/filter/ExternalFaces.cxx | 22 ++++++++++++++ vtkm/filter/ExternalFaces.h | 37 ++++++------------------ vtkm/filter/ExtractPoints.h | 9 +++--- vtkm/filter/ExtractPoints.hxx | 13 ++++----- vtkm/filter/MapFieldPermutation.cxx | 6 ++-- vtkm/filter/MaskPoints.h | 9 +++--- vtkm/filter/MaskPoints.hxx | 15 +++++----- vtkm/filter/ThresholdPoints.h | 11 +++---- vtkm/filter/ThresholdPoints.hxx | 13 ++++----- vtkm/worklet/ExternalFaces.h | 2 ++ vtkm/worklet/PointMerge.h | 2 ++ vtkm/worklet/RemoveDegenerateCells.h | 2 ++ vtkm/worklet/RemoveUnusedPoints.h | 5 ++++ 15 files changed, 126 insertions(+), 102 deletions(-) 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/ExternalFaces.cxx b/vtkm/filter/ExternalFaces.cxx index caafe4f06..2edb74a7b 100644 --- a/vtkm/filter/ExternalFaces.cxx +++ b/vtkm/filter/ExternalFaces.cxx @@ -64,6 +64,28 @@ 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); + } + + 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/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..b657da9a9 100644 --- a/vtkm/filter/ExtractPoints.hxx +++ b/vtkm/filter/ExtractPoints.hxx @@ -65,23 +65,22 @@ 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; } } diff --git a/vtkm/filter/MapFieldPermutation.cxx b/vtkm/filter/MapFieldPermutation.cxx index ac3f24b5a..62a908763 100644 --- a/vtkm/filter/MapFieldPermutation.cxx +++ b/vtkm/filter/MapFieldPermutation.cxx @@ -59,9 +59,9 @@ bool vtkm::filter::MapFieldPermutation(const vtkm::cont::Field& inputField, return functor.CalledMap; } -bool MapFieldPermutation(const vtkm::cont::Field& inputField, - const vtkm::cont::ArrayHandle& permutation, - vtkm::cont::DataSet& outputData) +bool vtkm::filter::MapFieldPermutation(const vtkm::cont::Field& inputField, + const vtkm::cont::ArrayHandle& permutation, + vtkm::cont::DataSet& outputData) { vtkm::cont::Field outputField; bool success = vtkm::filter::MapFieldPermutation(inputField, permutation, outputField); 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..0dd877e5c 100644 --- a/vtkm/filter/MaskPoints.hxx +++ b/vtkm/filter/MaskPoints.hxx @@ -58,22 +58,21 @@ 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; } } 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..4ebddbdde 100644 --- a/vtkm/filter/ThresholdPoints.hxx +++ b/vtkm/filter/ThresholdPoints.hxx @@ -187,23 +187,22 @@ 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; } } diff --git a/vtkm/worklet/ExternalFaces.h b/vtkm/worklet/ExternalFaces.h index 57b1be245..d6e4de895 100644 --- a/vtkm/worklet/ExternalFaces.h +++ b/vtkm/worklet/ExternalFaces.h @@ -953,6 +953,8 @@ public: } } + vtkm::cont::ArrayHandle GetCellIdMap() const { return this->CellIdMap; } + private: vtkm::cont::ArrayHandle CellIdMap; bool PassPolyData; 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/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; From 98f20ec2692deebc50b86803e063abded02e5ec3 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Thu, 6 Feb 2020 11:57:54 -0600 Subject: [PATCH 5/8] Use a worklet to permute fields rather than ArrayHandlePermutation According to talks with Rob Maynard, using a worklet should be (counterintuitively) faster than using ArrayHandlePermutation with ArrayCopy. This change also gives an opportunity to handle invalid indices, which may be intentionally set when no mapping is available for that value. For this case, MapFieldPermutation now takes an invalidValue argument to set such values. --- vtkm/filter/MapFieldPermutation.cxx | 82 +++++++++++++++++++++++++---- vtkm/filter/MapFieldPermutation.h | 14 ++++- 2 files changed, 85 insertions(+), 11 deletions(-) diff --git a/vtkm/filter/MapFieldPermutation.cxx b/vtkm/filter/MapFieldPermutation.cxx index 62a908763..d7948fae6 100644 --- a/vtkm/filter/MapFieldPermutation.cxx +++ b/vtkm/filter/MapFieldPermutation.cxx @@ -11,16 +11,75 @@ #include #include +#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; @@ -28,11 +87,13 @@ struct DoMapFieldPermutation template void operator()(const vtkm::cont::ArrayHandle& inputArray, const vtkm::cont::ArrayHandle& permutation, - vtkm::cont::VariantArrayHandle& output) + vtkm::cont::VariantArrayHandle& output, + vtkm::Float64 invalidValue) { vtkm::cont::ArrayHandle outputArray; - vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandlePermutation(permutation, inputArray), - outputArray); + MapPermutationWorklet worklet(CastInvalidValue(invalidValue)); + vtkm::cont::Invoker invoke; + invoke(worklet, permutation, inputArray, outputArray); output = vtkm::cont::VariantArrayHandle(outputArray); this->CalledMap = true; } @@ -42,12 +103,13 @@ struct DoMapFieldPermutation bool vtkm::filter::MapFieldPermutation(const vtkm::cont::Field& inputField, const vtkm::cont::ArrayHandle& permutation, - vtkm::cont::Field& outputField) + vtkm::cont::Field& outputField, + vtkm::Float64 invalidValue) { vtkm::cont::VariantArrayHandle outputArray; DoMapFieldPermutation functor; inputField.GetData().ResetTypes().CastAndCall( - vtkm::filter::PolicyDefault::StorageList{}, functor, permutation, outputArray); + vtkm::filter::PolicyDefault::StorageList{}, functor, permutation, outputArray, invalidValue); if (functor.CalledMap) { outputField = vtkm::cont::Field(inputField.GetName(), inputField.GetAssociation(), outputArray); @@ -61,10 +123,12 @@ bool vtkm::filter::MapFieldPermutation(const vtkm::cont::Field& inputField, bool vtkm::filter::MapFieldPermutation(const vtkm::cont::Field& inputField, const vtkm::cont::ArrayHandle& permutation, - vtkm::cont::DataSet& outputData) + vtkm::cont::DataSet& outputData, + vtkm::Float64 invalidValue) { vtkm::cont::Field outputField; - bool success = vtkm::filter::MapFieldPermutation(inputField, permutation, outputField); + bool success = + vtkm::filter::MapFieldPermutation(inputField, permutation, outputField, invalidValue); if (success) { outputData.AddField(outputField); diff --git a/vtkm/filter/MapFieldPermutation.h b/vtkm/filter/MapFieldPermutation.h index cd62d17d5..7a4fc168c 100644 --- a/vtkm/filter/MapFieldPermutation.h +++ b/vtkm/filter/MapFieldPermutation.h @@ -39,10 +39,15 @@ namespace filter /// `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::cont::Field& outputField, + vtkm::Float64 invalidValue = vtkm::Nan()); /// \brief Maps a field by permuting it by a given index array. /// @@ -62,10 +67,15 @@ VTKM_FILTER_EXPORT VTKM_CONT bool MapFieldPermutation( /// `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::cont::DataSet& outputData, + vtkm::Float64 invalidValue = vtkm::Nan()); } } // namespace vtkm::filter From 3c4e8a2ea5e058809e5c1f09d96af00f51af00ca Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Thu, 6 Feb 2020 15:58:59 -0600 Subject: [PATCH 6/8] Convert filters to use precompiled field map functions where applicable --- examples/game_of_life/GameOfLife.cxx | 9 ++--- vtkm/filter/CMakeLists.txt | 1 + vtkm/filter/ClipWithField.cxx | 25 ++++++++++++ vtkm/filter/ClipWithField.h | 36 +++++++++++------ vtkm/filter/ClipWithImplicitFunction.cxx | 24 +++++++++++ vtkm/filter/ClipWithImplicitFunction.h | 38 +++++++++++------- vtkm/filter/Contour.cxx | 25 ++++++++++++ vtkm/filter/Contour.h | 35 ++++++++++------ vtkm/filter/ExtractGeometry.cxx | 51 ++++++++++++++++++++++++ vtkm/filter/ExtractGeometry.h | 27 ++++++++----- vtkm/filter/ExtractGeometry.hxx | 37 ----------------- vtkm/filter/ExtractStructured.cxx | 26 ++++++++++++ vtkm/filter/ExtractStructured.h | 43 ++++++++++---------- vtkm/filter/ExtractStructured.hxx | 9 +++++ vtkm/filter/GhostCellRemove.h | 11 +++-- vtkm/filter/GhostCellRemove.hxx | 21 +++++----- vtkm/filter/Lagrangian.h | 9 ++--- vtkm/filter/Lagrangian.hxx | 9 ++--- vtkm/filter/LagrangianStructures.h | 11 +++-- vtkm/filter/LagrangianStructures.hxx | 7 ++-- vtkm/filter/Mask.h | 9 ++--- vtkm/filter/Mask.hxx | 25 +++++------- vtkm/filter/NDEntropy.h | 9 ++--- vtkm/filter/NDEntropy.hxx | 9 ++--- vtkm/filter/NDHistogram.h | 9 ++--- vtkm/filter/NDHistogram.hxx | 9 ++--- vtkm/filter/Pathline.h | 11 ++--- vtkm/filter/Pathline.hxx | 9 ++--- vtkm/filter/Probe.h | 9 ++++- vtkm/filter/Probe.hxx | 44 +++++++++++++------- vtkm/filter/SplitSharpEdges.h | 11 ++--- vtkm/filter/SplitSharpEdges.hxx | 24 +++++------ vtkm/filter/StreamSurface.h | 13 +++--- vtkm/filter/StreamSurface.hxx | 11 ++--- vtkm/filter/Streamline.h | 13 +++--- vtkm/filter/Streamline.hxx | 11 ++--- vtkm/filter/Tetrahedralize.h | 11 ++--- vtkm/filter/Tetrahedralize.hxx | 27 +++++++------ vtkm/filter/Threshold.cxx | 21 ++++++++++ vtkm/filter/Threshold.h | 31 +++++--------- vtkm/filter/Triangulate.h | 11 ++--- vtkm/filter/Triangulate.hxx | 30 +++++++------- vtkm/filter/Tube.h | 13 +++--- vtkm/filter/Tube.hxx | 33 ++++++++------- vtkm/filter/VertexClustering.h | 13 +++--- vtkm/filter/VertexClustering.hxx | 36 +++++++---------- vtkm/filter/ZFPCompressor1D.h | 14 +++---- vtkm/filter/ZFPCompressor1D.hxx | 10 ----- vtkm/filter/ZFPCompressor2D.h | 14 +++---- vtkm/filter/ZFPCompressor2D.hxx | 10 ----- vtkm/filter/ZFPCompressor3D.h | 14 +++---- vtkm/filter/ZFPCompressor3D.hxx | 10 ----- vtkm/filter/ZFPDecompressor1D.h | 14 +++---- vtkm/filter/ZFPDecompressor1D.hxx | 10 ----- vtkm/filter/ZFPDecompressor2D.h | 14 +++---- vtkm/filter/ZFPDecompressor2D.hxx | 10 ----- vtkm/filter/ZFPDecompressor3D.h | 14 +++---- vtkm/filter/ZFPDecompressor3D.hxx | 10 ----- vtkm/filter/testing/UnitTestProbe.cxx | 20 +++++++--- vtkm/testing/Testing.h | 44 ++++++++++++++------ vtkm/worklet/Clip.h | 5 +++ vtkm/worklet/Contour.h | 3 ++ vtkm/worklet/ExtractGeometry.h | 2 + vtkm/worklet/Mask.h | 2 + vtkm/worklet/Probe.h | 2 + vtkm/worklet/SplitSharpEdges.h | 2 + vtkm/worklet/Tetrahedralize.h | 19 ++++++--- vtkm/worklet/Threshold.h | 2 + vtkm/worklet/Triangulate.h | 19 ++++++--- vtkm/worklet/Tube.h | 9 +++++ vtkm/worklet/VertexClustering.h | 12 +++--- 71 files changed, 686 insertions(+), 505 deletions(-) create mode 100644 vtkm/filter/ExtractGeometry.cxx 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/filter/CMakeLists.txt b/vtkm/filter/CMakeLists.txt index 977af9df4..d00bf0697 100644 --- a/vtkm/filter/CMakeLists.txt +++ b/vtkm/filter/CMakeLists.txt @@ -152,6 +152,7 @@ set(sources_device ContourInteger.cxx ContourScalar.cxx ExternalFaces.cxx + ExtractGeometry.cxx ExtractStructured.cxx GradientScalar.cxx GradientUniformPoints.cxx diff --git a/vtkm/filter/ClipWithField.cxx b/vtkm/filter/ClipWithField.cxx index 017fe3259..eee6e4d2b 100644 --- a/vtkm/filter/ClipWithField.cxx +++ b/vtkm/filter/ClipWithField.cxx @@ -11,10 +11,35 @@ #include +#include + namespace vtkm { namespace filter { + +VTKM_FILTER_EXPORT bool ClipWithField::MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field) +{ + if (field.IsFieldPoint()) + { + // Handled by DoMapField, which the superclass will call. + // Actually already done by other version of MapFieldOntoOutput. (Stupid policies.) + //return this->FilterDataSetWithField::MapFieldOntoOutput(result, field, policy); + VTKM_ASSERT(false && "Should not be here"); + return false; + } + else if (field.IsFieldCell()) + { + vtkm::cont::ArrayHandle permutation = this->Worklet.GetCellMapOutputToInput(); + return vtkm::filter::MapFieldPermutation(field, permutation, result); + } + else + { + return false; + } +} + //----------------------------------------------------------------------------- VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(ClipWithField); } diff --git a/vtkm/filter/ClipWithField.h b/vtkm/filter/ClipWithField.h index e6817d767..e8eba9e63 100644 --- a/vtkm/filter/ClipWithField.h +++ b/vtkm/filter/ClipWithField.h @@ -46,6 +46,25 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, 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 policy) + { + if (field.IsFieldPoint()) + { + // DIE, POLICIES, DIE! + return this->FilterDataSetWithField::MapFieldOntoOutput(result, field, policy); + } + else + { + return this->MapFieldOntoOutput(result, field); + } + } + //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 +73,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.cxx b/vtkm/filter/ClipWithImplicitFunction.cxx index a5c4aa2a2..be9603a1e 100644 --- a/vtkm/filter/ClipWithImplicitFunction.cxx +++ b/vtkm/filter/ClipWithImplicitFunction.cxx @@ -11,10 +11,34 @@ #define vtkm_filter_ClipWithImplicitFunction_cxx #include +#include + namespace vtkm { namespace filter { + +VTKM_FILTER_EXPORT bool ClipWithImplicitFunction::MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field) +{ + if (field.IsFieldPoint()) + { + // Handled by DoMapField, which the superclass will call. + // Actually already done by other version of MapFieldOntoOutput. (Stupid policies.) + //return this->FilterDataSet::MapFieldOntoOutput(result, field, policy); + VTKM_ASSERT(false && "Should not be here"); + return false; + } + else if (field.IsFieldCell()) + { + vtkm::cont::ArrayHandle permutation = this->Worklet.GetCellMapOutputToInput(); + return vtkm::filter::MapFieldPermutation(field, permutation, result); + } + else + { + return false; + } +} //----------------------------------------------------------------------------- VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(ClipWithImplicitFunction); } diff --git a/vtkm/filter/ClipWithImplicitFunction.h b/vtkm/filter/ClipWithImplicitFunction.h index 457e99448..75300b985 100644 --- a/vtkm/filter/ClipWithImplicitFunction.h +++ b/vtkm/filter/ClipWithImplicitFunction.h @@ -43,6 +43,26 @@ public: vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, 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 policy) + { + if (field.IsFieldPoint()) + { + // DIE, POLICIES, DIE! + return this->FilterDataSet::MapFieldOntoOutput( + result, field, policy); + } + else + { + return this->MapFieldOntoOutput(result, field); + } + } + //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 +71,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.cxx b/vtkm/filter/Contour.cxx index c52ca1a15..cb2293694 100644 --- a/vtkm/filter/Contour.cxx +++ b/vtkm/filter/Contour.cxx @@ -10,6 +10,8 @@ #define vtkm_filter_Contour_cxx #include +#include + namespace vtkm { namespace filter @@ -67,5 +69,28 @@ VTKM_FILTER_EXPORT vtkm::Float64 Contour::GetIsoValue(vtkm::Id index) const { return this->IsoValues[static_cast(index)]; } + +//----------------------------------------------------------------------------- +VTKM_FILTER_EXPORT bool Contour::MapFieldOntoOutput(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field) +{ + if (field.IsFieldPoint()) + { + // Handled by DoMapField, which the superclass will call. + // Actually already done by other version of MapFieldOntoOutput. (Stupid policies.) + //return this->FilterDataSetWithField::MapFieldOntoOutput(result, field, policy); + VTKM_ASSERT(false && "Should not be here"); + return false; + } + else if (field.IsFieldCell()) + { + vtkm::cont::ArrayHandle permutation = this->Worklet.GetCellIdMap(); + return vtkm::filter::MapFieldPermutation(field, permutation, result); + } + else + { + return false; + } +} } } diff --git a/vtkm/filter/Contour.h b/vtkm/filter/Contour.h index 75b2fe0e3..917f8ea40 100644 --- a/vtkm/filter/Contour.h +++ b/vtkm/filter/Contour.h @@ -111,6 +111,25 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, 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 policy) + { + if (field.IsFieldPoint()) + { + // DIE, POLICIES, DIE! + return this->FilterDataSetWithField::MapFieldOntoOutput(result, field, policy); + } + else + { + return this->MapFieldOntoOutput(result, field); + } + } + //Map a new field onto the resulting dataset after running the filter //this call is only valid template @@ -119,20 +138,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/ExtractGeometry.cxx b/vtkm/filter/ExtractGeometry.cxx new file mode 100644 index 000000000..9901d1cd8 --- /dev/null +++ b/vtkm/filter/ExtractGeometry.cxx @@ -0,0 +1,51 @@ +//============================================================================ +// 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 + { + 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/ExtractStructured.cxx b/vtkm/filter/ExtractStructured.cxx index 3b1c6a1b4..4fd57c6d4 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,30 @@ 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); + } + + if (field.IsFieldCell()) + { + return vtkm::filter::MapFieldPermutation(field, this->CellFieldMap, result); + } + + 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..923664a43 100644 --- a/vtkm/filter/GhostCellRemove.hxx +++ b/vtkm/filter/GhostCellRemove.hxx @@ -19,6 +19,7 @@ #include #include +#include #include namespace @@ -360,24 +361,20 @@ 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 true; + return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetValidCellIds(), result); } 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..3050e649a 100644 --- a/vtkm/filter/Lagrangian.hxx +++ b/vtkm/filter/Lagrangian.hxx @@ -326,11 +326,10 @@ 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&, + const vtkm::cont::Field&, + vtkm::filter::PolicyBase) { return false; } 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..0d18a41ec 100644 --- a/vtkm/filter/LagrangianStructures.hxx +++ b/vtkm/filter/LagrangianStructures.hxx @@ -155,11 +155,10 @@ inline VTKM_CONT vtkm::cont::DataSet LagrangianStructures::DoExecute( } //----------------------------------------------------------------------------- -template -inline VTKM_CONT bool LagrangianStructures::DoMapField( +template +inline VTKM_CONT bool LagrangianStructures::MapFieldOntoOutput( vtkm::cont::DataSet&, - const vtkm::cont::ArrayHandle&, - const vtkm::filter::FieldMetadata&, + const vtkm::cont::Field&, vtkm::filter::PolicyBase) { return false; 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..ee97c5e98 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()) { - 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/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..96d343b35 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,37 @@ 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()) + { + // This is a special interpolation that is handled by DoMapField. The superclass' + // MapFieldOntoOutput will handle this. + return this->FilterDataSet::MapFieldOntoOutput(result, field, policy); + } + + if (field.IsFieldCell()) + { + return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetCellIds(), result); + } + + 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..9da6c989f 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()) { - 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..cbe0c233f 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,27 +63,24 @@ 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)); + result.AddField(field); return true; } // cell data must be scattered to the cells created per input cell - if (fieldMeta.IsCellField()) + if (field.IsFieldCell()) { - vtkm::cont::ArrayHandle output = this->Worklet.ProcessCellField(input); - - result.AddField(fieldMeta.AsField(output)); - return true; + vtkm::cont::ArrayHandle permutation = + this->Worklet.GetOutCellScatter().GetOutputToInputMap(); + return vtkm::filter::MapFieldPermutation(field, permutation, result); } return false; diff --git a/vtkm/filter/Threshold.cxx b/vtkm/filter/Threshold.cxx index bb4b5b904..19c0f3448 100644 --- a/vtkm/filter/Threshold.cxx +++ b/vtkm/filter/Threshold.cxx @@ -10,10 +10,31 @@ #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()) + { + //we copy the input handle to the result dataset, reusing the metadata + result.AddField(field); + return true; + } + + if (field.IsFieldCell()) + { + return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetValidCellIds(), result); + } + + 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/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..f5e0a23fa 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,26 +85,24 @@ 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)); + result.AddField(field); return true; } // cell data must be scattered to the cells created per input cell - if (fieldMeta.IsCellField()) + if (field.IsFieldCell()) { - vtkm::cont::ArrayHandle output = this->Worklet.ProcessCellField(input); - - result.AddField(fieldMeta.AsField(output)); - return true; + vtkm::cont::ArrayHandle permutation = + this->Worklet.GetOutCellScatter().GetOutputToInputMap(); + return vtkm::filter::MapFieldPermutation(field, permutation, result); } 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..43c3848cb 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,24 @@ 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 (field.IsFieldPoint()) + { + return vtkm::filter::MapFieldPermutation( + field, this->Worklet.GetOutputPointSourceIndex(), result); + } - if (fieldMeta.IsPointField()) - fieldArray = this->Worklet.ProcessPointField(input); - else if (fieldMeta.IsCellField()) - fieldArray = this->Worklet.ProcessCellField(input); - else - return false; + if (field.IsFieldCell()) + { + return vtkm::filter::MapFieldPermutation( + field, this->Worklet.GetOutputCellSourceIndex(), result); + } - //use the same meta data as the input so we get the same field name, etc. - result.AddField(fieldMeta.AsField(fieldArray)); - return true; + return false; } } } // 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..ff1da429c 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,22 @@ 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); - } - else if (fieldMeta.IsCellField()) - { - fieldArray = this->Worklet.ProcessCellField(input); - } - else - { - return false; + return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetPointIdMap(), result); } - //use the same meta data as the input so we get the same field name, etc. - result.AddField(fieldMeta.AsField(fieldArray)); + if (field.IsFieldCell()) + { + return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetCellIdMap(), result); + } - return true; + return false; } } } 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/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/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 GetValidCellIds() const { return this->ValidCellIds; } + private: vtkm::cont::ArrayHandle ValidCellIds; }; 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/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/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 } From f8fd0ce31616a807cc593bd1e9a8d6930d23567c Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Thu, 6 Feb 2020 20:41:10 -0600 Subject: [PATCH 7/8] Silence warning about cast losing precision When using math operators on small integers, the numbers are promoted to 32-bit ints. If that is set back to the same type, then some compilers give a warning. This is annoying and pointless when dealing with templated types, but we have to deal with it. --- vtkm/filter/testing/UnitTestMapFieldMergeAverage.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vtkm/filter/testing/UnitTestMapFieldMergeAverage.cxx b/vtkm/filter/testing/UnitTestMapFieldMergeAverage.cxx index b034f107a..eac7f8ba2 100644 --- a/vtkm/filter/testing/UnitTestMapFieldMergeAverage.cxx +++ b/vtkm/filter/testing/UnitTestMapFieldMergeAverage.cxx @@ -59,8 +59,8 @@ vtkm::cont::ArrayHandle MakeExpectedOutput(const vtkm::cont::ArrayHandle(sum + inputPortal.Get(fullI)); + num = static_cast(num + ComponentType(1)); } outputPortal.Set(reducedI, sum / T(num)); } From 5498ecd35b63e5afba3505cb4cf53dd575041ba5 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Wed, 19 Feb 2020 10:34:24 -0700 Subject: [PATCH 8/8] Properly handle global (whole mesh) fields in data set filters Generally, fields that have a WHOLE_MESH association might be valid even if the structure of the mesh changes. Thus, it makes sense for filters to pass this data pretty much all the time. Also cleaned up some code and comments to make the relationship between `MapFieldOntoOutput` and `DoMapField` more clear. --- vtkm/cont/Field.h | 1 + vtkm/filter/ClipWithField.cxx | 25 ------------------------ vtkm/filter/ClipWithField.h | 22 ++++++++++++++++----- vtkm/filter/ClipWithImplicitFunction.cxx | 24 ----------------------- vtkm/filter/ClipWithImplicitFunction.h | 21 +++++++++++++++----- vtkm/filter/Contour.cxx | 25 ------------------------ vtkm/filter/Contour.h | 22 ++++++++++++++++----- vtkm/filter/ExternalFaces.cxx | 11 +++++++++-- vtkm/filter/ExtractGeometry.cxx | 5 +++++ vtkm/filter/ExtractPoints.hxx | 13 +++++++++--- vtkm/filter/ExtractStructured.cxx | 14 +++++++++---- vtkm/filter/GhostCellRemove.hxx | 5 +++++ vtkm/filter/Lagrangian.hxx | 14 ++++++++++--- vtkm/filter/LagrangianStructures.hxx | 14 ++++++++++--- vtkm/filter/Mask.hxx | 2 +- vtkm/filter/MaskPoints.hxx | 13 +++++++++--- vtkm/filter/Probe.hxx | 19 ++++++++++++------ vtkm/filter/SplitSharpEdges.hxx | 2 +- vtkm/filter/Tetrahedralize.hxx | 18 +++++++++++------ vtkm/filter/Threshold.cxx | 11 ++++++----- vtkm/filter/ThresholdPoints.hxx | 13 +++++++++--- vtkm/filter/Triangulate.hxx | 18 +++++++++++------ vtkm/filter/Tube.hxx | 14 +++++++++---- vtkm/filter/VertexClustering.hxx | 14 +++++++++---- 24 files changed, 197 insertions(+), 143 deletions(-) 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/filter/ClipWithField.cxx b/vtkm/filter/ClipWithField.cxx index eee6e4d2b..017fe3259 100644 --- a/vtkm/filter/ClipWithField.cxx +++ b/vtkm/filter/ClipWithField.cxx @@ -11,35 +11,10 @@ #include -#include - namespace vtkm { namespace filter { - -VTKM_FILTER_EXPORT bool ClipWithField::MapFieldOntoOutput(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field) -{ - if (field.IsFieldPoint()) - { - // Handled by DoMapField, which the superclass will call. - // Actually already done by other version of MapFieldOntoOutput. (Stupid policies.) - //return this->FilterDataSetWithField::MapFieldOntoOutput(result, field, policy); - VTKM_ASSERT(false && "Should not be here"); - return false; - } - else if (field.IsFieldCell()) - { - vtkm::cont::ArrayHandle permutation = this->Worklet.GetCellMapOutputToInput(); - return vtkm::filter::MapFieldPermutation(field, permutation, result); - } - else - { - return false; - } -} - //----------------------------------------------------------------------------- VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(ClipWithField); } diff --git a/vtkm/filter/ClipWithField.h b/vtkm/filter/ClipWithField.h index e8eba9e63..5477b2504 100644 --- a/vtkm/filter/ClipWithField.h +++ b/vtkm/filter/ClipWithField.h @@ -14,6 +14,8 @@ #include #include +#include + #include namespace vtkm @@ -46,9 +48,6 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, 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, @@ -56,12 +55,25 @@ public: { if (field.IsFieldPoint()) { - // DIE, POLICIES, DIE! + // 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 this->MapFieldOntoOutput(result, field); + return false; } } diff --git a/vtkm/filter/ClipWithImplicitFunction.cxx b/vtkm/filter/ClipWithImplicitFunction.cxx index be9603a1e..a5c4aa2a2 100644 --- a/vtkm/filter/ClipWithImplicitFunction.cxx +++ b/vtkm/filter/ClipWithImplicitFunction.cxx @@ -11,34 +11,10 @@ #define vtkm_filter_ClipWithImplicitFunction_cxx #include -#include - namespace vtkm { namespace filter { - -VTKM_FILTER_EXPORT bool ClipWithImplicitFunction::MapFieldOntoOutput(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field) -{ - if (field.IsFieldPoint()) - { - // Handled by DoMapField, which the superclass will call. - // Actually already done by other version of MapFieldOntoOutput. (Stupid policies.) - //return this->FilterDataSet::MapFieldOntoOutput(result, field, policy); - VTKM_ASSERT(false && "Should not be here"); - return false; - } - else if (field.IsFieldCell()) - { - vtkm::cont::ArrayHandle permutation = this->Worklet.GetCellMapOutputToInput(); - return vtkm::filter::MapFieldPermutation(field, permutation, result); - } - else - { - return false; - } -} //----------------------------------------------------------------------------- VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(ClipWithImplicitFunction); } diff --git a/vtkm/filter/ClipWithImplicitFunction.h b/vtkm/filter/ClipWithImplicitFunction.h index 75300b985..087c6e159 100644 --- a/vtkm/filter/ClipWithImplicitFunction.h +++ b/vtkm/filter/ClipWithImplicitFunction.h @@ -14,6 +14,7 @@ #include #include +#include #include namespace vtkm @@ -43,9 +44,6 @@ public: vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, 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, @@ -53,13 +51,26 @@ public: { if (field.IsFieldPoint()) { - // DIE, POLICIES, DIE! + // 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 this->MapFieldOntoOutput(result, field); + return false; } } diff --git a/vtkm/filter/Contour.cxx b/vtkm/filter/Contour.cxx index cb2293694..c52ca1a15 100644 --- a/vtkm/filter/Contour.cxx +++ b/vtkm/filter/Contour.cxx @@ -10,8 +10,6 @@ #define vtkm_filter_Contour_cxx #include -#include - namespace vtkm { namespace filter @@ -69,28 +67,5 @@ VTKM_FILTER_EXPORT vtkm::Float64 Contour::GetIsoValue(vtkm::Id index) const { return this->IsoValues[static_cast(index)]; } - -//----------------------------------------------------------------------------- -VTKM_FILTER_EXPORT bool Contour::MapFieldOntoOutput(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field) -{ - if (field.IsFieldPoint()) - { - // Handled by DoMapField, which the superclass will call. - // Actually already done by other version of MapFieldOntoOutput. (Stupid policies.) - //return this->FilterDataSetWithField::MapFieldOntoOutput(result, field, policy); - VTKM_ASSERT(false && "Should not be here"); - return false; - } - else if (field.IsFieldCell()) - { - vtkm::cont::ArrayHandle permutation = this->Worklet.GetCellIdMap(); - return vtkm::filter::MapFieldPermutation(field, permutation, result); - } - else - { - return false; - } -} } } diff --git a/vtkm/filter/Contour.h b/vtkm/filter/Contour.h index 917f8ea40..5ea89fc9d 100644 --- a/vtkm/filter/Contour.h +++ b/vtkm/filter/Contour.h @@ -14,6 +14,8 @@ #include #include +#include + #include namespace vtkm @@ -111,9 +113,6 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, 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, @@ -121,12 +120,25 @@ public: { if (field.IsFieldPoint()) { - // DIE, POLICIES, DIE! + // 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 this->MapFieldOntoOutput(result, field); + return false; } } diff --git a/vtkm/filter/ExternalFaces.cxx b/vtkm/filter/ExternalFaces.cxx index 2edb74a7b..9a61b92f4 100644 --- a/vtkm/filter/ExternalFaces.cxx +++ b/vtkm/filter/ExternalFaces.cxx @@ -82,8 +82,15 @@ bool ExternalFaces::MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm:: { return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetCellIdMap(), result); } - - return false; + else if (field.IsFieldGlobal()) + { + result.AddField(field); + return true; + } + else + { + return false; + } } //----------------------------------------------------------------------------- diff --git a/vtkm/filter/ExtractGeometry.cxx b/vtkm/filter/ExtractGeometry.cxx index 9901d1cd8..b54bc7152 100644 --- a/vtkm/filter/ExtractGeometry.cxx +++ b/vtkm/filter/ExtractGeometry.cxx @@ -39,6 +39,11 @@ VTKM_FILTER_EXPORT bool ExtractGeometry::MapFieldOntoOutput(vtkm::cont::DataSet& 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; diff --git a/vtkm/filter/ExtractPoints.hxx b/vtkm/filter/ExtractPoints.hxx index b657da9a9..1d3f4b0a4 100644 --- a/vtkm/filter/ExtractPoints.hxx +++ b/vtkm/filter/ExtractPoints.hxx @@ -84,9 +84,16 @@ inline VTKM_CONT bool ExtractPoints::MapFieldOntoOutput( 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 4fd57c6d4..9aee477b4 100644 --- a/vtkm/filter/ExtractStructured.cxx +++ b/vtkm/filter/ExtractStructured.cxx @@ -36,13 +36,19 @@ bool ExtractStructured::MapFieldOntoOutput(vtkm::cont::DataSet& result, { return vtkm::filter::MapFieldPermutation(field, this->PointFieldMap, result); } - - if (field.IsFieldCell()) + else if (field.IsFieldCell()) { return vtkm::filter::MapFieldPermutation(field, this->CellFieldMap, result); } - - return false; + else if (field.IsFieldGlobal()) + { + result.AddField(field); + return true; + } + else + { + return false; + } } //----------------------------------------------------------------------------- diff --git a/vtkm/filter/GhostCellRemove.hxx b/vtkm/filter/GhostCellRemove.hxx index 923664a43..c64e0bd1d 100644 --- a/vtkm/filter/GhostCellRemove.hxx +++ b/vtkm/filter/GhostCellRemove.hxx @@ -376,6 +376,11 @@ VTKM_CONT bool GhostCellRemove::MapFieldOntoOutput(vtkm::cont::DataSet& result, { return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetValidCellIds(), result); } + else if (field.IsFieldGlobal()) + { + result.AddField(field); + return true; + } else { return false; diff --git a/vtkm/filter/Lagrangian.hxx b/vtkm/filter/Lagrangian.hxx index 3050e649a..e6bfeb489 100644 --- a/vtkm/filter/Lagrangian.hxx +++ b/vtkm/filter/Lagrangian.hxx @@ -327,11 +327,19 @@ inline VTKM_CONT vtkm::cont::DataSet Lagrangian::DoExecute( //--------------------------------------------------------------------------- template -inline VTKM_CONT bool Lagrangian::MapFieldOntoOutput(vtkm::cont::DataSet&, - const vtkm::cont::Field&, +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.hxx b/vtkm/filter/LagrangianStructures.hxx index 0d18a41ec..22deda787 100644 --- a/vtkm/filter/LagrangianStructures.hxx +++ b/vtkm/filter/LagrangianStructures.hxx @@ -157,11 +157,19 @@ inline VTKM_CONT vtkm::cont::DataSet LagrangianStructures::DoExecute( //----------------------------------------------------------------------------- template inline VTKM_CONT bool LagrangianStructures::MapFieldOntoOutput( - vtkm::cont::DataSet&, - const vtkm::cont::Field&, + 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/Mask.hxx b/vtkm/filter/Mask.hxx index ee97c5e98..e5b240e40 100644 --- a/vtkm/filter/Mask.hxx +++ b/vtkm/filter/Mask.hxx @@ -73,7 +73,7 @@ inline VTKM_CONT bool Mask::MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field, vtkm::filter::PolicyBase) { - if (field.IsFieldPoint()) + if (field.IsFieldPoint() || field.IsFieldGlobal()) { result.AddField(field); // pass through return true; diff --git a/vtkm/filter/MaskPoints.hxx b/vtkm/filter/MaskPoints.hxx index 0dd877e5c..2b15775eb 100644 --- a/vtkm/filter/MaskPoints.hxx +++ b/vtkm/filter/MaskPoints.hxx @@ -76,9 +76,16 @@ inline VTKM_CONT bool MaskPoints::MapFieldOntoOutput(vtkm::cont::DataSet& result 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/Probe.hxx b/vtkm/filter/Probe.hxx index 96d343b35..e7266f3e5 100644 --- a/vtkm/filter/Probe.hxx +++ b/vtkm/filter/Probe.hxx @@ -54,17 +54,24 @@ VTKM_CONT inline bool Probe::MapFieldOntoOutput(vtkm::cont::DataSet& result, { if (field.IsFieldPoint()) { - // This is a special interpolation that is handled by DoMapField. The superclass' - // MapFieldOntoOutput will handle this. + // 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); } - - if (field.IsFieldCell()) + else if (field.IsFieldCell()) { return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetCellIds(), result); } - - return false; + else if (field.IsFieldGlobal()) + { + result.AddField(field); + return true; + } + else + { + return false; + } } template diff --git a/vtkm/filter/SplitSharpEdges.hxx b/vtkm/filter/SplitSharpEdges.hxx index 9da6c989f..7f28b0b55 100644 --- a/vtkm/filter/SplitSharpEdges.hxx +++ b/vtkm/filter/SplitSharpEdges.hxx @@ -68,7 +68,7 @@ inline VTKM_CONT bool SplitSharpEdges::MapFieldOntoOutput(vtkm::cont::DataSet& r { return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetNewPointsIdArray(), result); } - else if (field.IsFieldCell()) + else if (field.IsFieldCell() || field.IsFieldGlobal()) { result.AddField(field); // pass through return true; diff --git a/vtkm/filter/Tetrahedralize.hxx b/vtkm/filter/Tetrahedralize.hxx index cbe0c233f..64398c658 100644 --- a/vtkm/filter/Tetrahedralize.hxx +++ b/vtkm/filter/Tetrahedralize.hxx @@ -68,22 +68,28 @@ inline VTKM_CONT bool Tetrahedralize::MapFieldOntoOutput(vtkm::cont::DataSet& re const vtkm::cont::Field& field, vtkm::filter::PolicyBase) { - // point data is copied as is because it was not collapsed if (field.IsFieldPoint()) { + // 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 (field.IsFieldCell()) + else if (field.IsFieldCell()) { + // 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); } - - return false; + else if (field.IsFieldGlobal()) + { + result.AddField(field); + return true; + } + else + { + return false; + } } } } diff --git a/vtkm/filter/Threshold.cxx b/vtkm/filter/Threshold.cxx index 19c0f3448..595bf70d7 100644 --- a/vtkm/filter/Threshold.cxx +++ b/vtkm/filter/Threshold.cxx @@ -20,19 +20,20 @@ namespace filter VTKM_FILTER_EXPORT bool Threshold::MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field) { - if (field.IsFieldPoint()) + if (field.IsFieldPoint() || field.IsFieldGlobal()) { //we copy the input handle to the result dataset, reusing the metadata result.AddField(field); return true; } - - if (field.IsFieldCell()) + else if (field.IsFieldCell()) { return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetValidCellIds(), result); } - - return false; + else + { + return false; + } } //----------------------------------------------------------------------------- diff --git a/vtkm/filter/ThresholdPoints.hxx b/vtkm/filter/ThresholdPoints.hxx index 4ebddbdde..97f2f08c3 100644 --- a/vtkm/filter/ThresholdPoints.hxx +++ b/vtkm/filter/ThresholdPoints.hxx @@ -206,9 +206,16 @@ inline VTKM_CONT bool ThresholdPoints::MapFieldOntoOutput( 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.hxx b/vtkm/filter/Triangulate.hxx index f5e0a23fa..bd1ae667d 100644 --- a/vtkm/filter/Triangulate.hxx +++ b/vtkm/filter/Triangulate.hxx @@ -90,22 +90,28 @@ inline VTKM_CONT bool Triangulate::MapFieldOntoOutput(vtkm::cont::DataSet& resul const vtkm::cont::Field& field, vtkm::filter::PolicyBase) { - // point data is copied as is because it was not collapsed if (field.IsFieldPoint()) { + // 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 (field.IsFieldCell()) + else if (field.IsFieldCell()) { + // 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); } - - return false; + else if (field.IsFieldGlobal()) + { + result.AddField(field); + return true; + } + else + { + return false; + } } } } diff --git a/vtkm/filter/Tube.hxx b/vtkm/filter/Tube.hxx index 43c3848cb..3d94c038f 100644 --- a/vtkm/filter/Tube.hxx +++ b/vtkm/filter/Tube.hxx @@ -64,14 +64,20 @@ inline VTKM_CONT bool Tube::MapFieldOntoOutput(vtkm::cont::DataSet& result, return vtkm::filter::MapFieldPermutation( field, this->Worklet.GetOutputPointSourceIndex(), result); } - - if (field.IsFieldCell()) + else if (field.IsFieldCell()) { return vtkm::filter::MapFieldPermutation( field, this->Worklet.GetOutputCellSourceIndex(), result); } - - return false; + else if (field.IsFieldGlobal()) + { + result.AddField(field); + return true; + } + else + { + return false; + } } } } // namespace vtkm::filter diff --git a/vtkm/filter/VertexClustering.hxx b/vtkm/filter/VertexClustering.hxx index ff1da429c..f1fce0943 100644 --- a/vtkm/filter/VertexClustering.hxx +++ b/vtkm/filter/VertexClustering.hxx @@ -56,13 +56,19 @@ inline VTKM_CONT bool VertexClustering::MapFieldOntoOutput(vtkm::cont::DataSet& { return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetPointIdMap(), result); } - - if (field.IsFieldCell()) + else if (field.IsFieldCell()) { return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetCellIdMap(), result); } - - return false; + else if (field.IsFieldGlobal()) + { + result.AddField(field); + return true; + } + else + { + return false; + } } } }