public LazyClosestPointsAmountEnumerator(RTree tree, IReadOnlyList <Point3d> oversized_tree_pts_array, IEnumerable <Point3d> needlePts, int amount) { if (tree.Count < amount) { throw new ArgumentException("Requested more items than the quantity present in tree."); } m_tree = tree; m_oversized_tree_pts_array = oversized_tree_pts_array; m_needlePts = needlePts; m_amount = amount; }
/// <summary> /// Constructs a new tree with an element for each pointcloud point. /// </summary> /// <param name="cloud">A pointcloud.</param> /// <returns>A new tree, or null on error.</returns> public static RTree CreatePointCloudTree(PointCloud cloud) { RTree rc = new RTree(); IntPtr pRtree = rc.NonConstPointer(); IntPtr pConstCloud = cloud.ConstPointer(); if (!UnsafeNativeMethods.ON_RTree_CreatePointCloudTree(pRtree, pConstCloud)) { rc.Dispose(); return(null); } uint size = UnsafeNativeMethods.ON_RTree_SizeOf(pRtree); rc.m_memory_pressure = size; GC.AddMemoryPressure(rc.m_memory_pressure); return(rc); }
public static Rhino.Commands.Result RTreeClosestPoint(RhinoDoc doc) { 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; }
internal static RTree CreateFromPointArray(IEnumerable <Point3d> points, out Point3d[] potentiallyOversizePtsArray, out int count) { if (points == null) { throw new ArgumentNullException(nameof(points)); } potentiallyOversizePtsArray = RhinoListHelpers.GetConstArray(points, out count); IntPtr ptr_rtree = UnsafeNativeMethods.ON_RTree_CreatePointArrayTree(potentiallyOversizePtsArray, count); if (ptr_rtree == IntPtr.Zero) { throw new InvalidOperationException("Could not create a tree with these inputs."); } var tree = new RTree(ptr_rtree) { m_count = count //avoid thread-unsafe tree traversal to fill Count. }; return(tree); }
/// <summary> /// Constructs a new tree with an element for each pointcloud point. /// </summary> /// <param name="cloud">A pointcloud.</param> /// <returns>A new tree, or null on error.</returns> public static RTree CreatePointCloudTree(PointCloud cloud) { if (cloud == null) { throw new ArgumentNullException(nameof(cloud)); } IntPtr const_ptr_cloud = cloud.ConstPointer(); IntPtr ptr_rtree = UnsafeNativeMethods.ON_RTree_CreatePointCloudTree(const_ptr_cloud); if (IntPtr.Zero == ptr_rtree) { return(null); } RTree rc = new RTree(ptr_rtree); uint size = UnsafeNativeMethods.ON_RTree_SizeOf(ptr_rtree); rc.m_memory_pressure = size; GC.AddMemoryPressure(rc.m_memory_pressure); rc.m_count = cloud.Count; GC.KeepAlive(cloud); return(rc); }
/// <summary> /// Constructs a new tree with an element for each face in the mesh. /// The element id is set to the index of the face. /// </summary> /// <param name="mesh">A mesh.</param> /// <returns>A new tree, or null on error.</returns> public static RTree CreateMeshFaceTree(Mesh mesh) { if (mesh == null) { throw new ArgumentNullException(nameof(mesh)); } RTree rc = new RTree(); IntPtr pRtree = rc.NonConstPointer(); IntPtr pConstMesh = mesh.ConstPointer(); if (!UnsafeNativeMethods.ON_RTree_CreateMeshFaceTree(pRtree, pConstMesh)) { rc.Dispose(); return(null); } uint size = UnsafeNativeMethods.ON_RTree_SizeOf(pRtree); rc.m_memory_pressure = size; GC.AddMemoryPressure(rc.m_memory_pressure); rc.m_count = mesh.Faces.Count; GC.KeepAlive(mesh); return(rc); }
internal static extern bool ON_RTree_Search2(IntPtr pConstRtreeA, IntPtr pConstRtreeB, double tolerance, int serial_number, RTree.SearchCallback searchCB);
internal static extern bool ON_RTree_SearchSphere(IntPtr pConstRtree, Point3d center, double radius, int serial_number, RTree.SearchCallback searchCB);
internal static extern bool ON_RTree_Search(IntPtr pConstRtree, Point3d pt0, Point3d pt1, int serial_number, RTree.SearchCallback searchCB);
/// <summary> /// Searches two R-trees for all pairs elements whose bounding boxes overlap. /// </summary> /// <param name="treeA">A first tree.</param> /// <param name="treeB">A second tree.</param> /// <param name="tolerance"> /// If the distance between a pair of bounding boxes is less than tolerance, /// then callback is called. /// </param> /// <param name="callback">A callback event handler.</param> /// <returns> /// true if entire tree was searched. It is possible no results were found. /// </returns> public static bool SearchOverlaps(RTree treeA, RTree treeB, double tolerance, EventHandler<RTreeEventArgs> callback) { IntPtr pConstTreeA = treeA.ConstPointer(); IntPtr pConstTreeB = treeB.ConstPointer(); if (m_callbacks == null) m_callbacks = new List<Callbackholder>(); Callbackholder cbh = new Callbackholder(); cbh.SerialNumber = m_next_serial_number++; cbh.Callback = callback; cbh.Sender = null; m_callbacks.Add(cbh); SearchCallback searcher = CustomSearchCallback; bool rc = UnsafeNativeMethods.ON_RTree_Search2(pConstTreeA, pConstTreeB, tolerance, cbh.SerialNumber, searcher); for (int i = 0; i < m_callbacks.Count; i++) { if (m_callbacks[i].SerialNumber == cbh.SerialNumber) { m_callbacks.RemoveAt(i); break; } } return rc; }
/// <summary> /// Constructs a new tree with an element for each pointcloud point. /// </summary> /// <param name="cloud">A pointcloud.</param> /// <returns>A new tree, or null on error.</returns> public static RTree CreatePointCloudTree(PointCloud cloud) { RTree rc = new RTree(); IntPtr pRtree = rc.NonConstPointer(); IntPtr pConstCloud = cloud.ConstPointer(); if (!UnsafeNativeMethods.ON_RTree_CreatePointCloudTree(pRtree, pConstCloud)) { rc.Dispose(); return null; } uint size = UnsafeNativeMethods.ON_RTree_SizeOf(pRtree); rc.m_memory_pressure = size; GC.AddMemoryPressure(rc.m_memory_pressure); return rc; }