Is it a bug in vtkMergePoint of Python?

I have a point set, and I want to insert new point which don’t duplication. So I used vtkMergePoints, but something went wrong, new point overwrite the exist point rather than added.
Code is follow:

## Initial point set and vtkMergePoints
points = vtkPoints()  # My point set
points.InsertNextPoint(0, 0, 0)
points.InsertNextPoint(1, 1, 1)
points.InsertNextPoint(2, 2, 2)

u_grid = vtkUnstructuredGrid()
u_grid.SetPoints(points)

merger = vtkMergePoints()  # Used to insert new point
merger.SetDataSet(u_grid)
merger.InitPointInsertion(u_grid.GetPoints(), u_grid.GetBounds())
merger.Update()

Try to insert exist point:

a = reference(999)
merger.InsertUniquePoint((0, 0, 0), a)
print(a)
print(merger.GetPoints().GetPoint(a))

The result is right:

0
(0.0, 0.0, 0.0)

But try to insert a point that don’t exitst:

b = reference(999)
merger.InsertUniquePoint((3, 3, 3), b)
print(b)
print(merger.GetPoints().GetPoint(b))

Something wrong occur:

0 # It should be 3!!! And the point (0, 0, 0) is overwrited
(3.0, 3.0, 3.0)

And try to print the exist points:

print(merger.GetPoints().GetPoint(0)) 
print(merger.GetPoints().GetPoint(1)) 
print(merger.GetPoints().GetPoint(2)) 

# result:
(3.0, 3.0, 3.0) # It should be (0, 0, 0)
(1.0, 1.0, 1.0)
(2.0, 2.0, 2.0)

Is the step of initialization used vtkUnstructuredGrid have question?
I have read the source code of C++, I think in Python, the function ‘InsertNextPoint’ not be called correctly in vtkMergePoints even in vtkPointLocator.

For a merging point locator, when you call InitPointInsertion(points, bounds), the points must be empty.

VTK expects you to add all the points to this locator with InsertUniquePoint(). If you call InsertNextPoint(), even if you do it before InitPointInsertion(), then the internal data structure of vtkMergePoints will be corrupted.

If I want to initialize a vtkMerger to manage the vtkpoints of vtkUnstructuredGrid, than insert points dynamicly, Is it correct to use the following method?

points = vtkPoints()
u_grid = vtkUnstructuredGrid()
u_grid.SetPoints(points)

merger = vtkMergePoints()

# Are two of follow methods all necessary?
u_grid.SetPointLocator(merger)
merger.SetDataSet(u_grid)

merger.InitPointInsertion(u_grid.GetPoints(), u_grid.GetBounds())
merger.Update()

... # some code

# Insert new point
# Is it have another pythonic method? vtkUnstructureGrid.InsertUniquePoint() ^_^
temp_merger = u_grid.GetPointLocator()
a = reference(0)
temp_merger.InsertUniquePoint((0, 0, 0), a)

I think the problem is your use of u_grid.GetBounds() for InitPointInsertion(points, bounds).

The VTK documentation says:

bounds represents the spatial bounding box, into which the points fall.

So be sure the bounds are large enough. It’s okay to use an estimate of the bounds, as long as you know that none of the points that you add will be outside the bounds.

# Are two of follow methods all necessary?
u_grid.SetPointLocator(merger)
merger.SetDataSet(u_grid)

SetPointLocator() is not necessary, but it is convenient to be able to use u_grid.GetPointLocator().

SetDataSet(u_grid) is needed for some locators, but it is not needed for vtkMergePoints.

# Is it have another pythonic method? vtkUnstructureGrid.InsertUniquePoint()

No, there is no such method. One of the reasons is that the grid’s PointLocator is not always vtkMergePoints, so the locator itself might not have an InsertUniquePoint() method. Or the grid might not have any locator at all.

1 Like