Can I delete an entry from a KD Tree?

I’m sorting locations of a mesh using mathutils.kdtree and wondering if there’s a way to drop entries. IE. An element of my KD tree might be the closest to more than one thing I search for, so I want it only to apply to the first.

I could build a list of ‘used’ elements and then use kd.find_n and check the results against the ‘used list’ but two immediate drawbacks are:

  • This is going to slow me down a lot as the list gets long
  • it’s possible that I’ll need a larger and larger n and A. that will slow me down generally and B. I don’t have a great way to predict how it will grow anyway.

Any advice?

EDIT: I see that there’s a filter option to use an “index” on kd.find, but I can’t seem to figure out what type to pass it for the index. Is the option available for kd.find_n? Doesn’t seem like it in the docs.

I’d suggest making a manual filter using a IF condition.
e.g.

for i, v in enumerate(bpy.context.object.data.vertices):
    if i != 8:
        kd.insert(v.co, i)

This is because Python, or at least Blender has a class called filter and is confusing that class with the function argument in `kd.find(co, filter). Personally, I can’t get the argument to work, whether with stating filter=value or without stating the argument and only inserting the value in the function itself. Maybe it’s a Blender API oversight? Not sure.

callable errors guide:

No, kd.find_n nor find_range have the filter argument. You can verify that by doing:

print(help(kd.find))
print(help(kd.find_n))
print(help(kd.find_range))

Only kd.filter should have that function argument… just unsure how to have the function accept values for that argument.

1 Like