M_Rhino_Geometry_RTree_Search_3 - mcneel/rhinocommon-api-docs GitHub Wiki
Searches for items in a sphere.
Namespace: Rhino.Geometry
Assembly: RhinoCommon (in RhinoCommon.dll) Version: Rhino 6.0
C#
public bool Search(
Sphere sphere,
EventHandler<RTreeEventArgs> callback,
Object tag
)
VB
Public Function Search (
sphere As Sphere,
callback As EventHandler(Of RTreeEventArgs),
tag As Object
) As Boolean
- sphere
- Type: Rhino.Geometry.Sphere
bounds used for searching. - callback
- Type: System.EventHandler(RTreeEventArgs)
An event handler to be raised when items are found. - tag
- Type: System.Object
State to be passed inside the RTreeEventArgs Tag property.
Type: Boolean
true if entire tree was searched. It is possible no results were found.
VB
Imports Rhino
Imports Rhino.Geometry
Namespace examples_vb
<System.Runtime.InteropServices.Guid("B89D4A42-A712-4FA4-9ABF-6BE1FB962D24")> _
Public Class RTreeClosestPoint
Inherits Rhino.Commands.Command
Public Overrides ReadOnly Property EnglishName() As String
Get
Return "vb_RtreeClosestPoint"
End Get
End Property
Private Sub SearchCallback(sender As Object, e As RTreeEventArgs)
Dim data As SearchData = TryCast(e.Tag, SearchData)
data.HitCount = data.HitCount + 1
Dim vertex As Point3f = data.Mesh.Vertices(e.Id)
Dim distance As Double = data.Point.DistanceTo(vertex)
If data.Index = -1 OrElse data.Distance > distance Then
' shrink the sphere to help improve the test
e.SearchSphere = New Sphere(data.Point, distance)
data.Index = e.Id
data.Distance = distance
End If
End Sub
Private Class SearchData
Public Sub New(mesh__1 As Mesh, point__2 As Point3d)
Point = point__2
Mesh = mesh__1
HitCount = 0
Index = -1
Distance = 0
End Sub
Public Property HitCount As Integer
Public Property Point As Point3d
Public Property Mesh As Mesh
Public Property Index As Integer
Public Property Distance As Double
End Class
Protected Overrides Function RunCommand(doc As RhinoDoc, mode As Rhino.Commands.RunMode) As Rhino.Commands.Result
Dim objref As Rhino.DocObjects.ObjRef = Nothing
Dim rc = Rhino.Input.RhinoGet.GetOneObject("select mesh", False, Rhino.DocObjects.ObjectType.Mesh, objref)
If rc <> Rhino.Commands.Result.Success Then
Return rc
End If
Dim mesh As Mesh = objref.Mesh()
objref.Object().Select(False)
doc.Views.Redraw()
Using tree As New RTree()
For i As Integer = 0 To 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)
Next
Dim point As Point3d
While True
rc = Rhino.Input.RhinoGet.GetPoint("test point", False, point)
If rc <> Rhino.Commands.Result.Success Then
Exit While
End If
Dim data As New SearchData(mesh, point)
' Use the first vertex in the mesh to define a start sphere
Dim distance As Double = point.DistanceTo(mesh.Vertices(0))
Dim sphere As New Sphere(point, distance * 1.1)
If tree.Search(sphere, AddressOf SearchCallback, data) Then
doc.Objects.AddPoint(mesh.Vertices(data.Index))
doc.Views.Redraw()
RhinoApp.WriteLine("Found point in {0} tests", data.HitCount)
End If
End While
End Using
Return Rhino.Commands.Result.Success
End Function
End Class
End Namespace
C#
using Rhino;
using Rhino.Geometry;
namespace examples_cs
{
[System.Runtime.InteropServices.Guid("0E82E6DA-5335-453A-AC94-2499BBBCBE55")]
public class RTreeClosestPoint : Rhino.Commands.Command
{
public override string EnglishName { get { return "cs_RtreeClosestPoint"; } }
void SearchCallback(object sender, RTreeEventArgs e)
{
SearchData data = e.Tag as SearchData;
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 = new Sphere(data.Point, distance);
data.Index = e.Id;
data.Distance = distance;
}
}
class SearchData
{
public SearchData(Mesh mesh, Point3d point)
{
Point = point;
Mesh = mesh;
HitCount = 0;
Index = -1;
Distance = 0;
}
public int HitCount { get; set; }
public Point3d Point { get; private set; }
public Mesh Mesh { get; private set; }
public int Index { get; set; }
public double Distance { get; set; }
}
protected override Rhino.Commands.Result RunCommand(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 = new RTree())
{
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 = new SearchData(mesh, point);
// Use the first vertex in the mesh to define a start sphere
double distance = point.DistanceTo(mesh.Vertices[0]);
Sphere sphere = new Sphere(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);
}
}
}
return Rhino.Commands.Result.Success;
}
}
}
Python
import Rhino
import rhinoscriptsyntax as rs
# data passed to the RTree's SearchCallback function that
# we can use for recording what is going on
class SearchData:
def __init__(self, mesh, point):
self.HitCount = 0
self.Mesh = mesh
self.Point = point
self.Index = -1
self.Distance = 0
def SearchCallback(sender, e):
data = e.Tag
data.HitCount += 1
vertex = data.Mesh.Vertices[e.Id]
distance = data.Point.DistanceTo(vertex)
if data.Index == -1 or 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
def RunSearch():
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 in enumerate(mesh.Vertices): tree.Insert(vertex, i)
while(True):
point = rs.GetPoint("test point")
if not 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()
Supported in: 6.0.16224.21491, 5D58w