How to Select a Surface Edge Using Python

I’m trying to automate an external CAM plugin I have through Grasshopper. Each operation I’m trying to automate requires me to input a surface, a surface edge, and a curve from the main Rhino doc. (I have potentially hundreds or thousands of surfaces work through in a given file which is why I want to automate).

I have generated pairs of matching named surfaces and closed curves on a named layer. The script grabs the the pair of GUIDs and names for the matching surfaces and curves. (For example data looks like:

    [(('000_dsurfaces_srf', '312664e8-7a71-465a-ab99-0d17a72d1eb4'), ('000_dsurfaces_crv', '36064a53-ff8f-4e1d-90cf-133a2ec6275e')),
     (('001_dsurfaces_srf', '581d9b2b-4b4a-45f2-a8cd-3e8fd97c30d1'), ('001_dsurfaces_crv', '35468a3c-6e46-4fa1-acdf-0a4b52a2f04e'))]

What I need to do is:

  • select a surface
  • hit Enter
  • select any one of the surface edges from the above surface
  • hit enter
  • select a curve
  • hit enter twice.

I have GUIDs and Object names of the surfaces and curves I need, but I can’t figure out how to select one of the surface’s edges. Is it possible?

(Currently the plugin only works in Rhino 5, but I have both Rhino 5 & 6).

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino

#Inputs: active, layer (layer name)

if active:
    sc.doc = Rhino.RhinoDoc.ActiveDoc
    objects = rs.ObjectsByLayer(layer)
    names = []
    objs = []
    
    for obj in objects:
        name = rs.ObjectName(obj)
        names.append(name)
        objs.append(str(obj))
        
    geoIDs = [(names[i], objs[i]) for i in range(0, len(objs))]
    geoIDs.sort()
    names = (zip(geoIDs[1::2], geoIDs[::2]))

    for c, (srf, crv) in enumerate(names):
        if c == 0: # temporary to get the script working with one line of data. 
            print(c, srf[1], crv[1])
            rs.Command("~_-JCAM_AddCustomOperation _D " + "_-SelID " + srf[1] + " _Enter _-SelID " + crv[1]) ## still haven't quite figured out the rest of this line...
        else: # temp
            break # temp

    active = True  
else:
    active = False

for obj in objects:
rs.DuplicateEdgeCurves(obj, True)

however, you should do a catch method to check if your object is a surface (rs.IsSurface) before using rs.DuplicateEdgeCurves.

Thanks, that was the key!