vtk-m/vtkm/filter/ThresholdPoints.hxx

244 lines
6.8 KiB
C++
Raw Normal View History

2017-03-07 21:03:22 +00:00
//============================================================================
// 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 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 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.
//============================================================================
namespace
{
2017-03-07 21:03:22 +00:00
// Needed to CompactPoints
template <typename BasePolicy>
struct CellSetSingleTypePolicy : public BasePolicy
{
using AllCellSetList = vtkm::cont::CellSetListTagUnstructured;
};
2017-03-07 21:03:22 +00:00
template <typename DerivedPolicy>
2017-05-18 14:29:41 +00:00
inline vtkm::filter::PolicyBase<CellSetSingleTypePolicy<DerivedPolicy>> GetCellSetSingleTypePolicy(
const vtkm::filter::PolicyBase<DerivedPolicy>&)
2017-03-07 21:03:22 +00:00
{
return vtkm::filter::PolicyBase<CellSetSingleTypePolicy<DerivedPolicy>>();
}
2017-03-07 21:03:22 +00:00
// Predicate for values less than minimum
class ValuesBelow
{
public:
VTKM_CONT
2017-05-18 14:29:41 +00:00
ValuesBelow(const vtkm::Float64& value)
: Value(value)
{
}
2017-03-07 21:03:22 +00:00
2017-05-18 14:29:41 +00:00
template <typename ScalarType>
VTKM_EXEC bool operator()(const ScalarType& value) const
2017-03-07 21:03:22 +00:00
{
return value <= static_cast<ScalarType>(this->Value);
2017-03-07 21:03:22 +00:00
}
private:
vtkm::Float64 Value;
2017-03-07 21:03:22 +00:00
};
// Predicate for values greater than maximum
class ValuesAbove
{
public:
VTKM_CONT
2017-05-18 14:29:41 +00:00
ValuesAbove(const vtkm::Float64& value)
: Value(value)
{
}
2017-03-07 21:03:22 +00:00
2017-05-18 14:29:41 +00:00
template <typename ScalarType>
VTKM_EXEC bool operator()(const ScalarType& value) const
2017-03-07 21:03:22 +00:00
{
return value >= static_cast<ScalarType>(this->Value);
2017-03-07 21:03:22 +00:00
}
private:
vtkm::Float64 Value;
2017-03-07 21:03:22 +00:00
};
// Predicate for values between minimum and maximum
class ValuesBetween
{
public:
VTKM_CONT
2017-05-18 14:29:41 +00:00
ValuesBetween(const vtkm::Float64& lower, const vtkm::Float64& upper)
: Lower(lower)
, Upper(upper)
{
}
2017-03-07 21:03:22 +00:00
2017-05-18 14:29:41 +00:00
template <typename ScalarType>
VTKM_EXEC bool operator()(const ScalarType& value) const
2017-03-07 21:03:22 +00:00
{
return value >= static_cast<ScalarType>(this->Lower) &&
2017-05-18 14:29:41 +00:00
value <= static_cast<ScalarType>(this->Upper);
2017-03-07 21:03:22 +00:00
}
private:
vtkm::Float64 Lower;
vtkm::Float64 Upper;
};
}
2017-05-18 14:29:41 +00:00
namespace vtkm
{
namespace filter
{
2017-03-07 21:03:22 +00:00
2017-05-18 14:29:41 +00:00
const int THRESHOLD_BELOW = 0;
const int THRESHOLD_ABOVE = 1;
2017-03-08 23:04:12 +00:00
const int THRESHOLD_BETWEEN = 2;
2017-03-07 21:03:22 +00:00
//-----------------------------------------------------------------------------
2017-05-18 14:29:41 +00:00
inline VTKM_CONT ThresholdPoints::ThresholdPoints()
: vtkm::filter::FilterDataSetWithField<ThresholdPoints>()
, LowerValue(0)
, UpperValue(0)
, ThresholdType(THRESHOLD_BETWEEN)
, CompactPoints(false)
2017-03-07 21:03:22 +00:00
{
}
//-----------------------------------------------------------------------------
2017-05-18 14:29:41 +00:00
inline VTKM_CONT void ThresholdPoints::SetThresholdBelow(const vtkm::Float64 value)
{
this->SetLowerThreshold(value);
this->SetUpperThreshold(value);
2017-03-08 23:04:12 +00:00
this->ThresholdType = THRESHOLD_BELOW;
}
2017-05-18 14:29:41 +00:00
inline VTKM_CONT void ThresholdPoints::SetThresholdAbove(const vtkm::Float64 value)
{
this->SetLowerThreshold(value);
this->SetUpperThreshold(value);
2017-03-08 23:04:12 +00:00
this->ThresholdType = THRESHOLD_ABOVE;
}
2017-05-18 14:29:41 +00:00
inline VTKM_CONT void ThresholdPoints::SetThresholdBetween(const vtkm::Float64 value1,
const vtkm::Float64 value2)
{
this->SetLowerThreshold(value1);
this->SetUpperThreshold(value2);
2017-03-08 23:04:12 +00:00
this->ThresholdType = THRESHOLD_BETWEEN;
}
2017-03-07 21:03:22 +00:00
//-----------------------------------------------------------------------------
2017-05-18 14:29:41 +00:00
template <typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
inline VTKM_CONT vtkm::filter::Result ThresholdPoints::DoExecute(
const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
2017-05-18 14:29:41 +00:00
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& device)
2017-03-07 21:03:22 +00:00
{
// extract the input cell set
2017-05-18 14:29:41 +00:00
const vtkm::cont::DynamicCellSet& cells = input.GetCellSet(this->GetActiveCellSetIndex());
2017-03-07 21:03:22 +00:00
// field to threshold on must be a point field
2017-03-07 21:03:22 +00:00
if (fieldMeta.IsPointField() == false)
{
//todo: we need to mark this as a failure of input, not a failure of the algorithm
return vtkm::filter::Result();
2017-03-07 21:03:22 +00:00
}
// run the worklet on the cell set and input field
2017-03-07 21:03:22 +00:00
vtkm::cont::CellSetSingleType<> outCellSet;
vtkm::worklet::ThresholdPoints worklet;
2017-03-08 23:04:12 +00:00
switch (this->ThresholdType)
{
2017-05-18 14:29:41 +00:00
case THRESHOLD_BELOW:
{
outCellSet = worklet.Run(vtkm::filter::ApplyPolicy(cells, policy),
field,
ValuesBelow(this->GetLowerThreshold()),
device);
2017-05-18 14:29:41 +00:00
break;
}
case THRESHOLD_ABOVE:
2017-03-08 23:04:12 +00:00
{
outCellSet = worklet.Run(vtkm::filter::ApplyPolicy(cells, policy),
field,
ValuesAbove(this->GetUpperThreshold()),
device);
2017-05-18 14:29:41 +00:00
break;
}
case THRESHOLD_BETWEEN:
default:
{
outCellSet = worklet.Run(vtkm::filter::ApplyPolicy(cells, policy),
field,
ValuesBetween(this->GetLowerThreshold(), this->GetUpperThreshold()),
device);
2017-05-18 14:29:41 +00:00
break;
2017-03-08 23:04:12 +00:00
}
}
// create the output dataset
vtkm::cont::DataSet output;
output.AddCellSet(outCellSet);
2017-05-18 14:29:41 +00:00
output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex()));
2017-03-07 21:03:22 +00:00
// compact the unused points in the output dataset
if (this->CompactPoints)
{
this->Compactor.SetCompactPointFields(true);
vtkm::filter::Result result;
2017-05-18 14:29:41 +00:00
result = this->Compactor.DoExecute(output, GetCellSetSingleTypePolicy(policy), DeviceAdapter());
return result;
}
else
{
return vtkm::filter::Result(output);
}
2017-03-07 21:03:22 +00:00
}
//-----------------------------------------------------------------------------
2017-05-18 14:29:41 +00:00
template <typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
inline VTKM_CONT bool ThresholdPoints::DoMapField(
vtkm::filter::Result& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
2017-05-18 14:29:41 +00:00
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter&)
2017-03-07 21:03:22 +00:00
{
// point data is copied as is because it was not collapsed
2017-05-18 14:29:41 +00:00
if (fieldMeta.IsPointField())
2017-03-07 21:03:22 +00:00
{
if (this->CompactPoints)
{
return this->Compactor.DoMapField(result, input, fieldMeta, policy, DeviceAdapter());
}
else
{
result.GetDataSet().AddField(fieldMeta.AsField(input));
return true;
}
2017-03-07 21:03:22 +00:00
}
2017-05-18 14:29:41 +00:00
2017-03-07 21:03:22 +00:00
// cell data does not apply
return false;
}
}
}