vtk-m/vtkm/worklet/ExtractGeometry.h

180 lines
6.3 KiB
C
Raw Normal View History

//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
2019-04-15 23:24:21 +00:00
//
// 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>
2017-05-18 14:51:24 +00:00
#include <vtkm/worklet/WorkletMapTopology.h>
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandle.h>
2017-05-18 14:51:24 +00:00
#include <vtkm/cont/CellSetPermutation.h>
#include <vtkm/cont/CoordinateSystem.h>
2017-05-18 14:51:24 +00:00
#include <vtkm/cont/DataSet.h>
#include <vtkm/ImplicitFunction.h>
2017-05-18 14:29:41 +00:00
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)
2017-05-18 14:29:41 +00:00
, 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
{
2017-05-04 21:04:54 +00:00
// Count points inside/outside volume of interest
vtkm::IdComponent inCnt = 0;
vtkm::IdComponent outCnt = 0;
2017-10-23 13:38:33 +00:00
vtkm::Id indx;
for (indx = 0; indx < numIndices; indx++)
{
2017-10-23 13:38:33 +00:00
vtkm::Id ptId = connectivityIn[static_cast<vtkm::IdComponent>(indx)];
2017-05-18 14:29:41 +00:00
vtkm::Vec<FloatDefault, 3> coordinate = coordinates.Get(ptId);
vtkm::FloatDefault value = function.Value(coordinate);
if (value <= 0)
inCnt++;
if (value >= 0)
outCnt++;
}
2017-05-04 21:04:54 +00:00
// Decide if cell is extracted
bool passFlag = false;
2017-05-18 14:29:41 +00:00
if (inCnt == numIndices && ExtractInside && !ExtractOnlyBoundaryCells)
{
passFlag = true;
2017-05-18 14:29:41 +00:00
}
else if (outCnt == numIndices && !ExtractInside && !ExtractOnlyBoundaryCells)
{
passFlag = true;
}
2017-05-18 14:29:41 +00:00
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
{
2019-08-13 21:28:37 +00:00
vtkm::cont::CellSetPermutation<CellSetType> permCellSet(*this->ValidIds, cellset);
*this->Output = permCellSet;
}
};
////////////////////////////////////////////////////////////////////////////////////
// Extract cells by ids permutes input data
template <typename CellSetType>
2017-05-18 14:29:41 +00:00
vtkm::cont::CellSetPermutation<CellSetType> Run(const CellSetType& cellSet,
const vtkm::cont::ArrayHandle<vtkm::Id>& cellIds)
{
2018-02-22 13:29:13 +00:00
using OutputType = vtkm::cont::CellSetPermutation<CellSetType>;
vtkm::cont::ArrayCopy(cellIds, this->ValidCellIds);
2019-08-13 21:28:37 +00:00
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
2019-08-13 21:28:37 +00:00
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