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.
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.