//============================================================================ // 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_ThresholdPoints_hxx #define vtk_m_filter_ThresholdPoints_hxx #include namespace { // Predicate for values less than minimum class ValuesBelow { public: VTKM_CONT ValuesBelow(const vtkm::Float64& value) : Value(value) { } template VTKM_EXEC bool operator()(const ScalarType& value) const { return value <= static_cast(this->Value); } private: vtkm::Float64 Value; }; // Predicate for values greater than maximum class ValuesAbove { public: VTKM_CONT ValuesAbove(const vtkm::Float64& value) : Value(value) { } template VTKM_EXEC bool operator()(const ScalarType& value) const { return value >= static_cast(this->Value); } private: vtkm::Float64 Value; }; // Predicate for values between minimum and maximum class ValuesBetween { public: VTKM_CONT ValuesBetween(const vtkm::Float64& lower, const vtkm::Float64& upper) : Lower(lower) , Upper(upper) { } template VTKM_EXEC bool operator()(const ScalarType& value) const { return value >= static_cast(this->Lower) && value <= static_cast(this->Upper); } private: vtkm::Float64 Lower; vtkm::Float64 Upper; }; } namespace vtkm { namespace filter { const int THRESHOLD_BELOW = 0; const int THRESHOLD_ABOVE = 1; const int THRESHOLD_BETWEEN = 2; //----------------------------------------------------------------------------- inline VTKM_CONT ThresholdPoints::ThresholdPoints() : vtkm::filter::FilterDataSetWithField() , LowerValue(0) , UpperValue(0) , ThresholdType(THRESHOLD_BETWEEN) , CompactPoints(false) { } //----------------------------------------------------------------------------- inline VTKM_CONT void ThresholdPoints::SetThresholdBelow(const vtkm::Float64 value) { this->SetLowerThreshold(value); this->SetUpperThreshold(value); this->ThresholdType = THRESHOLD_BELOW; } inline VTKM_CONT void ThresholdPoints::SetThresholdAbove(const vtkm::Float64 value) { this->SetLowerThreshold(value); this->SetUpperThreshold(value); this->ThresholdType = THRESHOLD_ABOVE; } inline VTKM_CONT void ThresholdPoints::SetThresholdBetween(const vtkm::Float64 value1, const vtkm::Float64 value2) { this->SetLowerThreshold(value1); this->SetUpperThreshold(value2); this->ThresholdType = THRESHOLD_BETWEEN; } //----------------------------------------------------------------------------- template inline VTKM_CONT vtkm::cont::DataSet ThresholdPoints::DoExecute( const vtkm::cont::DataSet& input, const vtkm::cont::ArrayHandle& field, const vtkm::filter::FieldMetadata& fieldMeta, vtkm::filter::PolicyBase policy) { // extract the input cell set const vtkm::cont::DynamicCellSet& cells = input.GetCellSet(); // field to threshold on must be a point field if (fieldMeta.IsPointField() == false) { throw vtkm::cont::ErrorFilterExecution("Point field expected."); } // run the worklet on the cell set and input field vtkm::cont::CellSetSingleType<> outCellSet; vtkm::worklet::ThresholdPoints worklet; switch (this->ThresholdType) { case THRESHOLD_BELOW: { outCellSet = worklet.Run(vtkm::filter::ApplyPolicyCellSet(cells, policy, *this), field, ValuesBelow(this->GetLowerThreshold())); break; } case THRESHOLD_ABOVE: { outCellSet = worklet.Run(vtkm::filter::ApplyPolicyCellSet(cells, policy, *this), field, ValuesAbove(this->GetUpperThreshold())); break; } case THRESHOLD_BETWEEN: default: { outCellSet = worklet.Run(vtkm::filter::ApplyPolicyCellSet(cells, policy, *this), field, ValuesBetween(this->GetLowerThreshold(), this->GetUpperThreshold())); break; } } // create the output dataset vtkm::cont::DataSet output; output.SetCellSet(outCellSet); output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex())); // compact the unused points in the output dataset if (this->CompactPoints) { this->Compactor.SetCompactPointFields(true); this->Compactor.SetMergePoints(true); return this->Compactor.Execute(output); } else { return output; } } //----------------------------------------------------------------------------- template inline VTKM_CONT bool ThresholdPoints::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 (field.IsFieldPoint()) { if (this->CompactPoints) { return this->Compactor.MapFieldOntoOutput(result, field, policy); } else { result.AddField(field); return true; } } else if (field.IsFieldGlobal()) { result.AddField(field); return true; } else { // cell data does not apply return false; } } } } #endif