vtk-m/vtkm/worklet/ExtractGeometry.h
Kenneth Moreland a6725b3acd Remove use of deprecated ImplicitFunctions with virtual methods
Unfortunately, this introduces a backward-incompatible change with the
filters that use ImplicitFunctions. Before, they would get an
ImplicitFunctionHandle. This class is deprecated, and there is no easy
way to get back the actual type of implicit function stored in it.
2021-02-22 06:40:02 -07:00

180 lines
6.3 KiB
C++

//============================================================================
// 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_ExtractGeometry_h
#define vtkm_m_worklet_ExtractGeometry_h
#include <vtkm/worklet/DispatcherMapTopology.h>
#include <vtkm/worklet/WorkletMapTopology.h>
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/CellSetPermutation.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/ImplicitFunction.h>
namespace vtkm
{
namespace worklet
{
class ExtractGeometry
{
public:
////////////////////////////////////////////////////////////////////////////////////
// Worklet to identify cells within volume of interest
class ExtractCellsByVOI : public vtkm::worklet::WorkletVisitCellsWithPoints
{
public:
using ControlSignature = void(CellSetIn cellset,
WholeArrayIn coordinates,
ExecObject implicitFunction,
FieldOutCell passFlags);
using ExecutionSignature = _4(PointCount, PointIndices, _2, _3);
ExtractCellsByVOI() = default;
VTKM_CONT
ExtractCellsByVOI(bool extractInside, bool extractBoundaryCells, bool extractOnlyBoundaryCells)
: ExtractInside(extractInside)
, ExtractBoundaryCells(extractBoundaryCells)
, ExtractOnlyBoundaryCells(extractOnlyBoundaryCells)
{
}
template <typename ConnectivityInVec, typename InVecFieldPortalType, typename ImplicitFunction>
VTKM_EXEC bool operator()(vtkm::Id numIndices,
const ConnectivityInVec& connectivityIn,
const InVecFieldPortalType& coordinates,
const ImplicitFunction& function) const
{
// Count points inside/outside volume of interest
vtkm::IdComponent inCnt = 0;
vtkm::IdComponent outCnt = 0;
vtkm::Id indx;
for (indx = 0; indx < numIndices; indx++)
{
vtkm::Id ptId = connectivityIn[static_cast<vtkm::IdComponent>(indx)];
vtkm::Vec<FloatDefault, 3> coordinate = coordinates.Get(ptId);
vtkm::FloatDefault value = function.Value(coordinate);
if (value <= 0)
inCnt++;
if (value >= 0)
outCnt++;
}
// Decide if cell is extracted
bool passFlag = false;
if (inCnt == numIndices && ExtractInside && !ExtractOnlyBoundaryCells)
{
passFlag = true;
}
else if (outCnt == numIndices && !ExtractInside && !ExtractOnlyBoundaryCells)
{
passFlag = true;
}
else if (inCnt > 0 && outCnt > 0 && (ExtractBoundaryCells || ExtractOnlyBoundaryCells))
{
passFlag = true;
}
return passFlag;
}
private:
bool ExtractInside;
bool ExtractBoundaryCells;
bool ExtractOnlyBoundaryCells;
};
class AddPermutationCellSet
{
vtkm::cont::DynamicCellSet* Output;
vtkm::cont::ArrayHandle<vtkm::Id>* ValidIds;
public:
AddPermutationCellSet(vtkm::cont::DynamicCellSet& cellOut,
vtkm::cont::ArrayHandle<vtkm::Id>& validIds)
: Output(&cellOut)
, ValidIds(&validIds)
{
}
template <typename CellSetType>
void operator()(const CellSetType& cellset) const
{
vtkm::cont::CellSetPermutation<CellSetType> permCellSet(*this->ValidIds, cellset);
*this->Output = permCellSet;
}
};
////////////////////////////////////////////////////////////////////////////////////
// Extract cells by ids permutes input data
template <typename CellSetType>
vtkm::cont::CellSetPermutation<CellSetType> Run(const CellSetType& cellSet,
const vtkm::cont::ArrayHandle<vtkm::Id>& cellIds)
{
using OutputType = vtkm::cont::CellSetPermutation<CellSetType>;
vtkm::cont::ArrayCopy(cellIds, this->ValidCellIds);
return OutputType(this->ValidCellIds, cellSet);
}
////////////////////////////////////////////////////////////////////////////////////
// Extract cells by implicit function permutes input data
template <typename CellSetType, typename ImplicitFunction>
vtkm::cont::CellSetPermutation<CellSetType> Run(const CellSetType& cellSet,
const vtkm::cont::CoordinateSystem& coordinates,
const ImplicitFunction& implicitFunction,
bool extractInside,
bool extractBoundaryCells,
bool extractOnlyBoundaryCells)
{
// Worklet output will be a boolean passFlag array
vtkm::cont::ArrayHandle<bool> passFlags;
ExtractCellsByVOI worklet(extractInside, extractBoundaryCells, extractOnlyBoundaryCells);
DispatcherMapTopology<ExtractCellsByVOI> dispatcher(worklet);
dispatcher.Invoke(cellSet, coordinates, implicitFunction, passFlags);
vtkm::cont::ArrayHandleCounting<vtkm::Id> indices =
vtkm::cont::make_ArrayHandleCounting(vtkm::Id(0), vtkm::Id(1), passFlags.GetNumberOfValues());
vtkm::cont::Algorithm::CopyIf(indices, passFlags, this->ValidCellIds);
// generate the cellset
return vtkm::cont::CellSetPermutation<CellSetType>(this->ValidCellIds, cellSet);
}
template <typename ValueType, typename StorageTagIn>
vtkm::cont::ArrayHandle<ValueType> ProcessCellField(
const vtkm::cont::ArrayHandle<ValueType, StorageTagIn>& input)
{
// Use a temporary permutation array to simplify the mapping:
auto tmp = vtkm::cont::make_ArrayHandlePermutation(this->ValidCellIds, input);
// Copy into an array with default storage:
vtkm::cont::ArrayHandle<ValueType> result;
vtkm::cont::ArrayCopy(tmp, result);
return result;
}
vtkm::cont::ArrayHandle<vtkm::Id> GetValidCellIds() const { return this->ValidCellIds; }
private:
vtkm::cont::ArrayHandle<vtkm::Id> ValidCellIds;
};
}
} // namespace vtkm::worklet
#endif // vtkm_m_worklet_ExtractGeometry_h