Is there a Python code equivalent to Proximity 2D?

Hi @rcmcdougle,

I’m late to the party, but if you are still interested in a Pythonic proximity2D script, here’s one that I wrote awhile back:

``````"""Search for three-dimensional proximity within a point list."""

__author__ = "p1r4t3b0y"

import Rhino.Geometry as rg
import rhinoscriptsyntax as rs

"""Finds the points in a point cloud that are closest to each of
its items/points within a certain maximum radius with the
RTree algorithm.
Args:
pt_cloud (Rhino.Geometry.PointCloud): A point cloud.
Returns:
A nested list with a sublist of closest point indices
for each point in the point cloud.
"""
rtree = rg.RTree()
# Populate the RTree with point cloud points
for i in xrange(pt_cloud.Count):
rtree.Insert(pt_cloud.Item[i].Location, i) # i is custom id
closest_indices = []
for i in xrange(pt_cloud.Count):
# Construct the sphere as bounds used for searching
center_pt = pt_cloud.Item[i].Location
# Perform the search within the spherical bounds
closest_ids = [] # list of custom ids per point
rtree_callback = lambda sender, args: closest_ids.append(args.Id) \
if i != args.Id else None
rtree.Search(search_sphere, rtree_callback)
# Sort the search result by closest distance
closest_dists = (pt_cloud.Item[j].Location.DistanceTo(center_pt) \
for j in closest_ids)
closest_ids = [x for _, x in sorted(zip(closest_dists, closest_ids))]
closest_indices.append(closest_ids)
return closest_indices

"""Search for three-dimensional proximity within a point list.

Args:
points (list): A collection of three-dimensional points.
max_num (int): A maximum number of closest points to find.
Returns:
A nested list of proximity topology indices [0] and
a nested list of proximity links [1].
"""
# Initalise a point cloud from the points
pt_cloud = rg.PointCloud(points)
# Initalise the proximity topology tree (closest point cloud item indices)
prox_indices = [[j for j in range(len(points))] for i in points]
prox_lines = []

# Get the closest indices for each point cloud item by maximum radius
# Replace the initial closesest indices

# Get the closest indices for each point cloud item by minimum radius
# Cull the closest indices of each point within the minimum radius
for i in xrange(len(prox_indices)):
prox_indices[i].pop(prox_indices[i].index(idx))

# Cull indices by maximum number per point cloud item
for i in range(len(prox_indices)):
if len(prox_indices[i]) > max_num:
# Initalise a temporary current closest points point cloud
cl_cloud = rg.PointCloud()
idcs_map = {} # maps the inital to the new cloud item indices
idx_count = 0 # keeps track of current point cloud item index
for j, pt in enumerate(points):
if j in prox_indices[i] and j != i:
idcs_map[idx_count] = j
idx_count += 1
# Get the closest indices in the current point cloud by max. count
pt = [points[i]] # single point in a list
pcl_cl_idcs = rg.RTree.PointCloudKNeighbors(cl_cloud, pt, max_num)
# Remap the current point cloud closest to the inital indices
cl_indices = [idcs_map[idx] for lt in pcl_cl_idcs for idx in lt]
# Remove the superfluous from the current proximity 3d indices
merged_idcs = prox_indices[i] + cl_indices
cull_idcs = [x for x in merged_idcs if merged_idcs.count(x) == 1]
for idx in cull_idcs:
prox_indices[i].pop(prox_indices[i].index(idx))

for i in range(len(points)):
closest_pts = [points[j] for j in prox_indices[i]]
for pt in closest_pts:
prox_lines.append(rg.Line(points[i], pt))

return prox_indices, prox_lines

###############################################################################

if __name__ == "__main__":
pt_guids = rs.GetObjects(message="Select points", filter=1, preselect=True)
points = []
for guid in pt_guids:
pt = rs.coerce3dpoint(guid)
points.append(pt)

max_num = rs.GetInteger(message="Maximum number of closest points",
number=3,
minimum=1,
maximum=len(points)-1)

number=0.0)