Scripting sub-object selection in Python

Is it possible to invoke sub-object selection through a Python script? For example, if I have a polysurface and I want to select one face. Or would I have to extract the face and deal with it that way? That’s what I am assuming I will need to do but I thought it’s worth asking.



If you were able to subobject select a face, what would you do with it?

Hi Dan,

you mean sub object selection by getting ?

import rhinoscriptsyntax as rs

def SubObjectSelect():
    obj_ref = rs.GetObject(message="Bla", filter=8, preselect=False, subobjects=True)
    if obj_ref:
        print "Surface:", obj_ref.Surface()
        print "Selection Point:", obj_ref.SelectionPoint()

if __name__=="__main__":

Or you`ve meant something different ?


You can get sub-objects - that is one of the strengths of Python, but you will have to go through RhinoCommon - as the subobject doesn’t really exist as an object with an ID in the document, so you have to first extract its geometry, then you can add that back to the document if you want it to exist in the document independently.

However, you can also just work with it as (virtual) geometry without adding it to the document - that is also one of the great strengths of Python/RhinoCommon. Unfortunately, at that point, as most rhinoscriptsyntax methods are based on ID’s - that is to say they only recognize objects that are in the document - if you want to continue working with your virtual geometry, you will need to do most of your succeeding operations in RhinoCommon as well. So things can get complicated pretty quick.

Following is a snippet that allows you to select a sub-surface and offset it by a given value. Note that the selection is not restricted to subsurfaces, it will also select surfaces (I don’t know yet how to restrict it to just Brep faces).

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino

def TestOffsetSubSrf():    
    msg="Select a surface or Brep face to offset"
    if rc!=Rhino.Commands.Result.Success: return
    offset=rs.GetReal("Offset value")
    if offset==None: return


the example above yours does. Thanks for your example too, i´ve learned something again from it !


Me too, thanks… I actually remember how to do it now - the following does restrict selection to just subsurfaces:

import Rhino

def GetOnlyBrepFace():
    msg="Select a surface or Brep face to offset"
    go = Rhino.Input.Custom.GetObject()
    go.GeometryFilter = Rhino.DocObjects.ObjectType.Surface
    go.SubObjectSelect = True
    if go.Get()!=Rhino.Input.GetResult.Object: return
    objref = go.Object(0)

What I am trying to do is extract information from an object, specifically hole information from an imported Solidworks detail. Ideally I would like to select the cylindrical face that represents the hole, then have the diameter, depth and location fed back to the command line, or whatever else I need to do with it. I have a tool that provides this information currently, but it’s not as automated as I would like.

Thanks Mitch and Clement for your code samples. I will study these closely tomorrow.


Maybe like this:

import rhinoscriptsyntax as rs

def SubSelectCylinder():
    obj_ref = rs.GetObject(message="Sel", filter=8, preselect=False, subobjects=True)
    if obj_ref:
        if subsrf:
            res, cyl = subsrf.TryGetCylinder()
            if res:
                circle = cyl.CircleAt(0.0)
                print "Cylinder properties:"
                print "axis vector:", cyl.Axis
                print "center:", cyl.Center
                print "height:", cyl.TotalHeight
                print "diameter:", circle.Diameter
                print "sorry, i am not a cylinder"

if __name__=="__main__":


All of these examples are very informative and helpful. I think I have more reading to do, especially with regard to RhinoCommon and how to use it. For example, TryGetCylinder is unknown to me, but looks like exactly what I need.



Yes, good catch Clement, didn’t think of that as a test…