//============================================================================ // 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 Sandia Corporation. // Copyright 2015 UT-Battelle, LLC. // Copyright 2015 Los Alamos National Security. // // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // 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 namespace vtkm { namespace worklet { class Threshold { public: struct BoolType : vtkm::ListTagBase { }; template class ThresholdByPointField : public vtkm::worklet::WorkletMapPointToCell { public: typedef void ControlSignature(CellSetIn cellset, FieldInPoint scalars, FieldOutCell passFlags); typedef _3 ExecutionSignature(_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: typedef void ControlSignature(CellSetIn cellset, FieldInTo scalars, FieldOut passFlags); typedef _3 ExecutionSignature(_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< CellSetType > Run(const CellSetType &cellSet, const vtkm::cont::Field &field, const UnaryPredicate &predicate, DeviceAdapter device) { (void) device; typedef vtkm::cont::CellSetPermutation< CellSetType > OutputType; vtkm::cont::ArrayHandle passFlags; switch(field.GetAssociation()) { case vtkm::cont::Field::ASSOC_POINTS: { typedef ThresholdByPointField ThresholdWorklet; ThresholdWorklet worklet(predicate); DispatcherMapTopology dispatcher(worklet); dispatcher.Invoke(cellSet, field, passFlags); break; } case vtkm::cont::Field::ASSOC_CELL_SET: { typedef ThresholdByCellField ThresholdWorklet; ThresholdWorklet worklet(predicate); DispatcherMapTopology dispatcher(worklet); dispatcher.Invoke(cellSet, field, passFlags); break; } default: throw vtkm::cont::ErrorBadValue("Expecting point or cell field."); } vtkm::cont::ArrayHandleCounting indices = vtkm::cont::make_ArrayHandleCounting(vtkm::Id(0), vtkm::Id(1), passFlags.GetNumberOfValues()); vtkm::cont::DeviceAdapterAlgorithm ::CopyIf(indices, passFlags, this->ValidCellIds); return OutputType(this->ValidCellIds, cellSet, cellSet.GetName()); } class PermuteCellData { public: PermuteCellData(const vtkm::cont::ArrayHandle validCellIds, vtkm::cont::DynamicArrayHandle &data) : ValidCellIds(validCellIds), Data(&data) { } template void operator()(const ArrayHandleType &input) const { *(this->Data) = vtkm::cont::DynamicArrayHandle( vtkm::cont::make_ArrayHandlePermutation(this->ValidCellIds, input)); } private: vtkm::cont::ArrayHandle ValidCellIds; vtkm::cont::DynamicArrayHandle *Data; }; vtkm::cont::Field ProcessCellField(const vtkm::cont::Field field) const { if (field.GetAssociation() != vtkm::cont::Field::ASSOC_CELL_SET) { throw vtkm::cont::ErrorBadValue("Expecting cell field."); } vtkm::cont::DynamicArrayHandle data; CastAndCall(field, PermuteCellData(this->ValidCellIds, data)); return vtkm::cont::Field(field.GetName(), field.GetAssociation(), field.GetAssocCellSet(), data); } private: vtkm::cont::ArrayHandle ValidCellIds; }; } } // namespace vtkm::worklet #endif // vtkm_m_worklet_Threshold_h