diff --git a/Accelerators/Vtkm/Filters/vtkmSlice.cxx b/Accelerators/Vtkm/Filters/vtkmSlice.cxx index 8d86d81b6d277720118d76fe998e1231b39b3aff..500e6d5e58ce3f777b0eab86028b3089c61e4aed 100644 --- a/Accelerators/Vtkm/Filters/vtkmSlice.cxx +++ b/Accelerators/Vtkm/Filters/vtkmSlice.cxx @@ -17,6 +17,7 @@ #include "vtkCellData.h" #include "vtkDataSet.h" +#include "vtkDataSetAttributes.h" #include "vtkImageData.h" #include "vtkInformation.h" #include "vtkInformationVector.h" @@ -33,9 +34,13 @@ #include "vtkmlib/ImplicitFunctionConverter.h" #include "vtkmlib/PolyDataConverter.h" +#include <vtkm/cont/ArrayCopy.h> #include <vtkm/cont/ErrorFilterExecution.h> +#include <vtkm/cont/Invoker.h> #include <vtkm/filter/contour/Slice.h> +#include <vtkm/filter/entity_extraction/Threshold.h> #include <vtkm/worklet/WorkletMapField.h> +#include <vtkm/worklet/WorkletMapTopology.h> VTK_ABI_NAMESPACE_BEGIN vtkStandardNewMacro(vtkmSlice); @@ -148,6 +153,34 @@ void ChangeTriangleOrientation(vtkm::cont::DataSet& dataset) } } +struct IdentifyCellsToDiscard : public vtkm::worklet::WorkletVisitCellsWithPoints +{ + using ControlSignature = void(CellSetIn cellset, FieldInCell cellGhostFlag, + FieldInPoint pointGhostFlags, FieldOutCell discard); + + using ExecutionSignature = _4(_2, _3, PointCount); + + template <typename VecType> + VTKM_EXEC vtkm::UInt8 operator()( + vtkm::UInt8 cellGhostFlag, const VecType& pointGhostFlags, vtkm::IdComponent numPoints) const + { + if (cellGhostFlag & (vtkDataSetAttributes::DUPLICATECELL | vtkDataSetAttributes::HIDDENCELL)) + { + return 1; + } + + for (vtkm::IdComponent i = 0; i < numPoints; ++i) + { + if (pointGhostFlags[i] & vtkDataSetAttributes::HIDDENPOINT) + { + return 1; + } + } + + return 0; + } +}; + } // anonymous namespace //------------------------------------------------------------------------------ @@ -217,6 +250,63 @@ int vtkmSlice::RequestData( vtkm::cont::DataSet result = filter.Execute(in); ChangeTriangleOrientation(result); + // discard hidden and duplicate cells + if (input->GetCellGhostArray() || input->GetPointGhostArray()) + { + using GhostValueTypeList = vtkm::List<vtkm::UInt8>; + using GhostStorageList = + vtkm::List<vtkm::cont::StorageTagConstant, vtkm::cont::StorageTagBasic>; + vtkm::cont::UncertainArrayHandle<GhostValueTypeList, GhostStorageList> cellGhostArray, + pointGhostArray; + if (input->GetCellGhostArray()) + { + const auto& field = result.GetCellField(input->GetCellGhostArray()->GetName()); + + // FIXME: The ghost fields get converted to float in the slice filter. This is fixed in + // newer version of VTK-m. The copy should be removed when we update and replaced with: + // cellGhostArray = field.GetData().AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::UInt8>>(); + vtkm::cont::ArrayHandle<vtkm::UInt8> copy; + vtkm::cont::ArrayCopy( + field.GetData().AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::FloatDefault>>(), copy); + cellGhostArray = copy; + } + else + { + cellGhostArray = vtkm::cont::ArrayHandleConstant<vtkm::UInt8>(0, result.GetNumberOfCells()); + } + + if (input->GetPointGhostArray()) + { + const auto& field = result.GetPointField(input->GetPointGhostArray()->GetName()); + + // FIXME: The ghost fields get converted to float in the slice filter. This is fixed in + // newer version of VTK-m. The copy should be removed when we update and replaced with: + // pointGhostArray = field.GetData().AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::UInt8>>(); + vtkm::cont::ArrayHandle<vtkm::UInt8> copy; + vtkm::cont::ArrayCopy( + field.GetData().AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::FloatDefault>>(), copy); + pointGhostArray = copy; + } + else + { + pointGhostArray = + vtkm::cont::ArrayHandleConstant<vtkm::UInt8>(0, result.GetNumberOfPoints()); + } + + vtkm::cont::ArrayHandle<vtkm::UInt8> discard; + vtkm::cont::Invoker{}( + IdentifyCellsToDiscard{}, result.GetCellSet(), cellGhostArray, pointGhostArray, discard); + + result.AddCellField("discard", discard); + + vtkm::filter::entity_extraction::Threshold threshold; + threshold.SetActiveField("discard", vtkm::cont::Field::Association::Cells); + threshold.SetThresholdBelow(0); + threshold.SetFieldsToPass( + vtkm::filter::FieldSelection("discard", vtkm::filter::FieldSelection::Mode::Exclude)); + result = threshold.Execute(result); + } + // convert back the dataset to VTK if (!fromvtkm::Convert(result, output, input)) {