Find maximum/minimum value in the neighbourhood of point

Dear all,

I would have a list of points that belong to different planes, what I need to do is to find local minima/maxima of various properties around these specific points. I know that maxima and minima can be found also in pvpython, is there a way to get only maxima and minima in the surroundings (eg. within a radius) of a point automatically?

Edit:
I found something that looks quite promising:


But I need to automate that in pvpython

Thank you in advance

Hi,

I think you can achieve what you want to do by using vtkStaticPointLocator’s FindPointsWithinRadius() function within a Programmable Filter.
https://docs.paraview.org/en/latest/ReferenceManual/pythonProgrammableFilter.html

Below is an example of using FindPointsWithinRadius() in vtk, which is a little different from the Programmable Filter syntax, but should not be too difficult to translate.

import vtk
from vtk.util.numpy_support import numpy_to_vtk
import numpy as np
import time

# create hexahedron cells
source = vtk.vtkCellTypeSource()
source.SetCellType(vtk.VTK_HEXAHEDRON)
source.SetBlocksDimensions(10, 10, 10)
source.Update()

source_writer = vtk.vtkXMLUnstructuredGridWriter()
source_writer.SetFileName('source.vtu')
source_writer.SetInputConnection(source.GetOutputPort())
source_writer.Write()

# Initialize the locator
locator = vtk.vtkStaticPointLocator()
locator.SetDataSet(source.GetOutput())
locator.BuildLocator()

# Create a point cloud
n = 8000
r = 5.0
p_source = vtk.vtkPointSource()
p_source.SetNumberOfPoints(n)
p_source.SetCenter(5, 5, 5)
p_source.SetRadius(r)
p_source.Update()
seeds = p_source.GetOutput()

scalars = source.GetOutput().GetPointData().GetArray('DistanceToCenter')

# Start measuring the time
time_start = time.time()

# Find the maximum and minimum scalar values within the search radius
search_r = 3.0
max_scalars = []
min_scalars = []
nei_ids = vtk.vtkIdList()
for i in range(seeds.GetNumberOfPoints()):
    point = seeds.GetPoint(i)
    locator.FindPointsWithinRadius(search_r, point, nei_ids)

    nei_scalars = []
    for j in range(nei_ids.GetNumberOfIds()):
        id = nei_ids.GetId(j)
        nei_scalars.append(scalars.GetTuple1(id))

    max_scalar = max(nei_scalars)
    min_scalar = min(nei_scalars)

    max_scalars.append(max_scalar)
    min_scalars.append(min_scalar)

# Add and output an array of maximum and minimum values, respectively
vtk_max_scalars = numpy_to_vtk(num_array=np.array(max_scalars), deep=True, array_type=vtk.VTK_FLOAT)
vtk_max_scalars.SetName('max_scalars')
seeds.GetPointData().AddArray(vtk_max_scalars)

vtk_min_scalars = numpy_to_vtk(num_array=np.array(min_scalars), deep=True, array_type=vtk.VTK_FLOAT)
vtk_min_scalars.SetName('min_scalars')
seeds.GetPointData().AddArray(vtk_min_scalars)

time_end = time.time()
print(f'Search elapsed time for maximum and minimum values: {time_end - time_start} sec')

writer = vtk.vtkXMLPolyDataWriter()
writer.SetFileName('seeds.vtp')
writer.SetInputData(seeds)
writer.Write()
2 Likes

Thanks a lot this solved my issue!