Skip to content

fix probe filter when using computed tolerance

Ken Martin requested to merge ken-martin/vtk:probe_filter_fix into master

Raphaël Bresson identified two issues with probing in VTK. First there was an issue where when using a computed tolerance it was using MAX_DOUBLE to lookup bins in the locator. But the code that converts an XYZ to a bin overflows on MAX_DOUBLE causing incorrect results. Specifically

void GetBucketIndices(const double *x, int ijk[3]) const

which happens when you pass to it a coordinate vector x with values VTK_DOUBLE_MAX as argument in that case the static_cast from double to vtkIdType overflows causes incorrrect results.

void GetBucketIndices(const double *x, int ijk[3]) const

which happens when you pass to it a coordinate vector x with values ~VTK_DOUBLE_MAX as argument in that case the static_cast from double to vtkIdType

(vtkIdType tmp0 = static_cast<vtkIdType>(((x[0] - this->BX) * this->FX)); and so on)

fails. This happens when using vtkProbeFilter in the following way. If we keep the default option ComputeTolerance to True Then the tolerance tol2 is set to VTK_MAX_DOUBLE in vtkProbeFilter.cxx Also In vtkPointSet.cxx, in

vtkIdType vtkPointSet::FindCell(double x[3], vtkCell *cell,
                                vtkGenericCell *gencell, vtkIdType cellId,
                                double tol2, int& subId, double pcoords[3],
                                double *weights)

tol2 which has the dimension of a surface is passed to R in

void vtkPointLocator::FindPointsWithinRadius(double R, const double x[3],
                                             vtkIdList *result)

where R is clearly a length. So sqrt(tol2) should be passed to R to be consistent here.

To fix this the computed tolerance should be something that makes sense in terms of the cell sizes. This topic uses a value computed from the first few cells to compute a reasonable tolerance. This along with fixing the length versus length2 issue solves some of the cell picking issues but one remains that requires falling back to a cell locator. Prior to this topic the approach used was based on finding the closest point to the probe point and then if needed walking cells up to some fixed limit to see if you find the cell containing the probe point. That approach has two main failure modes;

  • the mesh may not be connected at all in which case cell walking does not work.
  • the cell containing the probe point may be more than the walk limit away

Let's look at examples of these two cases. First the case where the cells are connected, but the closest point is too many cells away from the contained cell.

image

In this example the closest point (in black) is many cells away from the cell containing the probe point (in red). So the cell walking will fail as it exceeds the hardcoded limit. The second example is of a disconnected mesh.

image

In this example there are only two cells, not connected. The closest point is in the wrong cell and cell walking will go nowhere as the two cells are not connected.

To address these two cases this topic adds a final step where if the prior steps have not found a containing cell, a cell locator is constructed and used to see if it can find a containing cell.

Merge request reports