import Rhino
import rhinoscriptsyntax as rs
import scriptcontext
from System.Drawing import Color
import random as rnd
import time
Repeated Search To Find Closest Neighbor
Search Sample = 1 Million Points
Search Radius = 500 Units
Search Space = Cube (5000,5000,5000)
class SearchData:
    def __init__(self, pts, point):
        #Search Data class set up for instancing repeaded searching and tracking
        self.HitCount = 0 #amount of times we searched starts with 0
        self.arrPts = pts
        self.Point = point
        self.Index = -1 #insuring that we reduce the search radius after the first pass, see the conditional in searchcallback
        self.Distance = 0
        self.count = 0
def SearchCallback(sender, e):
    data = e.Tag
    data.HitCount += 1 #incrementing the hitcount
    vertex = data.arrPts[e.Id] #the current closest neighbor
    distance = data.Point.DistanceTo(vertex) #distance to the current closest neighbor from the query loc to define new search radius
    if data.Index == -1 or data.Distance > distance: #condition to resize the search sphere to optimize the searching
        e.SearchSphere = Rhino.Geometry.Sphere(data.Point, distance) #resize the search sphere
        data.Index = e.Id #update the data.index to current point ID
        data.Distance = distance #update the data.distance to the current distance
def RunSearch():
    pttimeStart = time.time() #Start Timer
    point = Rhino.Geometry.Point3d(5000/2,5000/2,5000/2)
    intNumPts = 1000000 #specify the number of sample points to search 
    pts = []
    tree = Rhino.Geometry.RTree() #create a new instance of the rtree class
    for x in range(0,intNumPts):
        randomPt = Rhino.Geometry.Point3d(rnd.random()*50000,rnd.random()*50000,rnd.random()*50000) #randomly place each point inside the 5k x 5k x 5k cube
        pts.append(randomPt) #add the current point to the end of the pts list
        tree.Insert(randomPt,x) #insert the current random point in the RTree at the specified index (x)
    pttimeEnd = time.time() #end the timer
    print "time taken to create pts: {}".format(pttimeEnd - pttimeStart) #print amount of time it took for calculations
    print "TreeCount = {}".format(tree.Count) #count of the amount of items in the tree
    timeStart = time.time() #Start Timer
    data = SearchData(pts, point) #Create an instance of the Search Data Class passing sample list, query loc
    sphere = Rhino.Geometry.Sphere(point, 500) #specify the inital search sphere size
    if tree.Search(sphere, SearchCallback, data): #call the search method from the Rtree Class 
        print "Found point in {0} tests".format(data.HitCount) #print the amount of search iterations we did
        print "ClosestPt = {}".format(data.arrPts[data.Index]) #print the closest neighbor
    timeEnd = time.time() #end the timer
    print "time taken: {}".format(timeEnd - timeStart) #print amount of time it took for calculations
if __name__=="__main__":
  • Share