mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Clip: Remove unused points
The clip filter used to copy the input points and point fields as is, regardless of if they were actually part of the output. With this change, we track which input points are actually part of the output and copy only those values. Address: #112
This commit is contained in:
parent
758fedc661
commit
1261e459d3
9
docs/changelog/clip-remove-unused-points.md
Normal file
9
docs/changelog/clip-remove-unused-points.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Clip now doesn't copy unused points from the input to the output
|
||||||
|
|
||||||
|
Previously, clip would just copy all the points and point data from the input to the output,
|
||||||
|
and only append the new points. This would affect the bounds computation of the result.
|
||||||
|
If the caller wanted to remove the unused points, they had to run the CleanGrid filter
|
||||||
|
on the result.
|
||||||
|
|
||||||
|
With this change, clip now keeps track of which inputs are actually part of the output
|
||||||
|
and copies only those points.
|
@ -70,8 +70,8 @@ void TestClipExplicit()
|
|||||||
vtkm::cont::ArrayHandle<vtkm::Float32> resultArrayHandle;
|
vtkm::cont::ArrayHandle<vtkm::Float32> resultArrayHandle;
|
||||||
temp.AsArrayHandle(resultArrayHandle);
|
temp.AsArrayHandle(resultArrayHandle);
|
||||||
|
|
||||||
vtkm::Float32 expected[7] = { 1, 2, 1, 0, 0.5, 0.5, 0.5 };
|
vtkm::Float32 expected[6] = { 1, 2, 1, 0.5, 0.5, 0.5 };
|
||||||
for (int i = 0; i < 7; ++i)
|
for (int i = 0; i < 6; ++i)
|
||||||
{
|
{
|
||||||
VTKM_TEST_ASSERT(test_equal(resultArrayHandle.ReadPortal().Get(i), expected[i]),
|
VTKM_TEST_ASSERT(test_equal(resultArrayHandle.ReadPortal().Get(i), expected[i]),
|
||||||
"Wrong result for Clip fliter on triangle explicit data");
|
"Wrong result for Clip fliter on triangle explicit data");
|
||||||
|
@ -71,11 +71,11 @@ void TestClipStructured(vtkm::Float64 offset)
|
|||||||
vtkm::cont::ArrayHandle<vtkm::Float32> resultArrayHandle;
|
vtkm::cont::ArrayHandle<vtkm::Float32> resultArrayHandle;
|
||||||
temp.AsArrayHandle(resultArrayHandle);
|
temp.AsArrayHandle(resultArrayHandle);
|
||||||
|
|
||||||
VTKM_TEST_ASSERT(resultArrayHandle.GetNumberOfValues() == 13,
|
VTKM_TEST_ASSERT(resultArrayHandle.GetNumberOfValues() == 12,
|
||||||
"Wrong number of points in the output dataset");
|
"Wrong number of points in the output dataset");
|
||||||
|
|
||||||
vtkm::Float32 expected[13] = { 1, 1, 1, 1, 0, 1, 1, 1, 1, 0.25, 0.25, 0.25, 0.25 };
|
vtkm::Float32 expected[12] = { 1, 1, 1, 1, 1, 1, 1, 1, 0.25, 0.25, 0.25, 0.25 };
|
||||||
for (int i = 0; i < 13; ++i)
|
for (int i = 0; i < 12; ++i)
|
||||||
{
|
{
|
||||||
VTKM_TEST_ASSERT(test_equal(resultArrayHandle.ReadPortal().Get(i), expected[i]),
|
VTKM_TEST_ASSERT(test_equal(resultArrayHandle.ReadPortal().Get(i), expected[i]),
|
||||||
"Wrong result for ClipWithImplicitFunction fliter on sturctured quads data");
|
"Wrong result for ClipWithImplicitFunction fliter on sturctured quads data");
|
||||||
@ -107,11 +107,11 @@ void TestClipStructuredInverted()
|
|||||||
vtkm::cont::ArrayHandle<vtkm::Float32> resultArrayHandle;
|
vtkm::cont::ArrayHandle<vtkm::Float32> resultArrayHandle;
|
||||||
temp.AsArrayHandle(resultArrayHandle);
|
temp.AsArrayHandle(resultArrayHandle);
|
||||||
|
|
||||||
VTKM_TEST_ASSERT(resultArrayHandle.GetNumberOfValues() == 13,
|
VTKM_TEST_ASSERT(resultArrayHandle.GetNumberOfValues() == 5,
|
||||||
"Wrong number of points in the output dataset");
|
"Wrong number of points in the output dataset");
|
||||||
|
|
||||||
vtkm::Float32 expected[13] = { 1, 1, 1, 1, 0, 1, 1, 1, 1, 0.25, 0.25, 0.25, 0.25 };
|
vtkm::Float32 expected[5] = { 0, 0.25, 0.25, 0.25, 0.25 };
|
||||||
for (int i = 0; i < 13; ++i)
|
for (int i = 0; i < 5; ++i)
|
||||||
{
|
{
|
||||||
VTKM_TEST_ASSERT(test_equal(resultArrayHandle.ReadPortal().Get(i), expected[i]),
|
VTKM_TEST_ASSERT(test_equal(resultArrayHandle.ReadPortal().Get(i), expected[i]),
|
||||||
"Wrong result for ClipWithImplicitFunction fliter on sturctured quads data");
|
"Wrong result for ClipWithImplicitFunction fliter on sturctured quads data");
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#ifndef vtkm_m_worklet_Clip_h
|
#ifndef vtkm_m_worklet_Clip_h
|
||||||
#define vtkm_m_worklet_Clip_h
|
#define vtkm_m_worklet_Clip_h
|
||||||
|
|
||||||
|
#include <vtkm/filter/clean_grid/worklet/RemoveUnusedPoints.h>
|
||||||
#include <vtkm/filter/contour/worklet/clip/ClipTables.h>
|
#include <vtkm/filter/contour/worklet/clip/ClipTables.h>
|
||||||
#include <vtkm/worklet/Keys.h>
|
#include <vtkm/worklet/Keys.h>
|
||||||
#include <vtkm/worklet/WorkletMapField.h>
|
#include <vtkm/worklet/WorkletMapField.h>
|
||||||
@ -325,6 +326,7 @@ public:
|
|||||||
FieldInCell clipStats,
|
FieldInCell clipStats,
|
||||||
ExecObject clipTables,
|
ExecObject clipTables,
|
||||||
ExecObject connectivityObject,
|
ExecObject connectivityObject,
|
||||||
|
WholeArrayOut pointsOnlyConnectivityIndices,
|
||||||
WholeArrayOut edgePointReverseConnectivity,
|
WholeArrayOut edgePointReverseConnectivity,
|
||||||
WholeArrayOut edgePointInterpolation,
|
WholeArrayOut edgePointInterpolation,
|
||||||
WholeArrayOut inCellReverseConnectivity,
|
WholeArrayOut inCellReverseConnectivity,
|
||||||
@ -349,7 +351,8 @@ public:
|
|||||||
_11,
|
_11,
|
||||||
_12,
|
_12,
|
||||||
_13,
|
_13,
|
||||||
_14);
|
_14,
|
||||||
|
_15);
|
||||||
|
|
||||||
template <typename CellShapeTag,
|
template <typename CellShapeTag,
|
||||||
typename PointVecType,
|
typename PointVecType,
|
||||||
@ -366,6 +369,7 @@ public:
|
|||||||
const ClipStats& clipStats,
|
const ClipStats& clipStats,
|
||||||
const internal::ClipTables::DevicePortal<DeviceAdapter>& clippingData,
|
const internal::ClipTables::DevicePortal<DeviceAdapter>& clippingData,
|
||||||
ConnectivityObject& connectivityObject,
|
ConnectivityObject& connectivityObject,
|
||||||
|
IdArrayType& pointsOnlyConnectivityIndices,
|
||||||
IdArrayType& edgePointReverseConnectivity,
|
IdArrayType& edgePointReverseConnectivity,
|
||||||
EdgeInterpolationPortalType& edgePointInterpolation,
|
EdgeInterpolationPortalType& edgePointInterpolation,
|
||||||
IdArrayType& inCellReverseConnectivity,
|
IdArrayType& inCellReverseConnectivity,
|
||||||
@ -388,6 +392,8 @@ public:
|
|||||||
// Start Indices to keep track of interpolation points for new cell.
|
// Start Indices to keep track of interpolation points for new cell.
|
||||||
vtkm::Id inCellInterpPointIndex = clipStats.NumberOfInCellInterpPoints;
|
vtkm::Id inCellInterpPointIndex = clipStats.NumberOfInCellInterpPoints;
|
||||||
vtkm::Id inCellEdgeInterpIndex = clipStats.NumberOfInCellEdgeIndices;
|
vtkm::Id inCellEdgeInterpIndex = clipStats.NumberOfInCellEdgeIndices;
|
||||||
|
// Start index of connectivityPointsOnly
|
||||||
|
vtkm::Id pointsOnlyConnectivityIndicesIndex = connectivityIndex - edgeIndex - inCellIndex;
|
||||||
|
|
||||||
// Iterate over the shapes for the current cell and begin to fill connectivity.
|
// Iterate over the shapes for the current cell and begin to fill connectivity.
|
||||||
vtkm::Id numberOfCells = clippingData.ValueAt(clipIndex++);
|
vtkm::Id numberOfCells = clippingData.ValueAt(clipIndex++);
|
||||||
@ -471,6 +477,8 @@ public:
|
|||||||
}
|
}
|
||||||
else if (entry >= 100) // existing vertex
|
else if (entry >= 100) // existing vertex
|
||||||
{
|
{
|
||||||
|
pointsOnlyConnectivityIndices.Set(pointsOnlyConnectivityIndicesIndex++,
|
||||||
|
connectivityIndex);
|
||||||
connectivityObject.SetConnectivity(connectivityIndex++, points[entry - 100]);
|
connectivityObject.SetConnectivity(connectivityIndex++, points[entry - 100]);
|
||||||
}
|
}
|
||||||
else // case of a new edge point
|
else // case of a new edge point
|
||||||
@ -588,6 +596,7 @@ public:
|
|||||||
bool invert)
|
bool invert)
|
||||||
{
|
{
|
||||||
vtkm::cont::Invoker invoke;
|
vtkm::cont::Invoker invoke;
|
||||||
|
|
||||||
// Create the required output fields.
|
// Create the required output fields.
|
||||||
vtkm::cont::ArrayHandle<ClipStats> clipStats;
|
vtkm::cont::ArrayHandle<ClipStats> clipStats;
|
||||||
vtkm::cont::ArrayHandle<vtkm::Id> clipTableIndices;
|
vtkm::cont::ArrayHandle<vtkm::Id> clipTableIndices;
|
||||||
@ -610,6 +619,10 @@ public:
|
|||||||
shapes, numberOfIndices, connectivity, offsets, total);
|
shapes, numberOfIndices, connectivity, offsets, total);
|
||||||
|
|
||||||
//Begin Process of Constructing the new CellSet.
|
//Begin Process of Constructing the new CellSet.
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id> pointsOnlyConnectivityIndices;
|
||||||
|
pointsOnlyConnectivityIndices.Allocate(total.NumberOfIndices - total.NumberOfEdgeIndices -
|
||||||
|
total.NumberOfInCellIndices);
|
||||||
|
|
||||||
vtkm::cont::ArrayHandle<vtkm::Id> edgePointReverseConnectivity;
|
vtkm::cont::ArrayHandle<vtkm::Id> edgePointReverseConnectivity;
|
||||||
edgePointReverseConnectivity.Allocate(total.NumberOfEdgeIndices);
|
edgePointReverseConnectivity.Allocate(total.NumberOfEdgeIndices);
|
||||||
vtkm::cont::ArrayHandle<EdgeInterpolation> edgeInterpolation;
|
vtkm::cont::ArrayHandle<EdgeInterpolation> edgeInterpolation;
|
||||||
@ -635,6 +648,7 @@ public:
|
|||||||
cellSetStats,
|
cellSetStats,
|
||||||
this->ClipTablesInstance,
|
this->ClipTablesInstance,
|
||||||
connectivityObject,
|
connectivityObject,
|
||||||
|
pointsOnlyConnectivityIndices,
|
||||||
edgePointReverseConnectivity,
|
edgePointReverseConnectivity,
|
||||||
edgeInterpolation,
|
edgeInterpolation,
|
||||||
cellPointReverseConnectivity,
|
cellPointReverseConnectivity,
|
||||||
@ -648,6 +662,30 @@ public:
|
|||||||
clipTableIndices.ReleaseResources();
|
clipTableIndices.ReleaseResources();
|
||||||
cellSetStats.ReleaseResources();
|
cellSetStats.ReleaseResources();
|
||||||
|
|
||||||
|
// extract only the used points from the input
|
||||||
|
{
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::IdComponent> pointMask;
|
||||||
|
pointMask.AllocateAndFill(scalars.GetNumberOfValues(), 0);
|
||||||
|
|
||||||
|
auto pointsOnlyConnectivity =
|
||||||
|
vtkm::cont::make_ArrayHandlePermutation(pointsOnlyConnectivityIndices, connectivity);
|
||||||
|
|
||||||
|
invoke(
|
||||||
|
vtkm::worklet::RemoveUnusedPoints::GeneratePointMask{}, pointsOnlyConnectivity, pointMask);
|
||||||
|
|
||||||
|
vtkm::worklet::ScatterCounting scatter(pointMask, true);
|
||||||
|
auto pointMapInputToOutput = scatter.GetInputToOutputMap();
|
||||||
|
this->PointMapOutputToInput = scatter.GetOutputToInputMap();
|
||||||
|
pointMask.ReleaseResources();
|
||||||
|
|
||||||
|
invoke(vtkm::worklet::RemoveUnusedPoints::TransformPointIndices{},
|
||||||
|
pointsOnlyConnectivity,
|
||||||
|
pointMapInputToOutput,
|
||||||
|
pointsOnlyConnectivity);
|
||||||
|
|
||||||
|
pointsOnlyConnectivityIndices.ReleaseResources();
|
||||||
|
}
|
||||||
|
|
||||||
// Get unique EdgeInterpolation : unique edge points.
|
// Get unique EdgeInterpolation : unique edge points.
|
||||||
// LowerBound for edgeInterpolation : get index into new edge points array.
|
// LowerBound for edgeInterpolation : get index into new edge points array.
|
||||||
// LowerBound for cellPointEdgeInterpolation : get index into new edge points array.
|
// LowerBound for cellPointEdgeInterpolation : get index into new edge points array.
|
||||||
@ -670,7 +708,7 @@ public:
|
|||||||
EdgeInterpolation::LessThanOp());
|
EdgeInterpolation::LessThanOp());
|
||||||
cellPointEdgeInterpolation.ReleaseResources();
|
cellPointEdgeInterpolation.ReleaseResources();
|
||||||
|
|
||||||
this->EdgePointsOffset = scalars.GetNumberOfValues();
|
this->EdgePointsOffset = this->PointMapOutputToInput.GetNumberOfValues();
|
||||||
this->InCellPointsOffset =
|
this->InCellPointsOffset =
|
||||||
this->EdgePointsOffset + this->EdgePointsInterpolation.GetNumberOfValues();
|
this->EdgePointsOffset + this->EdgePointsInterpolation.GetNumberOfValues();
|
||||||
|
|
||||||
@ -691,7 +729,7 @@ public:
|
|||||||
invoke(scatterInCellPointConnectivity, cellPointReverseConnectivity, connectivity);
|
invoke(scatterInCellPointConnectivity, cellPointReverseConnectivity, connectivity);
|
||||||
|
|
||||||
vtkm::cont::CellSetExplicit<> output;
|
vtkm::cont::CellSetExplicit<> output;
|
||||||
vtkm::Id numberOfPoints = scalars.GetNumberOfValues() +
|
vtkm::Id numberOfPoints = this->PointMapOutputToInput.GetNumberOfValues() +
|
||||||
this->EdgePointsInterpolation.GetNumberOfValues() + total.NumberOfInCellPoints;
|
this->EdgePointsInterpolation.GetNumberOfValues() + total.NumberOfInCellPoints;
|
||||||
|
|
||||||
vtkm::cont::ConvertNumComponentsToOffsets(numberOfIndices, offsets);
|
vtkm::cont::ConvertNumComponentsToOffsets(numberOfIndices, offsets);
|
||||||
@ -833,21 +871,25 @@ public:
|
|||||||
this->InterpolationKeys.BuildArrays(this->InCellInterpolationKeys, KeysSortType::Unstable);
|
this->InterpolationKeys.BuildArrays(this->InCellInterpolationKeys, KeysSortType::Unstable);
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkm::Id numberOfOriginalValues = input.GetNumberOfValues();
|
vtkm::Id numberOfVertexPoints = this->PointMapOutputToInput.GetNumberOfValues();
|
||||||
vtkm::Id numberOfEdgePoints = this->EdgePointsInterpolation.GetNumberOfValues();
|
vtkm::Id numberOfEdgePoints = this->EdgePointsInterpolation.GetNumberOfValues();
|
||||||
vtkm::Id numberOfInCellPoints = this->InterpolationKeys.GetUniqueKeys().GetNumberOfValues();
|
vtkm::Id numberOfInCellPoints = this->InterpolationKeys.GetUniqueKeys().GetNumberOfValues();
|
||||||
|
|
||||||
// Copy over the original values. They are still part of the output. (Unused points are
|
output.Allocate(numberOfVertexPoints + numberOfEdgePoints + numberOfInCellPoints);
|
||||||
// not culled. Use CleanGrid for that.)
|
|
||||||
output.Allocate(numberOfOriginalValues + numberOfEdgePoints + numberOfInCellPoints);
|
// Copy over the original values that are still part of the output.
|
||||||
vtkm::cont::Algorithm::CopySubRange(input, 0, numberOfOriginalValues, output);
|
vtkm::cont::Algorithm::CopySubRange(
|
||||||
|
vtkm::cont::make_ArrayHandlePermutation(this->PointMapOutputToInput, input),
|
||||||
|
0,
|
||||||
|
numberOfVertexPoints,
|
||||||
|
output);
|
||||||
|
|
||||||
// Interpolate all new points that lie on edges of the input mesh.
|
// Interpolate all new points that lie on edges of the input mesh.
|
||||||
vtkm::cont::Invoker invoke;
|
vtkm::cont::Invoker invoke;
|
||||||
invoke(PerformEdgeInterpolations{},
|
invoke(PerformEdgeInterpolations{},
|
||||||
this->EdgePointsInterpolation,
|
this->EdgePointsInterpolation,
|
||||||
input,
|
input,
|
||||||
vtkm::cont::make_ArrayHandleView(output, numberOfOriginalValues, numberOfEdgePoints));
|
vtkm::cont::make_ArrayHandleView(output, numberOfVertexPoints, numberOfEdgePoints));
|
||||||
|
|
||||||
// Perform a gather on the output to get all the required values for calculation of centroids
|
// Perform a gather on the output to get all the required values for calculation of centroids
|
||||||
// using the interpolation info array.
|
// using the interpolation info array.
|
||||||
@ -857,7 +899,7 @@ public:
|
|||||||
this->InterpolationKeys,
|
this->InterpolationKeys,
|
||||||
toReduceValues,
|
toReduceValues,
|
||||||
vtkm::cont::make_ArrayHandleView(
|
vtkm::cont::make_ArrayHandleView(
|
||||||
output, numberOfOriginalValues + numberOfEdgePoints, numberOfInCellPoints));
|
output, numberOfVertexPoints + numberOfEdgePoints, numberOfInCellPoints));
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkm::cont::ArrayHandle<vtkm::Id> GetCellMapOutputToInput() const
|
vtkm::cont::ArrayHandle<vtkm::Id> GetCellMapOutputToInput() const
|
||||||
@ -871,6 +913,7 @@ private:
|
|||||||
vtkm::cont::ArrayHandle<vtkm::Id> InCellInterpolationKeys;
|
vtkm::cont::ArrayHandle<vtkm::Id> InCellInterpolationKeys;
|
||||||
vtkm::cont::ArrayHandle<vtkm::Id> InCellInterpolationInfo;
|
vtkm::cont::ArrayHandle<vtkm::Id> InCellInterpolationInfo;
|
||||||
vtkm::cont::ArrayHandle<vtkm::Id> CellMapOutputToInput;
|
vtkm::cont::ArrayHandle<vtkm::Id> CellMapOutputToInput;
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id> PointMapOutputToInput;
|
||||||
vtkm::Id EdgePointsOffset;
|
vtkm::Id EdgePointsOffset;
|
||||||
vtkm::Id InCellPointsOffset;
|
vtkm::Id InCellPointsOffset;
|
||||||
vtkm::worklet::Keys<vtkm::Id> InterpolationKeys;
|
vtkm::worklet::Keys<vtkm::Id> InterpolationKeys;
|
||||||
|
Loading…
Reference in New Issue
Block a user