Skip to content

Commit

Permalink
BUG: Fix Segfault in Delaunay Filter
Browse files Browse the repository at this point in the history
In the event that the Delaunay filter attempts to flip a non-internal
edge (such as along the boundary of an open mesh), the EulerOperator
returns a nullptr.  Previously, this filter was not properly checking
whether the returned edge was nullptr when attempting to reassign cell
data, causing a segfault.  Although the test mesh (mushroom.vtk) is
open and contains a boundary edge, these edges were apparently not being
added to the priority queue, presumably due to the regularity of the
cells, and therefore this case was not triggered in the testing suite.

In this patch, the test is modified by adding a small amount of noise
to the mesh vertices, causing boundary edges to be added to the priority
queue and triggering the failure.  Second, this patch only attempts to
reassign cell data if the Euler operator does not return a nullptr,
thus preventing the segfault.
  • Loading branch information
sudomakeinstall committed Jun 22, 2020
1 parent 3bcac28 commit e72fd01
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,15 @@ DelaunayConformingQuadEdgeMeshFilter<TInputMesh, TOutputMesh>::Process()
const auto il_id = qe->GetLeft(); // Input Left ID
const auto ir_id = qe->GetRight(); // Input Right ID
qe = m_FlipEdge->Evaluate(qe);
const auto ol_id = qe->GetLeft(); // Output Left ID
const auto or_id = qe->GetRight(); // Output Right ID

this->ReassignCellData(il_id, ol_id);
this->ReassignCellData(ir_id, or_id);

if (qe != nullptr)
{
const auto ol_id = qe->GetLeft(); // Output Left ID
const auto or_id = qe->GetRight(); // Output Right ID

this->ReassignCellData(il_id, ol_id);
this->ReassignCellData(ir_id, or_id);

++this->m_NumberOfEdgeFlips;
list_qe[4] = qe;

Expand Down
1 change: 1 addition & 0 deletions Modules/Filtering/QuadEdgeMeshFiltering/itk-module.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ itk_module(ITKQuadEdgeMeshFiltering
TEST_DEPENDS
ITKTestKernel
ITKIOMesh
ITKStatistics
DESCRIPTION
"${DOCUMENTATION}"
)
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ endforeach()

itk_add_test(NAME itkDelaunayConformingQuadEdgeMeshFilterTest
COMMAND ITKQuadEdgeMeshFilteringTestDriver
itkDelaunayConformingQuadEdgeMeshFilterTest DATA{${INPUTDATA}/mushroom.vtk} ${TEMP}/mushrom_delaunay.vtk)
itkDelaunayConformingQuadEdgeMeshFilterTest DATA{${INPUTDATA}/mushroom.vtk} ${TEMP}/mushroom_delaunay.vtk)
itk_add_test(NAME itkCleanQuadEdgeMeshFilterTest
COMMAND ITKQuadEdgeMeshFilteringTestDriver
itkCleanQuadEdgeMeshFilterTest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "itkMeshFileReader.h"
#include "itkMeshFileWriter.h"
#include "itkQuadEdgeMesh.h"
#include "itkNormalVariateGenerator.h"

// NEW
#include "itkDelaunayConformingQuadEdgeMeshFilter.h"
Expand All @@ -44,6 +45,20 @@ itkDelaunayConformingQuadEdgeMeshFilterTestHelper(const std::string & input,

MeshType::Pointer mesh = reader->GetOutput();

using GeneratorType = itk::Statistics::NormalVariateGenerator;
const auto generator = GeneratorType::New();
generator->Initialize(0);

const double sigma = 0.01;

for (auto it = mesh->GetPoints()->Begin(); it != mesh->GetPoints()->End(); ++it)
{
for (size_t d = 0; d < MeshType::MeshTraits::PointDimension; ++d)
{
it.Value()[d] += (generator->GetVariate() * sigma);
}
}

if (cell_data)
{
for (auto it = mesh->GetCells()->Begin(); it != mesh->GetCells()->End(); ++it)
Expand All @@ -54,16 +69,15 @@ itkDelaunayConformingQuadEdgeMeshFilterTestHelper(const std::string & input,

const auto filter = DelaunayConformFilterType::New();
filter->SetInput(mesh);
filter->Update();
ITK_TRY_EXPECT_NO_EXCEPTION(filter->Update());

if (cell_data)
{
for (auto it = mesh->GetCells()->Begin(); it != mesh->GetCells()->End(); ++it)
{
mesh->SetCellData(it.Index(), it.Index());
itkAssertOrThrowMacro(mesh->GetCellData()->IndexExists(it.Index()),
"Incorrect number of cells in cell data array.");
ITK_TEST_EXPECT_TRUE(mesh->GetCellData()->IndexExists(it.Index()));
}
ITK_TEST_EXPECT_EQUAL(mesh->GetNumberOfCells(), mesh->GetCellData()->Size());
}

// ** WRITE OUTPUT **
Expand Down

0 comments on commit e72fd01

Please sign in to comment.