Fix degenerate polygon removal

There was a bug in `CleanGrid` when removing degenerate polygons where it
would not detect if the first and last point were the same. This has been
fixed.

There was also an error with function overloading that was causing 0D and
3D cells to enter the wrong computation for degenerate cells. This has also
been fixed.

Fixes #796
This commit is contained in:
Kenneth Moreland 2023-08-24 16:10:50 -04:00
parent 7fa44ff4a8
commit 6e674ddea6
3 changed files with 21 additions and 9 deletions

@ -0,0 +1,9 @@
# Fix degenerate cell removal
There was a bug in `CleanGrid` when removing degenerate polygons where it
would not detect if the first and last point were the same. This has been
fixed.
There was also an error with function overloading that was causing 0D and
3D cells to enter the wrong computation for degenerate cells. This has also
been fixed.

@ -140,7 +140,7 @@ void TestPointMerging()
<< std::endl; << std::endl;
cleanGrid.SetRemoveDegenerateCells(true); cleanGrid.SetRemoveDegenerateCells(true);
vtkm::cont::DataSet noDegenerateCells = cleanGrid.Execute(inData); vtkm::cont::DataSet noDegenerateCells = cleanGrid.Execute(inData);
constexpr vtkm::Id numNonDegenerateCells = 33; constexpr vtkm::Id numNonDegenerateCells = 18;
VTKM_TEST_ASSERT(noDegenerateCells.GetNumberOfCells() == numNonDegenerateCells); VTKM_TEST_ASSERT(noDegenerateCells.GetNumberOfCells() == numNonDegenerateCells);
VTKM_TEST_ASSERT(noDegenerateCells.GetCellSet().GetNumberOfPoints() == farFastMergeNumPoints); VTKM_TEST_ASSERT(noDegenerateCells.GetCellSet().GetNumberOfPoints() == farFastMergeNumPoints);
VTKM_TEST_ASSERT(noDegenerateCells.GetNumberOfPoints() == farFastMergeNumPoints); VTKM_TEST_ASSERT(noDegenerateCells.GetNumberOfPoints() == farFastMergeNumPoints);

@ -44,18 +44,20 @@ struct RemoveDegenerateCells
{ {
const vtkm::IdComponent numPoints = pointIds.GetNumberOfComponents(); const vtkm::IdComponent numPoints = pointIds.GetNumberOfComponents();
vtkm::IdComponent numUnduplicatedPoints = 0; vtkm::IdComponent numUnduplicatedPoints = 0;
for (vtkm::IdComponent localPointId = 0; localPointId < numPoints; ++localPointId) // Skip first point if it is the same as the last.
for (vtkm::IdComponent localPointId = ((pointIds[0] != pointIds[numPoints - 1]) ? 0 : 1);
localPointId < numPoints;
++localPointId)
{ {
++numUnduplicatedPoints; ++numUnduplicatedPoints;
if (numUnduplicatedPoints >= dimensionality + 1) if (numUnduplicatedPoints >= dimensionality + 1)
{ {
return true; return true;
} }
while (((localPointId < numPoints - 1) && // Skip over any repeated points. Assume any repeated points are adjacent.
(pointIds[localPointId] == pointIds[localPointId + 1])) || while ((localPointId < numPoints - 1) &&
((localPointId == numPoints - 1) && (pointIds[localPointId] == pointIds[0]))) (pointIds[localPointId] == pointIds[localPointId + 1]))
{ {
// Skip over any repeated points. Assume any repeated points are adjacent.
++localPointId; ++localPointId;
} }
} }
@ -65,7 +67,7 @@ struct RemoveDegenerateCells
template <typename CellShapeTag, typename PointVecType> template <typename CellShapeTag, typename PointVecType>
VTKM_EXEC bool CheckForDimensionality(vtkm::CellTopologicalDimensionsTag<0>, VTKM_EXEC bool CheckForDimensionality(vtkm::CellTopologicalDimensionsTag<0>,
CellShapeTag, CellShapeTag,
PointVecType&&) PointVecType&&) const
{ {
return true; return true;
} }
@ -73,9 +75,10 @@ struct RemoveDegenerateCells
template <typename CellShapeTag, typename PointVecType> template <typename CellShapeTag, typename PointVecType>
VTKM_EXEC bool CheckForDimensionality(vtkm::CellTopologicalDimensionsTag<3>, VTKM_EXEC bool CheckForDimensionality(vtkm::CellTopologicalDimensionsTag<3>,
CellShapeTag shape, CellShapeTag shape,
PointVecType&& pointIds) PointVecType&& pointIds) const
{ {
const vtkm::IdComponent numFaces = vtkm::exec::CellFaceNumberOfFaces(shape, *this); vtkm::IdComponent numFaces;
vtkm::exec::CellFaceNumberOfFaces(shape, numFaces);
vtkm::Id numValidFaces = 0; vtkm::Id numValidFaces = 0;
for (vtkm::IdComponent faceId = 0; faceId < numFaces; ++faceId) for (vtkm::IdComponent faceId = 0; faceId < numFaces; ++faceId)
{ {