usingRhino;usingRhino.Geometry;namespace examples_cs
{[System.Runtime.InteropServices.Guid("0E82E6DA-5335-453A-AC94-2499BBBCBE55")]publicclassRTreeClosestPoint:Rhino.Commands.Command{publicoverridestringEnglishName{get{return"cs_RtreeClosestPoint";}}voidSearchCallback(object sender,RTreeEventArgs e){SearchData data = e.TagasSearchData;if(data ==null)return;
data.HitCount= data.HitCount+1;Point3f vertex = data.Mesh.Vertices[e.Id];double distance = data.Point.DistanceTo(vertex);if(data.Index==-1|| data.Distance> distance){// shrink the sphere to help improve the test
e.SearchSphere=newSphere(data.Point, distance);
data.Index= e.Id;
data.Distance= distance;}}classSearchData{publicSearchData(Mesh mesh,Point3d point){Point= point;Mesh= mesh;HitCount=0;Index=-1;Distance=0;}publicintHitCount{get;set;}publicPoint3dPoint{get;privateset;}publicMeshMesh{get;privateset;}publicintIndex{get;set;}publicdoubleDistance{get;set;}}protectedoverrideRhino.Commands.ResultRunCommand(RhinoDoc doc,Rhino.Commands.RunMode mode){Rhino.DocObjects.ObjRef objref;var rc =Rhino.Input.RhinoGet.GetOneObject("select mesh",false,Rhino.DocObjects.ObjectType.Mesh,out objref);if(rc !=Rhino.Commands.Result.Success)return rc;Mesh mesh = objref.Mesh();
objref.Object().Select(false);
doc.Views.Redraw();using(RTree tree =newRTree()){for(int i =0; i < mesh.Vertices.Count; i++){// we can make a C++ function that just builds an rtree from the// vertices in one quick shot, but for now...
tree.Insert(mesh.Vertices[i], i);}while(true){Point3d point;
rc =Rhino.Input.RhinoGet.GetPoint("test point",false,out point);if(rc !=Rhino.Commands.Result.Success)break;SearchData data =newSearchData(mesh, point);// Use the first vertex in the mesh to define a start spheredouble distance = point.DistanceTo(mesh.Vertices[0]);Sphere sphere =newSphere(point, distance *1.1);if(tree.Search(sphere,SearchCallback, data)){
doc.Objects.AddPoint(mesh.Vertices[data.Index]);
doc.Views.Redraw();RhinoApp.WriteLine("Found point in {0} tests", data.HitCount);}}}returnRhino.Commands.Result.Success;}}}
importRhinoimport rhinoscriptsyntax as rs
# data passed to the RTree's SearchCallback function that# we can use for recording what is going onclassSearchData:def__init__(self, mesh, point):self.HitCount=0self.Mesh= mesh
self.Point= point
self.Index=-1self.Distance=0defSearchCallback(sender, e):
data = e.Tag
data.HitCount+=1
vertex = data.Mesh.Vertices[e.Id]
distance = data.Point.DistanceTo(vertex)if data.Index==-1or data.Distance> distance:# shrink the sphere to help improve the test
e.SearchSphere=Rhino.Geometry.Sphere(data.Point, distance)
data.Index= e.Id
data.Distance= distance
defRunSearch():
id = rs.GetObject("select mesh", rs.filter.mesh)
mesh = rs.coercemesh(id)if mesh:
rs.UnselectObject(id)
tree =Rhino.Geometry.RTree()# I can add a RhinoCommon function that just builds an rtree from the# vertices in one quick shot, but for now...for i,vertex inenumerate(mesh.Vertices): tree.Insert(vertex, i)while(True):
point = rs.GetPoint("test point")ifnot point:break
data =SearchData(mesh, point)# Use the first vertex in the mesh to define a start sphere
distance = point.DistanceTo(mesh.Vertices[0])
sphere =Rhino.Geometry.Sphere(point, distance *1.1)if tree.Search(sphere,SearchCallback, data):
rs.AddPoint(mesh.Vertices[data.Index])
print "Found point in {0} tests".format(data.HitCount)if __name__=="__main__":RunSearch()
ImportsRhinoImportsRhino.GeometryNamespace examples_vb
<System.Runtime.InteropServices.Guid("B89D4A42-A712-4FA4-9ABF-6BE1FB962D24")> _
PublicClassRTreeClosestPointInheritsRhino.Commands.CommandPublicOverridesReadOnlyPropertyEnglishName()AsStringGetReturn"vb_RtreeClosestPoint"EndGetEndPropertyPrivateSubSearchCallback(sender AsObject, e AsRTreeEventArgs)Dim data AsSearchData=TryCast(e.Tag,SearchData)
data.HitCount= data.HitCount+1Dim vertex AsPoint3f= data.Mesh.Vertices(e.Id)Dim distance AsDouble= data.Point.DistanceTo(vertex)If data.Index=-1OrElse data.Distance> distance Then' shrink the sphere to help improve the test
e.SearchSphere=NewSphere(data.Point, distance)
data.Index= e.Id
data.Distance= distance
EndIfEndSubPrivateClassSearchDataPublicSubNew(mesh__1 AsMesh, point__2 AsPoint3d)Point= point__2
Mesh= mesh__1
HitCount=0Index=-1Distance=0EndSubPublicPropertyHitCountAsIntegerPublicPropertyPointAsPoint3dPublicPropertyMeshAsMeshPublicPropertyIndexAsIntegerPublicPropertyDistanceAsDoubleEndClassProtectedOverridesFunctionRunCommand(doc AsRhinoDoc, mode AsRhino.Commands.RunMode)AsRhino.Commands.ResultDim objref AsRhino.DocObjects.ObjRef=NothingDim rc =Rhino.Input.RhinoGet.GetOneObject("select mesh",False,Rhino.DocObjects.ObjectType.Mesh, objref)If rc <>Rhino.Commands.Result.SuccessThenReturn rc
EndIfDim mesh AsMesh= objref.Mesh()
objref.Object().Select(False)
doc.Views.Redraw()Using tree AsNewRTree()For i AsInteger=0To mesh.Vertices.Count-1' we can make a C++ function that just builds an rtree from the' vertices in one quick shot, but for now...
tree.Insert(mesh.Vertices(i), i)NextDim point AsPoint3dWhileTrue
rc =Rhino.Input.RhinoGet.GetPoint("test point",False, point)If rc <>Rhino.Commands.Result.SuccessThenExitWhileEndIfDim data AsNewSearchData(mesh, point)' Use the first vertex in the mesh to define a start sphereDim distance AsDouble= point.DistanceTo(mesh.Vertices(0))Dim sphere AsNewSphere(point, distance *1.1)If tree.Search(sphere,AddressOfSearchCallback, data)Then
doc.Objects.AddPoint(mesh.Vertices(data.Index))
doc.Views.Redraw()RhinoApp.WriteLine("Found point in {0} tests", data.HitCount)EndIfEndWhileEndUsingReturnRhino.Commands.Result.SuccessEndFunctionEndClassEndNamespace