RTree howto?

Could anyone come up with a simpler example than the one used here:
https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Geometry_RTree__ctor.htm

I don’t use meshes at all and I cannot fully understand what the callback does.

in the SearchData class, is the mesh input supposed to contain the point input?

using callback as an argument in a method is very confusing. Who is supposed to be the “sender” and the “eventArgs” object in that case?

Hi @ivelin.peychev

This is the simplest example I could come up with:
rtree_python.gh (6.1 KB)

I’ll have to leave the answers to your questions for smarter people.

Hope it helps

-David

3 Likes

Thank you @DavidLeon,

About creating the RTree from the list of points without looping through each point in the list: I read in the documentation as comment in the examples it’s not yet in RhinoCommon. Is there a plan for this to be included in, at least, the WIP?

https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_Geometry_RTree.htm

I’m talking about this part:

creating the RTree directly by inputting a list rather than looping through each point.

FYI: I found a bug or limitation:

Something like this doesn’t work?

https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Geometry_RTree_CreateFromPointArray.htm

(I know next to nothing about this honestly)

2 Likes

Huh, I did not see this :blush:

The good about not understanding how RTree works is that it lead me to implementing CPython and numpy ran from standard GhPython component :smiley: Respectively implementing the algorithm with numpy.

You can do that, just translate in python:

@menno is is possible to give different radius for each point?
while executing this line:
IEnumerable<int[]> found = RTree.Point3dClosestPoints(pointsToSearchFrom, needles, dist);

    public static List<Point3d> RTreeSearch(List<Point3d> pointsToSearchFrom, List<Point3d> needles, double dist, ref object A) {

        //If not empty
        if (pointsToSearchFrom.Count == 0 || needles.Count == 0)
            return new List<Point3d>();

        //Search
        IEnumerable<int[]> found = RTree.Point3dClosestPoints(pointsToSearchFrom, needles, dist);

        List<Point3d> result = new List<Point3d>();

        foreach (var item in found) {
            int[] data = item;
            for (int j = 0; j < data.Length; ++j)
                result.Add(pointsToSearchFrom[data[j]]);
        }

        return result;
    }
1 Like

@ivelin.peychev that’s just a display artefact. If you touch the preview component, you’ll see that it’s working fine.

1 Like

I see, thanks.

Interesting :slight_smile:

I this case it would be very slow, once you have millions of points and large number of needles, because you are rebuilding rtree each time.

Ok got it, once you change to list, and change the code for the arrays , the rtee is not rebuilt

1 Like

Hi Ivelin,
do you have the code with serchPoint as a list input?
It would be super appreciate if you can share :slight_smile:

Edit:
sorry. I was being dumb.

import Rhino.Geometry as rg

__author__ = "david.leon_Review_MP"
__version__ = "2020.03.19"


#build the tree
tree = rg.RTree()

#add the points to the tree
for i in range(len(pointList)):
    tree.Insert(pointList[i], i)

closestPoints = []
closestIndices = []

#event handler of type RTreeEventArgs
def SearchCallback(sender, e):
    closestPoints.Add(pointList[e.Id])
    closestIndices.Add(e.Id)

for item in searchPoint:
    tree.Search(rg.Sphere(item, radius), SearchCallback)

pts = closestPoints
ind = closestIndices