//============================================================================ // 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. // // Copyright 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS). // Copyright 2015 UT-Battelle, LLC. // Copyright 2015 Los Alamos National Security. // // Under the terms of Contract DE-NA0003525 with NTESS, // the U.S. Government retains certain rights in this software. // // Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National // Laboratory (LANL), the U.S. Government retains certain rights in // this software. //============================================================================ #ifndef vtkm_m_worklet_Threshold_h #define vtkm_m_worklet_Threshold_h #include #include #include #include #include #include #include #include #include #include namespace vtkm { namespace worklet { class Threshold { public: enum class FieldType { Point, Cell }; struct BoolType : vtkm::ListTagBase { }; template class ThresholdByPointField : public vtkm::worklet::WorkletMapPointToCell { public: using ControlSignature = void(CellSetIn cellset, FieldInPoint scalars, FieldOutCell passFlags); using ExecutionSignature = _3(_2, PointCount); VTKM_CONT ThresholdByPointField() : Predicate() { } VTKM_CONT explicit ThresholdByPointField(const UnaryPredicate& predicate) : Predicate(predicate) { } template VTKM_EXEC bool operator()(const ScalarsVecType& scalars, vtkm::Id count) const { bool pass = false; for (vtkm::IdComponent i = 0; i < count; ++i) { pass |= this->Predicate(scalars[i]); } return pass; } private: UnaryPredicate Predicate; }; template class ThresholdByCellField : public vtkm::worklet::WorkletMapPointToCell { public: using ControlSignature = void(CellSetIn cellset, FieldInTo scalars, FieldOut passFlags); using ExecutionSignature = _3(_2); VTKM_CONT ThresholdByCellField() : Predicate() { } VTKM_CONT explicit ThresholdByCellField(const UnaryPredicate& predicate) : Predicate(predicate) { } template VTKM_EXEC bool operator()(const ScalarType& scalar) const { return this->Predicate(scalar); } private: UnaryPredicate Predicate; }; template vtkm::cont::CellSetPermutation Run( const CellSetType& cellSet, const vtkm::cont::ArrayHandle& field, const vtkm::cont::Field::Association fieldType, const UnaryPredicate& predicate) { using OutputType = vtkm::cont::CellSetPermutation; vtkm::cont::ArrayHandle passFlags; switch (fieldType) { case vtkm::cont::Field::Association::POINTS: { using ThresholdWorklet = ThresholdByPointField; ThresholdWorklet worklet(predicate); DispatcherMapTopology dispatcher(worklet); dispatcher.Invoke(cellSet, field, passFlags); break; } case vtkm::cont::Field::Association::CELL_SET: { using ThresholdWorklet = ThresholdByCellField; ThresholdWorklet worklet(predicate); DispatcherMapTopology dispatcher(worklet); dispatcher.Invoke(cellSet, field, passFlags); break; } default: throw vtkm::cont::ErrorBadValue("Expecting point or cell field."); } vtkm::cont::Algorithm::CopyIf( vtkm::cont::ArrayHandleIndex(passFlags.GetNumberOfValues()), passFlags, this->ValidCellIds); return OutputType(this->ValidCellIds, cellSet, cellSet.GetName()); } template struct CallWorklet { vtkm::cont::DynamicCellSet& Output; vtkm::worklet::Threshold& Worklet; const FieldArrayType& Field; const vtkm::cont::Field::Association FieldType; const UnaryPredicate& Predicate; CallWorklet(vtkm::cont::DynamicCellSet& output, vtkm::worklet::Threshold& worklet, const FieldArrayType& field, const vtkm::cont::Field::Association fieldType, const UnaryPredicate& predicate) : Output(output) , Worklet(worklet) , Field(field) , FieldType(fieldType) , Predicate(predicate) { } template void operator()(const CellSetType& cellSet) const { this->Output = this->Worklet.Run(cellSet, this->Field, this->FieldType, this->Predicate); } }; template vtkm::cont::DynamicCellSet Run(const vtkm::cont::DynamicCellSetBase& cellSet, const vtkm::cont::ArrayHandle& field, const vtkm::cont::Field::Association fieldType, const UnaryPredicate& predicate) { using Worker = CallWorklet, UnaryPredicate>; vtkm::cont::DynamicCellSet output; Worker worker(output, *this, field, fieldType, predicate); cellSet.CastAndCall(worker); return output; } template vtkm::cont::ArrayHandle ProcessCellField( const vtkm::cont::ArrayHandle in) const { // Use a temporary permutation array to simplify the mapping: auto tmp = vtkm::cont::make_ArrayHandlePermutation(this->ValidCellIds, in); // Copy into an array with default storage: vtkm::cont::ArrayHandle result; vtkm::cont::ArrayCopy(tmp, result); return result; } private: vtkm::cont::ArrayHandle ValidCellIds; }; } } // namespace vtkm::worklet #endif // vtkm_m_worklet_Threshold_h