//============================================================================ // 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 vtkm_m_worklet_Threshold_h #define vtkm_m_worklet_Threshold_h #include #include #include #include #include #include #include #include #include #include #include namespace vtkm { namespace worklet { class Threshold { public: enum class FieldType { Point, Cell }; template class ThresholdByPointField : public vtkm::worklet::WorkletVisitCellsWithPoints { 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; }; struct ThresholdCopy : public vtkm::worklet::WorkletMapField { using ControlSignature = void(FieldIn, FieldOut, WholeArrayIn); template VTKM_EXEC void operator()(vtkm::Id& index, ScalarType& output, const WholeFieldIn& inputField) const { output = inputField.Get(index); } }; 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; switch (fieldType) { case vtkm::cont::Field::Association::POINTS: { using ThresholdWorklet = ThresholdByPointField; vtkm::cont::ArrayHandle passFlags; ThresholdWorklet worklet(predicate); DispatcherMapTopology dispatcher(worklet); dispatcher.Invoke(cellSet, field, passFlags); vtkm::cont::Algorithm::CopyIf(vtkm::cont::ArrayHandleIndex(passFlags.GetNumberOfValues()), passFlags, this->ValidCellIds); break; } case vtkm::cont::Field::Association::CELL_SET: { vtkm::cont::Algorithm::CopyIf(vtkm::cont::ArrayHandleIndex(field.GetNumberOfValues()), field, this->ValidCellIds, predicate); break; } default: throw vtkm::cont::ErrorBadValue("Expecting point or cell field."); } return OutputType(this->ValidCellIds, cellSet); } 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 { // Copy output to an explicit grid so that other units can guess what this is. this->Output = vtkm::worklet::CellDeepCopy::Run( 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 { vtkm::cont::ArrayHandle result; DispatcherMapField dispatcher; dispatcher.Invoke(this->ValidCellIds, result, in); return result; } private: vtkm::cont::ArrayHandle ValidCellIds; }; } } // namespace vtkm::worklet #endif // vtkm_m_worklet_Threshold_h