import Rhino
import rhinoscriptsyntax as rs
import scriptcontext
from System.Drawing import Color
import random as rnd
import time
"""--------------------------------------------------------
PERFORMANCE TEST - RTREE CLASS RHINOCOMMON
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__":
RunSearch()
Update