New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pcl::MeshQuadricDecimationVTK seg fault #967

Open
felipepolido opened this Issue Oct 20, 2014 · 2 comments

Comments

Projects
None yet
2 participants
@felipepolido

Oi,

I am running a continuous loop that get the latest point-cloud from a laser sensor and transform it into a mesh.
The Point-cloud( input data) is very similar in each loop.
I am using the pcl::MeshQuadricDecimationVTK to decimate most of the mesh.
The code works for a few loops, behaving exactly like expected, but after what appears to be a random number of iterations it seg-faults with the following ( from gbd):

Program received signal SIGSEGV, Segmentation fault.

[Switching to Thread 0x7fffa6ffd700 (LWP 2502)]
0x00007fffde6006f9 in vtkQuadricDecimation::CollapseEdge(long long, long long) () from /usr/lib/libvtkGraphics.so.5.8
(gdb) bt
#0  0x00007fffde6006f9 in vtkQuadricDecimation::CollapseEdge(long long, long long) ()
   from /usr/lib/libvtkGraphics.so.5.8
#1  0x00007fffde602927 in vtkQuadricDecimation::RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) () from /usr/lib/libvtkGraphics.so.5.8
#2  0x00007fffe0973204 in vtkExecutive::CallAlgorithm(vtkInformation*, int, vtkInformationVector**, vtkInformationVector*) () from /usr/lib/libvtkFiltering.so.5.8
#3  0x00007fffe096775c in vtkDemandDrivenPipeline::ExecuteData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) () from /usr/lib/libvtkFiltering.so.5.8
#4  0x00007fffe096a79d in vtkDemandDrivenPipeline::ProcessRequest(vtkInformation*, vtkInformationVector**, vtkInformationVector*) () from /usr/lib/libvtkFiltering.so.5.8
#5  0x00007fffe0aa6cac in vtkStreamingDemandDrivenPipeline::ProcessRequest(vtkInformation*, vtkInformationVector**, vtkInformationVector*) () from /usr/lib/libvtkFiltering.so.5.8
#6  0x00007fffe09692a7 in vtkDemandDrivenPipeline::UpdateData(int) () from /usr/lib/libvtkFiltering.so.5.8
#7  0x00007fffe0aa8485 in vtkStreamingDemandDrivenPipeline::Update(int) () from /usr/lib/libvtkFiltering.so.5.8
#8  0x00007fffe586af1d in pcl::MeshQuadricDecimationVTK::performProcessing(pcl::PolygonMesh&) ()
   from /usr/lib/libpcl_surface.so.1.7
#9  0x00007fffe5717986 in pcl::MeshProcessing::process(pcl::PolygonMesh&) () from /usr/lib/libpcl_surface.so.1.7
#10 0x00007fffee194a88 in TrajOpt::AtlasTraj::PrepPointCloud(boost::shared_ptr<pcl::PointCloud<pcl::PointXYZRGB> >, Eigen::Transform<double, 3, 2, 0>) () from /home/fpolido/drc_workspace/src/trajopt/build_trajopt/lib/libatlas_traj.so
#11 0x000000000040ec07 in ConvexDecompLoop() ()
#12 0x00007ffff7020ce9 in thread_proxy () from /usr/lib/libboost_thread.so.1.46.1
#13 0x00007ffff6dfee9a in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0
#14 0x00007fffed6f331d in clone () from /lib/x86_64-linux-gnu/libc.so.6
#15 0x0000000000000000 in ?? ()

The specific lines in my code are =

pcl::PolygonMesh::Ptr simpleMesh(new pcl::PolygonMesh()); 
pcl::MeshQuadricDecimationVTK mesh_decimator; 
mesh_decimator.setInputMesh(triangles); 
mesh_decimator.setTargetReductionFactor(1 - 0.1); 
mesh_decimator.process(*simpleMesh); 

For reference, the mesh generation from Point-Cloud is:

// Normal estimation*
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;
pcl::PointCloud<pcl::Normal>::Ptr normals (new pcl::PointCloud<pcl::Normal>);
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>);
tree->setInputCloud (temp);
n.setInputCloud (temp);
n.setSearchMethod (tree);
n.setKSearch (20);
n.compute (*normals);
//* normals should not contain the point normals + surface curvatures

// Concatenate the XYZ and normal fields*
pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals (new pcl::PointCloud<pcl::PointNormal>);
pcl::concatenateFields (*temp, *normals, *cloud_with_normals);
//* cloud_with_normals = cloud + normals

// Create search tree*
pcl::search::KdTree<pcl::PointNormal>::Ptr tree2 (new pcl::search::KdTree<pcl::PointNormal>);
tree2->setInputCloud (cloud_with_normals);

// Initialize objects
pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3;
//pcl::PolygonMesh triangles;
pcl::PolygonMesh::Ptr triangles(new pcl::PolygonMesh());

// Set the maximum distance between connected points (maximum edge length)
//Very importan in setting the size of blocks:
gp3.setSearchRadius (0.15); //0.025

// Set typical values for the parameters
gp3.setMu (250);//2.5
gp3.setMaximumNearestNeighbors (100);
gp3.setMaximumSurfaceAngle(M_PI/4); // 45 degrees
gp3.setMinimumAngle(M_PI/18); // 10 degrees
gp3.setMaximumAngle(2*M_PI/3); // 120 degrees
gp3.setNormalConsistency(false);

// Get result
gp3.setInputCloud (cloud_with_normals);
gp3.setSearchMethod (tree2);
gp3.reconstruct (*triangles);

The computer is concurrently running a simulator, which hogs a lot of the memory. I am guessing this is an internal memory-leak. I wasn't able to find any similar bugs on the Issue Tracker

Any ideas? And is there any alternative options for the same functionality as MeshQuadricDecimationVTK?

Thanks in advance!

Felipe

@felipepolido

This comment has been minimized.

Show comment
Hide comment
@felipepolido

felipepolido Oct 21, 2014

Alright, I compiled VTK from source in DEBUG mode, and the error message is the following:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fff93fff700 (LWP 13376)]
0x00007fffe8ac2d85 in vtkQuadricDecimation2::CollapseEdge (this=0x7fff9406cc20, pt0Id=635, pt1Id=635)
    at /home/fpolido/drc_workspace/src/trajopt/src/cloudproc/vtkQuadricDecimation2.cxx:1101
1101          if (pts[j] == pt1Id) 
(gdb) bt
#0  0x00007fffe8ac2d85 in vtkQuadricDecimation2::CollapseEdge (this=0x7fff9406cc20, pt0Id=635, pt1Id=635)
    at /home/fpolido/drc_workspace/src/trajopt/src/cloudproc/vtkQuadricDecimation2.cxx:1101
#1  0x00007fffe8abeee2 in vtkQuadricDecimation2::RequestData (this=0x7fff9406cc20, inputVector=0x7fff94764da0, 
    outputVector=0x7fff94795d70)
    at /home/fpolido/drc_workspace/src/trajopt/src/cloudproc/vtkQuadricDecimation2.cxx:352
#2  0x00007fffe00b1204 in vtkExecutive::CallAlgorithm(vtkInformation*, int, vtkInformationVector**, vtkInformationVector*) () from /usr/lib/libvtkFiltering.so.5.8
#3  0x00007fffe00a575c in vtkDemandDrivenPipeline::ExecuteData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) () from /usr/lib/libvtkFiltering.so.5.8
#4  0x00007fffe00a879d in vtkDemandDrivenPipeline::ProcessRequest(vtkInformation*, vtkInformationVector**, vtkInformationVector*) () from /usr/lib/libvtkFiltering.so.5.8
#5  0x00007fffe01e4cac in vtkStreamingDemandDrivenPipeline::ProcessRequest(vtkInformation*, vtkInformationVector**, vtkInformationVector*) () from /usr/lib/libvtkFiltering.so.5.8
#6  0x00007fffe00a72a7 in vtkDemandDrivenPipeline::UpdateData(int) () from /usr/lib/libvtkFiltering.so.5.8
#7  0x00007fffe01e6485 in vtkStreamingDemandDrivenPipeline::Update(int) () from /usr/lib/libvtkFiltering.so.5.8
#8  0x00007fffe8aba7fc in cloudproc::quadricSimplifyVTK (in=..., meshDecimationFrac=0.100000001)
    at /home/fpolido/drc_workspace/src/trajopt/src/cloudproc/mesh_simplification.cpp:81
#9  0x00007fffee0ed06d in TrajOpt::AtlasTraj::PrepPointCloud (this=0x330b330, cloudPtr=..., trans=...)
    at /home/fpolido/drc_workspace/src/trajopt/drc_traj/src/atlas_traj.cpp:597
#10 0x000000000043537a in ConvexDecompLoop ()
    at /home/fpolido/drc_workspace/src/trajopt/ros_interface/src/TrajOptNode.cpp:62
#11 0x000000000044a263 in boost::detail::thread_data<void (*)()>::run (this=0x904f540)
    at /usr/include/boost/thread/detail/thread.hpp:61
#12 0x00007ffff7020ce9 in thread_proxy () from /usr/lib/libboost_thread.so.1.46.1
#13 0x00007ffff6dfee9a in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0
#14 0x00007fffed5c131d in clone () from /lib/x86_64-linux-gnu/libc.so.6
#15 0x0000000000000000 in ?? ()

Line 1101 is the IF statement below:

int vtkQuadricDecimation2::CollapseEdge(vtkIdType pt0Id, vtkIdType pt1Id) 
{
  int j, numDeleted=0;
  vtkIdType i, npts, *pts, cellId;

  this->Mesh->GetPointCells(pt0Id, this->CollapseCellIds);
  for (i = 0; i < this->CollapseCellIds->GetNumberOfIds(); i++) 
    {
    cellId = this->CollapseCellIds->GetId(i);
    this->Mesh->GetCellPoints(cellId, npts, pts);
    for (j = 0; j < 3; j++) 
      {
      if (pts[j] == pt1Id) 
        {
        this->Mesh->RemoveCellReference(cellId);
        this->Mesh->DeleteCell(cellId);       
        numDeleted++;
        }
      }
    }

I narrowed down to the pts[j] variable returning an Invalid Pointer. So as a quick "hack solution" I wrapped the for loop with an if statement that checks for the pointer validity:

if(NULL !=pts) 
{
for (j = 0; j < 3; j++) 
  {
  if (pts[j] == pt1Id) 
    {
    this->Mesh->RemoveCellReference(cellId);
    this->Mesh->DeleteCell(cellId);       
    numDeleted++;
    }
  }
}
}

This "solved" the problem for me, but it doesn't actually tackle why this->Mesh->GetCellPoints is never initializing the pointer on some edge case.

Best,

Felipe

Alright, I compiled VTK from source in DEBUG mode, and the error message is the following:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fff93fff700 (LWP 13376)]
0x00007fffe8ac2d85 in vtkQuadricDecimation2::CollapseEdge (this=0x7fff9406cc20, pt0Id=635, pt1Id=635)
    at /home/fpolido/drc_workspace/src/trajopt/src/cloudproc/vtkQuadricDecimation2.cxx:1101
1101          if (pts[j] == pt1Id) 
(gdb) bt
#0  0x00007fffe8ac2d85 in vtkQuadricDecimation2::CollapseEdge (this=0x7fff9406cc20, pt0Id=635, pt1Id=635)
    at /home/fpolido/drc_workspace/src/trajopt/src/cloudproc/vtkQuadricDecimation2.cxx:1101
#1  0x00007fffe8abeee2 in vtkQuadricDecimation2::RequestData (this=0x7fff9406cc20, inputVector=0x7fff94764da0, 
    outputVector=0x7fff94795d70)
    at /home/fpolido/drc_workspace/src/trajopt/src/cloudproc/vtkQuadricDecimation2.cxx:352
#2  0x00007fffe00b1204 in vtkExecutive::CallAlgorithm(vtkInformation*, int, vtkInformationVector**, vtkInformationVector*) () from /usr/lib/libvtkFiltering.so.5.8
#3  0x00007fffe00a575c in vtkDemandDrivenPipeline::ExecuteData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) () from /usr/lib/libvtkFiltering.so.5.8
#4  0x00007fffe00a879d in vtkDemandDrivenPipeline::ProcessRequest(vtkInformation*, vtkInformationVector**, vtkInformationVector*) () from /usr/lib/libvtkFiltering.so.5.8
#5  0x00007fffe01e4cac in vtkStreamingDemandDrivenPipeline::ProcessRequest(vtkInformation*, vtkInformationVector**, vtkInformationVector*) () from /usr/lib/libvtkFiltering.so.5.8
#6  0x00007fffe00a72a7 in vtkDemandDrivenPipeline::UpdateData(int) () from /usr/lib/libvtkFiltering.so.5.8
#7  0x00007fffe01e6485 in vtkStreamingDemandDrivenPipeline::Update(int) () from /usr/lib/libvtkFiltering.so.5.8
#8  0x00007fffe8aba7fc in cloudproc::quadricSimplifyVTK (in=..., meshDecimationFrac=0.100000001)
    at /home/fpolido/drc_workspace/src/trajopt/src/cloudproc/mesh_simplification.cpp:81
#9  0x00007fffee0ed06d in TrajOpt::AtlasTraj::PrepPointCloud (this=0x330b330, cloudPtr=..., trans=...)
    at /home/fpolido/drc_workspace/src/trajopt/drc_traj/src/atlas_traj.cpp:597
#10 0x000000000043537a in ConvexDecompLoop ()
    at /home/fpolido/drc_workspace/src/trajopt/ros_interface/src/TrajOptNode.cpp:62
#11 0x000000000044a263 in boost::detail::thread_data<void (*)()>::run (this=0x904f540)
    at /usr/include/boost/thread/detail/thread.hpp:61
#12 0x00007ffff7020ce9 in thread_proxy () from /usr/lib/libboost_thread.so.1.46.1
#13 0x00007ffff6dfee9a in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0
#14 0x00007fffed5c131d in clone () from /lib/x86_64-linux-gnu/libc.so.6
#15 0x0000000000000000 in ?? ()

Line 1101 is the IF statement below:

int vtkQuadricDecimation2::CollapseEdge(vtkIdType pt0Id, vtkIdType pt1Id) 
{
  int j, numDeleted=0;
  vtkIdType i, npts, *pts, cellId;

  this->Mesh->GetPointCells(pt0Id, this->CollapseCellIds);
  for (i = 0; i < this->CollapseCellIds->GetNumberOfIds(); i++) 
    {
    cellId = this->CollapseCellIds->GetId(i);
    this->Mesh->GetCellPoints(cellId, npts, pts);
    for (j = 0; j < 3; j++) 
      {
      if (pts[j] == pt1Id) 
        {
        this->Mesh->RemoveCellReference(cellId);
        this->Mesh->DeleteCell(cellId);       
        numDeleted++;
        }
      }
    }

I narrowed down to the pts[j] variable returning an Invalid Pointer. So as a quick "hack solution" I wrapped the for loop with an if statement that checks for the pointer validity:

if(NULL !=pts) 
{
for (j = 0; j < 3; j++) 
  {
  if (pts[j] == pt1Id) 
    {
    this->Mesh->RemoveCellReference(cellId);
    this->Mesh->DeleteCell(cellId);       
    numDeleted++;
    }
  }
}
}

This "solved" the problem for me, but it doesn't actually tackle why this->Mesh->GetCellPoints is never initializing the pointer on some edge case.

Best,

Felipe

@taketwo

This comment has been minimized.

Show comment
Hide comment
@taketwo

taketwo Oct 22, 2014

Member

So this is a bug on vtk side, not ours?

Member

taketwo commented Oct 22, 2014

So this is a bug on vtk side, not ours?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment