# vtkStaticCellLocator problem (vtk9.0.3)

**URL:** <https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854>\
**Category:** Development\
**Created:** [February 16, 2022, 5:40pm UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854 "2022-02-16T17:40:59Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![marcomusy](https://discourse.vtk.org/user_avatar/discourse.vtk.org/marcomusy/32/95_2.png) [@marcomusy](https://discourse.vtk.org/u/marcomusy)\
**Post date:** [February 16, 2022, 5:40pm UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/1 "2022-02-16T17:40:59Z")

</div>

I observe something strange in `vtkStaticCellLocator.FindClosestPoint()` vs `vtkCellLocator.FindClosestPoint()`:

with vtkStaticCellLocator (wrong):

 ![Screenshot from 2022-02-16 18-10-06](https://discourse.vtk.org/uploads/default/original/2X/d/d7c96245ee609de7302460e5fa01bebfde0b8482.png)

with vtkCellLocator (correct):

 ![Screenshot from 2022-02-16 18-10-20](https://discourse.vtk.org/uploads/default/original/2X/f/f5b69310501e73d949179f547eed10ae1b18598a.png)

```python
from vedo import *

# Load and cut mouse limb mesh
limb = Mesh("https://vedo.embl.es/examples/data/270_flank.vtk")
limb.alpha(0.3).c("purple9").lighting("off")

# Make a wall in the cut limb to show gradient
grid = Grid(sx=2000, sy=2000, resx=50, resy=50).rotateX(90)
grid.cutWithMesh(limb).wireframe(False)

# scaling things makes no difference
#limb.scale(0.001)
#grid.scale(0.001)

values = []
for p in grid.points():
    q = limb.closestPoint(p)
    values.append(mag(p-q))
grid.cmap("viridis_r", values).addScalarBar()

show(limb, grid, viewup='z', axes=1)

```

The range is also very different.  
The name of the two classes is literally the only thing I change between the two… Any ideas?

---

<div class="post-metadata">

**Author:** ![Yohann\_Bearzi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/yohann_bearzi/32/671_2.png) [@Yohann\_Bearzi](https://discourse.vtk.org/u/Yohann_Bearzi)\
**Post date:** [February 16, 2022, 5:56pm UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/2 "2022-02-16T17:56:15Z")

</div>

This seems to be a bug. What happens if you run the same script but replace `vtkStaticCellLocator` by `vtkStaticPointLocator`?

---

<div class="post-metadata">

**Author:** ![will.schroeder](https://discourse.vtk.org/user_avatar/discourse.vtk.org/will.schroeder/32/233_2.png) [@will.schroeder](https://discourse.vtk.org/u/will.schroeder)\
**Post date:** [February 16, 2022, 6:01pm UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/3 "2022-02-16T18:01:27Z")

</div>

The behavior of the two classes should be the same. Could you create an equivalent VTK python script…

---

<div class="post-metadata">

**Author:** ![marcomusy](https://discourse.vtk.org/user_avatar/discourse.vtk.org/marcomusy/32/95_2.png) [@marcomusy](https://discourse.vtk.org/u/marcomusy)\
**Post date:** [February 16, 2022, 6:55pm UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/4 "2022-02-16T18:55:39Z")

</div>

…unless i’m doing something silly…:

```python
import vtk
from vedo import Mesh, Grid, mag, show

# load the data as VTK objs
limb = Mesh("https://vedo.embl.es/examples/data/270_flank.vtk")
lpoints = limb.points() # numpy array
limb = limb.polydata() # vtkPolyData
grid = Grid(sx=2000, sy=2000, resx=50, resy=50)
gpoints = grid.points() # numpy array
grid = grid.polydata() # vtkPolyData

locator1 = vtk.vtkCellLocator()
locator1.SetDataSet(limb)
locator1.BuildLocator()

locator2 = vtk.vtkStaticCellLocator()
locator2.SetDataSet(limb)
locator2.BuildLocator()

locator3 = vtk.vtkPointLocator()
locator3.SetDataSet(limb)
locator3.BuildLocator()

locator4 = vtk.vtkStaticPointLocator()
locator4.SetDataSet(limb)
locator4.BuildLocator()

values1 = []
values2 = []
values3 = []
values4 = []
for p in gpoints:
    q = [0, 0, 0]
    cid = vtk.mutable(0)
    dist2 = vtk.mutable(0)
    subid = vtk.mutable(0)
    locator1.FindClosestPoint(p, q, cid, subid, dist2)
    values1.append(mag(p-q))

    q = [0, 0, 0]
    cid = vtk.mutable(0)
    dist2 = vtk.mutable(0)
    subid = vtk.mutable(0)
    locator2.FindClosestPoint(p, q, cid, subid, dist2)
    values2.append(mag(p-q))

    id3 = locator3.FindClosestPoint(p)
    values3.append(mag(p-lpoints[id3]))

    id4 = locator4.FindClosestPoint(p)
    values4.append(mag(p-lpoints[id3]))

print(max(values1), max(values2)) # should be the same
print(max(values3), max(values4)) # should be the same (and they are)

# show(Mesh(grid).cmap("jet", values2))

```

outputs:

```auto
795.8835103198636 993.0246205222754
795.8835103198636 795.8835103198636

```

![Screenshot from 2022-02-16 19-39-49](https://discourse.vtk.org/uploads/default/original/2X/f/f428d6fa83c3ece4906e256ed782b477d869e5fa.png) ![Screenshot from 2022-02-16 19-39-34](https://discourse.vtk.org/uploads/default/original/2X/1/13c00a93e3849fdba9185c7ef77e2ab861e10fa1.png)

---

<div class="post-metadata">

**Author:** ![Yohann\_Bearzi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/yohann_bearzi/32/671_2.png) [@Yohann\_Bearzi](https://discourse.vtk.org/u/Yohann_Bearzi)\
**Post date:** [February 16, 2022, 7:07pm UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/5 "2022-02-16T19:07:48Z")

</div>

I just run this script in ParaView master and I do get the correct max values. What version of VTK are you using?

---

<div class="post-metadata">

**Author:** ![marcomusy](https://discourse.vtk.org/user_avatar/discourse.vtk.org/marcomusy/32/95_2.png) [@marcomusy](https://discourse.vtk.org/u/marcomusy)\
**Post date:** [February 16, 2022, 7:09pm UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/6 "2022-02-16T19:09:05Z")

</div>

it’s  
vtk version : 9.0.3  
python version : 3.8.8 (default, Apr 13 2021, 19:58:26) [GCC 7.3.0]  
python interpreter: /home/musy/soft/anaconda3/bin/python  
system : Linux 5.4.0-99-generic posix x86\_64

---

<div class="post-metadata">

**Author:** ![will.schroeder](https://discourse.vtk.org/user_avatar/discourse.vtk.org/will.schroeder/32/233_2.png) [@will.schroeder](https://discourse.vtk.org/u/will.schroeder)\
**Post date:** [February 16, 2022, 7:12pm UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/7 "2022-02-16T19:12:51Z")

</div>

There was a bug fix made to vtkStaticCellLocator related to FindClosestPoint (commit 2b07d64ea made about a year ago…)

---

<div class="post-metadata">

**Author:** ![Yohann\_Bearzi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/yohann_bearzi/32/671_2.png) [@Yohann\_Bearzi](https://discourse.vtk.org/u/Yohann_Bearzi)\
**Post date:** [February 16, 2022, 7:21pm UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/8 "2022-02-16T19:21:56Z")

</div>

Yep, you should update to VTK 9.1.0 to have this fixed.

---

<div class="post-metadata">

**Author:** ![Jens\_Munk\_Hansen](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jens_munk_hansen/32/1215_2.png) [@Jens\_Munk\_Hansen](https://discourse.vtk.org/u/Jens_Munk_Hansen)\
**Post date:** [March 16, 2023, 3:50pm UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/9 "2023-03-16T15:50:15Z")

</div>

I stumbled upon the same issue, when replacing the vtkCellLocator of vtkImplicitPolyDataDistance with the vtkStaticCellLocator to get some extra performance. Is there a reason why the vtkStaticCellLocator is not used as the default in vtkImplicitPolyDataDistance. My experience is that neither vtkCellLocator or vtkStaticCellLocator are thread-safe. Would it be an idea to introduce thread\_local into the hierarchy of class for vtkStaticCellLocator to make it thread-safe? Making it thread-safe would make it possible to use vtkSMPTools are bit more widely, e.g. for the vtkPolyDataDistanceFilter?

---

<div class="post-metadata">

**Author:** ![will.schroeder](https://discourse.vtk.org/user_avatar/discourse.vtk.org/will.schroeder/32/233_2.png) [@will.schroeder](https://discourse.vtk.org/u/will.schroeder)\
**Post date:** [March 17, 2023, 11:09am UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/10 "2023-03-17T11:09:22Z")

</div>

> > Is there a reason why the vtkStaticCellLocator is not used as the default in vtkImplicitPolyDataDistance

Probably because vtkStaticCellLocator was added after vtkImplicitPolyDataDistance, and vtkImplicitPolyDataDistance was never updated.

vtkStaticCellLocator should be thread safe (once built). There is an outstanding issue for a potential race condition that needs tracking down, maybe this is biting you?

---

<div class="post-metadata">

**Author:** ![Jens\_Munk\_Hansen](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jens_munk_hansen/32/1215_2.png) [@Jens\_Munk\_Hansen](https://discourse.vtk.org/u/Jens_Munk_Hansen)\
**Post date:** [March 17, 2023, 4:28pm UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/11 "2023-03-17T16:28:37Z")

</div>

Thanks. I get some weird indices but I am also not waiting for the locators to build. I build a separate locator for each thread in the Initialize function using vtkSMPTools. But I guess from the name, vtkStaticCellLocator, this obviously goes wrong.

I will wait for a single locator to build and use it across multiple threads. I am sure this should work.

If I track down and locate a data race, I will ensure to communicate it such that errors are fixed. Thanks for replying

Jens

---

<div class="post-metadata">

**Author:** ![will.schroeder](https://discourse.vtk.org/user_avatar/discourse.vtk.org/will.schroeder/32/233_2.png) [@will.schroeder](https://discourse.vtk.org/u/will.schroeder)\
**Post date:** [March 17, 2023, 5:18pm UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/12 "2023-03-17T17:18:37Z")

</div>

Generally what I’ve done is build the locator prior to the parallel for. Mostly because the locators can chew up a lot of memory, and can take some time to build, so I minimize these by using just the one instance.

The [race](https://gitlab.kitware.com/vtk/vtk/-/issues/18842#note_1330743) is reported by Sean who is (rightfully) bugging me 🙂

---

<div class="post-metadata">

**Author:** ![Jens\_Munk\_Hansen](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jens_munk_hansen/32/1215_2.png) [@Jens\_Munk\_Hansen](https://discourse.vtk.org/u/Jens_Munk_Hansen)\
**Post date:** [March 17, 2023, 5:20pm UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/13 "2023-03-17T17:20:52Z")

</div>

Exactly what I am doing now and things are looking pretty fast here - more memory efficient than what I did before.

What I did before, which most likely triggers the data race was the following.

Replace `vtkCellLocator` with `vtkStaticCellLocator` in `vtkImplicitPolyDataDistance` and use the functor below.

```auto
class MyOp
{
private:
  vtkSMPThreadLocalObject<vtkImplicitPolyDataDistance> Imp;
  vtkSpsDisplacementPolyDataFilter* Self;
  vtkDoubleArray* OutputScalar;
  vtkDoubleArray* OutputVector;
  vtkPolyData* Src;
  vtkPolyData* Dst;
public:
  MyOp(vtkDisplacementPolyDataFilter* self,
       vtkImplicitPolyDataDistance* src, vtkPolyData* dst,
       vtkDoubleArray* outputScalar,
       vtkDoubleArray* outputVector) :
    Self(self), Src(src), Dst(dst),
    OutputScalar(outputScalar), OutputVector(outputVector)
  {
    
  }
  void Initialize()
  {
    // Weird things happen
    vtkSpsImplicitPolyDataDistance*& imp = this->Imp.Local();
    imp->SetInput(this->Src);
  }
  void operator()(vtkIdType begin, vtkIdType end)
  {
    vtkImplicitPolyDataDistance*& imp = this->Imp.Local();
    for (vtkIdType ptId = begin; ptId < end; ptId++) {
      double pt[3];
      this->Dst->GetPoint(ptId, pt);
    
      double closestPoint[3];
      double val = imp->EvaluateFunctionAndGetClosestPoint(pt, closestPoint);
      double dist = Self->SignedDistance ? (Self->NegateDistance ? -val : val) : fabs(val);
      double direction[3];
      double absDistance = 0.0;
      for (int i = 0 ; i < 3 ; i++) {
        direction[i] = closestPoint[i] - pt[i];
      }
      absDistance = std::max<double>(1e-6, fabs(dist));

      // Normalize direction
      for (int i = 0 ; i < 3 ; i++) {
        direction[i] /= absDistance;
      }
      
      OutputVector->SetTuple(ptId, direction);
      OutputScalar->SetValue(ptId, dist);
    }
  }
  void Reduce() {
  }
};

```

I know that I can use the gradient which is faster than computing a new vector and normalizing it… Thanks again for reaching out.

---

<div class="post-metadata">

**Author:** ![levi](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/l/ce73a5/32.png) [@levi](https://discourse.vtk.org/u/levi)\
**Post date:** [May 13, 2023, 9:03am UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/14 "2023-05-13T09:03:14Z")

</div>

Hi, Jens

i have just replace `vtkCellLocator` with `vtkStaticCellLocator` in `vtkImplicitPolyDataDistance`, with nothing else.  
but the process is as slow as vtkCellLocator,  
i`m sure smp is supported since other classes with smp is quite fast  
am i missing something? what other change should i take?  
thanks

---

<div class="post-metadata">

**Author:** ![Jens\_Munk\_Hansen](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jens_munk_hansen/32/1215_2.png) [@Jens\_Munk\_Hansen](https://discourse.vtk.org/u/Jens_Munk_Hansen)\
**Post date:** [May 13, 2023, 10:22am UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/15 "2023-05-13T10:22:19Z")

</div>

I have replaced vtkCellLocator and introduced vtkSMP. It made it 2 orders of magnitude faster. Below is a snippet from a new vtkDisplacementFilter, where both distance and directions are computed in parallell.

```auto
namespace
{
class DisplacementOp
{
private:
  vtkDisplacementPolyDataFilter* Self;
  vtkDoubleArray* OutputScalar;
  vtkDoubleArray* OutputVector;
  vtkImplicitPolyDataDistance* Imp;
  vtkPolyData* Dst;

public:
  DisplacementOp(vtkDisplacementPolyDataFilter* self, vtkImplicitPolyDataDistance* imp,
                 vtkPolyData* dst, vtkDoubleArray* outputScalar, vtkDoubleArray* outputVector)
    : Self(self)
    , Imp(imp)
    , Dst(dst)
    , OutputScalar(outputScalar)
    , OutputVector(outputVector) {}
  void Initialize() {}
  void operator()(vtkIdType begin, vtkIdType end)
  {
    vtkImplicitPolyDataDistance* imp = this->Imp;
    vtkTypeBool signedDistance = Self->GetSignedDistance();
    vtkTypeBool negateDistance = Self->GetNegateDistance();
    for (vtkIdType ptId = begin; ptId < end; ptId++)
      {
        double pt[3];
        Dst->GetPoint(ptId, pt);

        double closestPoint[3];
        double val = imp->EvaluateFunctionAndGetClosestPoint(pt, closestPoint);
        double dist = signedDistance
           ? (negateDistance ? -val : val) : fabs(val);
        double direction[3];
        double absDistance = 0.0;
        for (int i = 0; i < 3; i++)
          {
            direction[i] = closestPoint[i] - pt[i];
          }
        absDistance = std::max<double>(1e-6, fabs(dist));

        // Normalize direction
        for (int i = 0; i < 3; i++)
          {
            direction[i] /= absDistance;
          }

        OutputVector->SetTuple(ptId, direction);
        OutputScalar->SetValue(ptId, dist);
      }
  }
  void Reduce() {}
};

```

and to execute it

```auto
  vtkImplicitPolyDataDistance* imp = vtkImplicitPolyDataDistance::New();
  imp->SetInput(src);

  // Calculate distance from points.
  int numPts = mesh->GetNumberOfPoints();

  vtkDoubleArray* directionArray = vtkDoubleArray::New();
  directionArray->SetName("Direction");
  directionArray->SetNumberOfComponents(3);
  directionArray->SetNumberOfTuples(numPts);

  vtkDoubleArray* distanceArray = vtkDoubleArray::New();
  distanceArray->SetName("Distance");
  distanceArray->SetNumberOfComponents(1);
  distanceArray->SetNumberOfTuples(numPts);

  // The sign of the functions are the dot product between pseudo normal and the vector
  // x-p. The point p is on the target polydata.
  DisplacementOp pointFunctor(this, imp, mesh, distanceArray, directionArray);
  vtkSMPTools::For(0, numPts, pointFunctor);

```

---

<div class="post-metadata">

**Author:** ![levi](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/l/ce73a5/32.png) [@levi](https://discourse.vtk.org/u/levi)\
**Post date:** [May 15, 2023, 9:05am UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/16 "2023-05-15T09:05:48Z")

</div>

Hi Jens  
thanks for your reply, i have changed vtkDistancePolyDataFilter like yours and it works.  
though the time is just reduced about 75%(i will continue optimize it).

with vtk 9.1, i have some error result in vtkStaticCellLoacator, i’ll have some check

by the way, i found your commit in vtk for [https://gitlab.kitware.com/vtk/vtk/-/commit/90cf6e9cd3876bf7423af7f4ed00df3ce620ef21](https://gitlab.kitware.com/vtk/vtk/-/commit/90cf6e9cd3876bf7423af7f4ed00df3ce620ef21)  
👍

---

<div class="post-metadata">

**Author:** ![Jens\_Munk\_Hansen](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jens_munk_hansen/32/1215_2.png) [@Jens\_Munk\_Hansen](https://discourse.vtk.org/u/Jens_Munk_Hansen)\
**Post date:** [May 15, 2023, 9:53pm UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/17 "2023-05-15T21:53:17Z")

</div>

I got a factor of around 70 but in addition to the commit you mentioned, I replaced the `vtkCellLocator` with `vtkStaticCellLocator`. Also remember to enable `vtkSMPTools`. I usually use TBB.

---

<div class="post-metadata">

**Author:** ![levi](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/l/ce73a5/32.png) [@levi](https://discourse.vtk.org/u/levi)\
**Post date:** [May 16, 2023, 1:16am UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/18 "2023-05-16T01:16:56Z")

</div>

got it  
by now i just use OpenMP, maybe i should test against TBB

---

<div class="post-metadata">

**Author:** ![Jens\_Munk\_Hansen](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jens_munk_hansen/32/1215_2.png) [@Jens\_Munk\_Hansen](https://discourse.vtk.org/u/Jens_Munk_Hansen)\
**Post date:** [May 16, 2023, 3:05pm UTC](https://discourse.vtk.org/t/vtkstaticcelllocator-problem-vtk9-0-3/7854/19 "2023-05-16T15:05:37Z")

</div>

or even just STDThread.
