Site Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

developer:rhinocommonsamples:closestpoint [2015/09/14] (current)
Line 1: Line 1:
 +===== Sample: Closest Point Calculations with an RTree =====
 +
 +===== C# =====
 +<code c#>
 +using System;
 +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;​
 +    }
 +  }
 +}
 +</​code>​
 +===== VB.NET =====
 +<code 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
 +</​code>​
 +===== Python =====
 +<code 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()
 +</​code>​
 +
 +{{tag>​Developer rhinocommon}}
  
developer/rhinocommonsamples/closestpoint.txt ยท Last modified: 2015/09/14 (external edit)