Select Similar?

I just had the same problem.
I solved it via a very large spatial hashtable to find overlapping ( or similar) curves:
The nice thing about this aproach is that it keeps the runtime linear.

import rhinoscriptsyntax as rs

from collections import defaultdict as defD

crvs = rs.GetObjects(filter=rs.filter.curve)

tolerance = 1.5 # adjust for your use case

# hash function considering tolerance
def tup (pt):
    x=int(pt.X/tolerance)
    y=int(pt.Y/tolerance)
    z=int(pt.Z/tolerance)
    return x,y,z
    
    
D={}
X=defD(int)
for crv in crvs:
    pts=rs.DivideCurveLength(crv,tolerance*0.7) # space points a bit thighter than tolerance
    tp=0,0,0
    for p in pts:
        t=tup(p)
        if t<>tp:
            if t in D:
                ocrv=D[t]
                c2 = ocrv,crv
                X[c2] +=1
            else:
                D[t]=crv
            tp=t


for (t,o),k in X.items():
    if k > 5: # require an overlap at 5 locations within tolerance ?
        lo=rs.CurveLength(o)
        lt=rs.CurveLength(t)
        if lo < lt: # select the shorter of the two curves
            rs.SelectObject(o)
        else:
            rs.SelectObject(t)
1 Like

Hey guys,

@Mitch @Goswin is it not possible to write a script that find curves that are “hiding” on top of another, doesn’t get picked up by Selddup because they’re shorter? Anotherwords colinear?

Think you mean @Helvetosaur (aka Mitch) :slight_smile:

I think my script would pick up those too. did you try?

Hey @Goswin Goswin, I would love to try it but I’m afraid I’m not proficient enough with scripts to create an rvb.

Is your script available as a drag’n dropable rvb :slight_smile:? If you can “package” it (or show men how) I would really appreciate it.

@cosmas use the command EditPythonScript to open the editor. Paste the code into an empty file and run it with F5.
You will then be prompted to select some curves…

Thank you, @Goswin – it worked !!

Hi @Goswin

It is possible to adapt this script to be able also to select similar object?

I need this selection capability in Rhino and unfortunately the SuperSelect plugin seems to be down.

Thank you.

@Macuso yes this script can be adapted in various ways.
Its is all about breaking down your objects in many 3D points. Almost like voxels. And then checking for common Voxels.
For curves I do this via rs.DivideCurveLength.
So you would have to think about what type of points are signifacnt in your use case.
For Surfaces is it only the edges or is it Points on the surface too?
Then the question would be how many voxels two Surfaces need to share in order to be overlaping.

Hey Mitch,

Your python file is very useful and Exception%20Occured was working well and all of a sudden it’s displaying an “Exception Occured” message when I run it. (See attached). Any thoughts?

Hi Cosmas -
Des this happen with anything or just a specific file or object(s)…? If it is the second, can you post or PM me the file that makes it fail - I might be able to fix something. If it’s the first and you get the error on all files I will need to see if something changed in a service release that broke the script…

Let me check Mitch and get back to you. Thank you.

Hi Mitch,

Hmmm… I did a test file (which I’ve attached) where I drew a 1”x1” square and arrayed it 10x in the x and y direction. I then copied them in place and moved the copy .005” in the x direction and .005” in the y direction. I ran SelNearDupCrvs1.py and I’m getting the same message. I picked .005 ‘cause the tolerance is set to .01.

Tolerances are not my forte but… Do you think that my file’s overall tolerance would affect this? That’s also set to .01 units. My system info is:

Rhino 6 SR14 2019-4-8 (Rhino 6, 6.14.19098.19271, Git hash:master @ 0f7781a49ce492be6a3be8a97cb2399d3c7823fe)

License type: Commercial, build 2019-04-08

License details: Cloud Zoo. In use by: Cosmas Demetriou ()

Windows 10.0 SR0.0 or greater (Physical RAM: 32Gb)

Machine name: DESKTOP-7SR0TFT

Non-hybrid graphics.

Primary display and OpenGL: NVIDIA Quadro P2000 (NVidia) Memory: 5GB, Driver date: 3-17-2019 (M-D-Y). OpenGL Ver: 4.6.0 NVIDIA 419.67

OpenGL Settings

Safe mode: Off

Use accelerated hardware modes: On

Redraw scene when viewports are exposed: On

Anti-alias mode: 8x

Mip Map Filtering: Linear

Anisotropic Filtering Mode: Height

Vendor Name: NVIDIA Corporation

Render version: 4.6

Shading Language: 4.60 NVIDIA

Driver Date: 3-17-2019

Driver Version: 25.21.14.1967

Maximum Texture size: 32768 x 32768

Z-Buffer depth: 24 bits

Maximum Viewport size: 32768 x 32768

Total Video Memory: 5 GB

Rhino plugins

C:\Program Files\Rhino 6\Plug-ins\Commands.rhp "Commands" 6.14.19098.19271

C:\Program Files\Rhino 6\Plug-ins\WebBrowser.rhp "WebBrowser"

C:\Program Files\Rhino 6\Plug-ins\rdk.rhp "Renderer Development Kit"

C:\Program Files\Rhino 6\Plug-ins\RhinoScript.rhp "RhinoScript"

C:\Program Files\Rhino 6\Plug-ins\RPC.rhp "RPC"

C:\Program Files\Rhino 6\Plug-ins\RhinoBonusTools.rhp "Rhino Bonus Tools"

C:\Program Files\Rhino 6\Plug-ins\AnimationTools.rhp "AnimationTools"

C:\Program Files\Rhino 6\Plug-ins\IdleProcessor.rhp "IdleProcessor"

C:\Program Files\Rhino 6\Plug-ins\RhinoRender.rhp "Rhino Render"

C:\Program Files\Rhino 6\Plug-ins\rdk_etoui.rhp "RDK_EtoUI" 6.14.19098.19271

C:\Program Files\Rhino 6\Plug-ins\rdk_ui.rhp "Renderer Development Kit UI"

C:\Program Files\Rhino 6\Plug-ins\NamedSnapshots.rhp "Snapshots"

C:\Program Files\Rhino 6\Plug-ins\Alerter.rhp "Alerter"

C:\Program Files\Rhino 6\Plug-ins\IronPython\RhinoDLR_Python.rhp "IronPython" 6.14.19098.19271

C:\Program Files\Rhino 6\Plug-ins\RhinoCycles.rhp "RhinoCycles" 6.14.19098.19271

C:\Program Files\Rhino 6\Plug-ins\Toolbars\Toolbars.rhp "Toolbars" 6.14.19098.19271

C:\Program Files\Rhino 6\Plug-ins\3dxrhino.rhp "3Dconnexion 3D Mouse"

C:\Program Files\Rhino 6\Plug-ins\Displacement.rhp "Displacement"SelNearDupCrvs1.py.3dm (932.0 KB)

Hi Cosmas -
I think you are using an old version of the script - one that used CurveDeviation to check the distance, which fails occasionally. I re-wrote the script to use point sampling instead, the most recent version is below. This version has a few more bells and whistles - there are optional arguments:

optional arguments:
chk_all - True==check all visible selectable curves; False==user select curves
sel_dup_all - True==select all duplicates, False==leave one duplicate unselected
crv_divs - number of points to sample along curve
user_tol - default comparison tolerance (user-adaptable, sticky)
Defaults: True, False, 25, 0.1

The user_tol value is asked every time, you can change the value, and the new value sticks within the same session. The other values are semi hard-coded and need to be set by adding an optional argument on the last line of the script - for example, if you want to select all the duplicates and not leave one copy unselected, you can change the last line to look like this:

SelectNearDupCrvs(sel_dup_all=True)

Note also that the minimum value you can set the tolerance to is the file absolute tolerance.

SelNearDupCrvs.py (4.9 KB)

It works, Mitch :slight_smile:. Thank you!