Rtree and nearest neighbour searches in general (c#)

NN searches in (indexed) Point sets are a tool i need all the time in Rhino. And over the years i found different ways to handle the problem.

E.g. as far as i can tell several mesh methods have acceleration structures build in, so it can be faster to build a semi-invalid mesh from a polyline to do closest point calculations on it. That was used for a isomesher that builds ‘blobmeshes’ around splines, where the fake mesh was magnitudes faster than native polyline NN methods.

External libraries are another - ‘Alglib’ works nicely, but you need the dll around, so its quite bad for distribution. (working with students, and also only c#-GH scripting components)

Now there is RTree, and i would use it, but why the callback? I am not an expert, but doesn’t that mean it runs async? I need a NN search in my loop that works now, and not maybe calls back in 20ms…

So my point / question is - am i missing something, and what is the best way to approach this? And can i use RTree without those callbacks?

I hope what i wrote makes sense and is not totally besides the point.
Thanks for reading!

Callback functions do not imply asynchronous execution:

In pseudo-code:
start search on rtree object from calling function rtree searches rtree calls your callback (here you would store, or do something with the results) rtree finishes search control is returned to your calling function

thanks! and i try to understand - why is this the only method i found in rhinocommon that has a callback?

edit: got it to work, and trying to understand the example - is the ‘tag’ field in the search meant to pass data around - so to get the results back to the caller method?

Yes, the tag field comes back in the RTreeEventArgs.Tag property.
For example, I needed to pass the index found by the RTree back to the caller. I used it like so:

int[] result = new int[1];
result[0] = -1;
if (tree.Search(pt, SearchCallback, result) && result[0] >= 0)
  int id = result[0]; // this was filled during the SearchCallback;

and my callback is:

private void SearchCallback(object sender, RTreeEventArgs args)
  int[] arr = args.Tag as int[];
  arr[0] = args.Id;