0
votes

I am writing a very simple program that:

  • 1 - Reads a .vtk file using itk::MeshFileReader

  • 2 - Decimates the mesh using SquaredEdgeLengthDecimationQuadEdgeMeshFilter

During step 2, I get an Access violation reading location error.

This crash happens for certain .vtk file and doesn't happen for others.

Have you encountered such error? How to solve it?

2

2 Answers

0
votes

It sounds like a bug in SquaredEdgeLengthDecimationQuadEdgeMeshFilter, or, less likely, in MeshFileReader.

Have you tried it with the latest stable release (v4.13) or the git master? If not, try that first. If the problem still persists, report the issue on ITK forum.

0
votes

SquaredEdgeLengthDecimationQuadEdgeMeshFilter expects a QuadEdge mesh input, which is only a subset of all possible geometries that can be saved within .vtk file. E.g. you can have a non-manifold stored as .vtk, in which case you cannot expect sane results when you run a QuadEdgeMeshFilter on it.

What I consider a bug is that the filter doesn't check this precondition; I would think throwing an exception would be appropriate in such case.

Unfortunately I don't know how to check whether an input mesh is a valid input mesh. But I have successfully avoided crashes in this filter by:

  • making sure the input has only one connected component (vtkPolyDataConnectivityFilter)
  • cleaning up with vtkCleanPolyData with PointMerging turned on

before converting to itk::QuadEdgeMesh and feeding it to SquaredEdgeLengthDecimationQuadEdgeMeshFilter.

On Linux you can use valgrind to check for memory issues, it will point out to you if/where there are memory issues when the filter is run. Preprocessing with the above two filters fixed the memory issues/crashes for my surfaces and the run under valgrind comes out clean.

EDIT: Below code for illustration:

#include <vtkPolyDataReader.h>
#include <vtkPolyDataConnectivityFilter.h>
#include <vtkCleanPolyData.h>

#define VTK_CREATE(type, name) vtkSmartPointer<type> name = vtkSmartPointer<type>::New();

...
VTK_CREATE(vtkPolyDataReader, reader);
reader->SetFileName("/tmp/mesh.vtk");

VTK_CREATE(vtkPolyDataConnectivityFilter, connFilter);
connFilter->SetInputConnection(reader->GetOutputPort());
connFilter->SetExtractionModeToLargestRegion();

VTK_CREATE(vtkCleanPolyData, cleaner);
cleaner->SetInputConnection(connFilter->GetOutputPort());
cleaner->SetPointMerging(1);
cleaner->Update();

// Now either convert it to itk::QuadMesh, or if you don't have a converter, just do another I/O
// itk::QuadEdgeMesh<double, 3> MeshType;
// MeshType::Pointer inputItk = PolyDataToItkMesh<MeshType>(cleaner->GetOutput());

VTK_CREATE(vtkPolyDataWriter, writer);
writer->SetInputData(cleaner->GetOutput());
writer->SetFileName("/tmp/mesh_processed.vtk");
writer->Update();