Is there a Python code equivalent to Proximity 2D?

I would like to put this code under a button with similar options on the command line. I have it running perfectly in Grasshopper but fear it is too cumbersome to distribute in a group working environment.


You can always create a cluster and make user object that you can distribute.

But I’m sure it is possible with python as well.

Hi Robb - what exactly do you want to do in Rhino? Select a bunch of points and then a single point and say how many nearest points you want to select, something like that?

import rhinoscriptsyntax as rs
import Rhino
import scriptcontext as sc

def test():
    num = 10
    if sc.sticky.has_key('NUM_CLOSEST_PTS'):
        num = sc.sticky['NUM_CLOSEST_PTS']
    ids = rs.GetObjects("Select points", filter=1, preselect=True)
    if not ids: return
    pts = rs.coerce3dpointlist(ids)
    id = rs.GetObject("Select test point", filter=1)
    if not id: return
    testPt = rs.coerce3dpoint(id)
    num = rs.GetInteger("Number of closest points?",num)
    if not num: return
    sc.sticky['NUM_CLOSEST_PTS'] = num
    pList = Rhino.Collections.Point3dList(pts)
    ptIds = []
    count = 0

    while count <= num:
        idx = Rhino.Collections.Point3dList.ClosestIndexInList(pList, testPt)
        ptIdx = pts.index(pList[idx])
        count += 1
    if len(ptIds)>0:


Not that… I work a lot with patterns generated in 3D then I flow a section of the resulting intersecting curves onto a 2d surface. I then need join & close up those curves to laser burn some samples. The attached .GH has a simple example internalized in the Curve component. When you play with the sliders you see different connections being made.

It would be great if the script worked exactly like that. My python abilities are not up to this task at present. It seemed like this should already be there in somebody’s arsenal.

Thanks Pascal. (95.0 KB)

Hi Robb - I don’t know if this is what you’re looking for, but give it a spin-

@rcmcdougle- I fixed a bug… if you got it earlier, I think this one is better (no dups)

to use the Python script use RunPythonScript, or a macro:

_-RunPythonScript "Full path to py file inside double-quotes"


This is the idea and, 2 issues occur at this moment.
1- the script generates 2 curves for each pair of points. SelDup fixes the problem but it would be good to not need to remember the need to clean up after the operation.
2 - It runs perfectly with the > _-RunPythonScript " script " < in the button but fails when I > ! _-RunPythonScript (
) < and paste the code to the button itself. ???!

#2 is important because I am endeavoring to keep the tools contained to the toolbar and not be roaming the network looking for bits and pieces. I am consulting for a global corporation with offices all over.

Many thanks for your help with this.


Hi Robb - I updated the first one to get rid of the dups - delete what you have and download again from the link above. I can put it in a plug-in so that you just run a command - is that OK? Of course your users would still need the plug-in…

@rcmcdougle - a couple more little tuneups above ^^.


Thanks Ivelin.

Clusters are the way to go to protect the fragile from the uninformed. What is silly about this one is that the input sliders feed just one component. I looks the same when clustered.


1 Like

Yeah, I didn’t know how your definition looks and how big it is :slight_smile:

Thanks Pascal - this does the job perfectly… however #2 is still a mystery.
2 - It runs perfectly with the > _-RunPythonScript " script " < in the button but fails when I > ! _-RunPythonScript (
) < and paste the code to the button itself. ???!
I am endeavoring to limit all custom tools to just a toolbar with no external links…

Hi Robb - I don’t know that it is even possible as with running a RhinoScript. I believe you need a file to point to.


I have several other chunks of fairly elaborate Python code under buttons and they work well. The only obvious thing I see different in this one is the addition of >
class ConnectorConduit(Rhino.Display.DisplayConduit):
< for the preview (I’m assuming). Could there be something about that which confuses the beast. When I click the button with pasted code it steps through the commands with no pauses and returns to a raw command prompt.

Thanks again for your help with this.

Hi Rob - yeah, I never messed with this before, I admit… let me monkey with it a bit.
For what it is worth, I cannot get scripts that do any drawing to run off of a button - so far - just a test or two…
@rcmcdougle - on the last line where is has

if __name__ == '__main__':Proximity()

just make that line have only


without the ‘if’ stuff at all.
@rcmcdougle - did that help, changing the last line of the script?


Thanks Pascal - Monkey good!

Perfection Pascal. I should have been able to figure that out as none of my other scripts under buttons close that way. At any rate this works perfectly now.

It seems the actual script you created and cleaned up is no longer available on this thread. I do believe others would find it useful so perhaps the link to the .PY could be restored.

Thanks again,

Hi Robb - there should be a link to GitHub in that post above - I replaced the direct link so that I can just update the script on GitHub and anyone can get the most current.

Do you see that?


I see the link Pascal. When I click on it I get to a page of dense HTML with no PY code that I can see. The “show original” does the same thing, both in Chrome. The file name extension is showing as .JS.

Bad monkeys somewhere. ;-(


Same here, but I found this url in amongst the soup:\

If you just delete the “.js” part of the url above, things will be better…

Thanks Pascal - this is great. This latest iteration leaves the newly created lines selected but deselects the input curves. This suggests to me a command line option to join the new and previously selected curves.