Locating the index of a value in a vtk (double) array

I have a vtkDoubleArray and want to find a value’s index (which I know exists) without converting my vtk array to the C++ array (and using std::find). Is it possible to do so? I tried LookupValue but it failed me. Here is an example of what I did: I have a polydata (inputPoly) and I want to find the maximum value in the array (my array has only 1 component), and change that value to -1.

while (condition){
    CalculateWeight(inputPoly); //This is a function to calculate some quantity I called weight
    double maxVal = inputPoly->GetPointData()->GetArray("Weights")->GetRange()[1];
    int maxId = inputPoly->GetPointData()->GetArray("Weights")->LookupValue(maxVal);
    inputPoly->GetPointData()->GetArray("Weights")->SetComponent(maxId, 0, -1.0);
    inputPoly->GetPointData()->GetArray("Weights")->Modified();
    inputPoly->Modified();
}

If you are working in python you can use numpy.where.

I’m trying to avoid creating new containers (such as NumPy in python or array in C++) to save memory space. I just wondering if vtk array has some sort of “find” or “where” method.

I don’t think there’s a where method on vtk data arrays. If you are in python a numpy wrapper of an array doen’t make a copy, so it’s lightweight compared to searching a big array.

You can use vtk array ranges (no copy is performed):

#include <vtkDataArrayRange.h>
#include <vtkDoubleArray.h>
#include <algorithm>

vtkDoubleArray* array = GetMyDoubleArraySomewhere();
double val = SomeValue();

auto range = vtk::DataArrayValueRange(array);
auto it = std::find(range.begin(), range.end(), val);

std::cout << "Found " << *it << " at index " << std::distance(range.begin(), it) << std::end;
2 Likes

This is exactly what I need, but I’m using vtk 8, which doesn’t have vtkDataArrayRange. By any chance, is there any workaround for vtk 8?

You could get the raw pointer using vtkDoubleArray::GetPointer(0), but this kind of pointer handling is not recommended with newer versions of VTK, as array ranges provide a better abstraction over all types of arrays. It will still work with newer versions of VTK though.

Yeah, I’m not comfortable with vtk raw pointer handling. Since I don’t have the option of upgrading to vtk 9, I guess I’m better off copying my vtk array to some stl container and finding the index. I prefer lousy resource management rather than touching raw vtk pointers. Anyhow, I’m going to accept your answer since it is the best solution for vtk 9 users.

Edit: Thank you for providing the answer for vtk 8 as well.

You can make it work without copying:

#include <vtkDoubleArray.h>
#include <algorithm>

vtkDoubleArray* array = GetMyDoubleArraySomewhere();
double val = SomeValue();

double* begin = array->GetPointer(0);
double* end = begin + array->GetNumberOfValues();
double* it = std::find(begin, end, val);

std::cout << "Found " << *it << " at index " << std::distance(begin, it) << std::end;
1 Like

Perfect! This is awesome, thank you very much!

I want to know why the method LookupValue failed。