If I'm understanding your problem correctly, you may want to look at vtkCleanPolyData, with PointMergingOn and a given tolerance.
Removing point from cloud which are closer than threshold distance
-
16-03-2022 - |
Question
I am importing mesh file where each face is described by coordinates of its vertices. Most vertices are shared between points. Therefore, I would like to eliminate points which are closer than threshold
to a point which has been already added to the cloud. That means that I need to efficiently perform closest-point lookup and point insertion at the same time.
I try to use vtkPointLocator
which I've already used for static cloud; but I am at loss how is it supposed to be used incrementally. The documentation is quite terse, and examples (e.g. this one) don't cover this scenario. This post was somewhat helpful, but I still don't have a working solution - I get segfaults in InsertNextPoint
(the case below), infinite recursion in CheateChildNode
(when using vtkIncrementalOctreePointLocator
instead of vtkPointLocator
), or some VTK error (like no points to subdivide
, when there are zero points).
This is approximately what I do:
// read from input file
std::vector<Vector3d> vertices;
// bounds of the data are known
double bounds[6]={/*...*/};
const double threshold=1e-5;
auto locator=vtkSmartPointer<vtkIncrementalOctreePointLocator>::New();
auto polydata=vtkSmartPointer<vtkPolyData>::New();
auto points=vtkSmartPointer<vtkPoint>::New();
polydata->SetPoints(points);
locator->SetDataSet(polydata);
locator->InitPointInsertion(points,bounds);
for(size_t i=0; i< i<vertices.size(); i++){
double* vertex=vertices[i].data(); // pointer to data
double dist; // unused
vtkIdType id;
// don't search if there are no points yet
// FindClosestPointWithinRadius calls BuildLocator internally,
// which needs some points to be present already
if(points->GetNumberOfPoints()>0) id=locator->FindClosestPointWithinRadius(threshold,vertex,dist);
else id=-1;
if(id<0){
// point not found, insert it into the locator
locator->InsertNextPoint(vertex);
}
}
If there is an obvious error in the way the error is organized, I will be happy for any suggestion. If not, I try to make a MWE.
From reading the source, it seems even incremental classes call BuildLocator
at every lookup, if the pointset was modified, which might be expensive. A suggestion for a better class for combined insertion/lookup would be therefore also appreciated.
Solution