How to project points to Polydata?

Hello!!!

I’m using VTK 9.01 and Python 3.8.3 and I’m trying to probe point scalar values from a Polydata to a set of target Points.

The target Points lie close to, but not necessarily ON the cells in the polydata and this is causing the output of the vtkProbeFIlter to be patchy - many input points are missed (do not map to a cell) as.I can see by looking at the output vtkValidPointMask.

I have tried,

  1. disabling ComputeTolernace and using a very liberal tolerance
  2. using a CellLocator instead of a PointLocator
  3. tried various FindCellStrategies

but I’m still not getting good results.

So my next strategy is to project the target points onto the Polydata, and probe the projected points. Projecting a set of points onto a PolyDtata seems like something that should have a filter in VTK, but I can’t find one.

So I’ll either have to iterate over every target point using vtkCellLocator.FindClosestPoint() or calculate a normal for every taget point and then use vtkCellLocator.IntersectWithLine()

So I have two questions,

  1. Is there an exitsing filter that can project points to PolyData? (and if so, what’s it called?)
  2. If there is no exitsing filter, are there any other approaches other than the two I outlined above that might work?

Thanks in advance,

Doug

I’m curious, can you give us an idea of how far away the points are from the polydata surface (in both relative (to the size of the polydata cells) and absolute) distance?

Projection is tricky depending on whether you are trying to control the projection direction, or simply trying to find the closest point. If you are simply looking for the closest point, then either a point locator (find closest point) or cell locator (find closest cell) should work. Also, unless you are incrementally modifying the polydata surface as you perform your operations, I suggest you use vtkStaticCellLocator / vtkStaticPointLocator (with threading enabled typically TBB) which are much faster.

Thanks for the reply Will.
In fact only part of this probem turned out to be the the target points not being close enough to the source cells - the real probelm is that the source cells in this case are polygons with more than four edges - and it appears that vtkProbeFilter just doesn’t support this cell topology.

I partially solved the problem using vtkDataSetTriangleFilter to convert these cells to triangles,

But I’m still not fully happy with the result. (This is a validPointMask plot

The source and target are different meshes on the same cylndrical shape - so the deviation betwen the two is really quite small - basically proportional to the chord/arc sagitta. The cylinder diameter here is 130mm and the target mesh cell size is around 10mm

It gets better if I assign a 5mm tolerance (although I would have expected this to map EVERY point)

But I didn’t have much success with the cellLocator

probe = vtk.vtkProbeFilter()
probe.SetComputeTolerance(False)
probe.SetTolerance(5.0)
locator = vtk.vtkCellLocator()
probe.SetCellLocatorPrototype(locator)

Here are the files I’m using
from_mesh.vtp (1.1 MB) to_mesh.vtp (111.2 KB) triangular_source.vtp (1.3 MB)

Any my testbed Python code

test_project.py (2.9 KB)

Thanks for the data and test script. I will definitely look into this… it’ll likely be next week.

Thanks - I look forward to any guidance you can give

I have used the projection approach for this. You can create a new target by raycasting each point of the target (in the positive and negative direction of its point normal) onto the source mesh. Then the data can be sampled at the new mesh points using vtkResampleWithDatset.

For large target meshes, VTK raycasting may be slow. Intel’s Embree library can be used to accelerate that step. As it appears you are using Python, I suggest using PyVista which already has support for Embree ready casting.

https://docs.pyvista.org/core/filters.html?highlight=multi_ray_trace#pyvista.PolyDataFilters.multi_ray_trace