Select mesh faces with naked edges, select vertices

My goal is to select all the vertices of each upper edge in a collection of meshes, so only the uppermost vertices that make up the top edge of a surface that is a mesh. My approach so far is to check which faces have naked edges. While trying to do this I ran into not being able to select them: this question is two-fold. How would I be able to select a mesh face from a mesh? A starter attempt below:

import Rhino as rh
import rhinoscriptsyntax as rs

def Selufaces():

arrObjs = rh.Input.RhinoGet.GetMultipleObjects("Select meshes",False,rh.DocObjects.ObjectType.Mesh)
for x in arrObjs[1]:
    rhino_object = x.Object()
    cind = rhino_object.SubobjectMaterialComponents
    faces = rhino_object.MeshGeometry.Faces
    for count,y in enumerate(faces):
        nface = rhino_object.MeshGeometry.Faces.HasNakedEdges(count)
        ftype = y.GetType
        fguid = ftype.DeclaringType.GUID
        rhino_object.SelectSubObject(cind, True, True)

I tried using the GUID to select the face using rs.SelectObject(fguid), but this throws an error as the GUID is not found in the document object list. Using subobjects throws an error that states I fed it an array. I’m assuming I’m doing something very simple in a stupidly complex manner?

Second, is there an easy way of selecting all of the vertices that I’m after? The ultimate goal is to use SetPt to set all of the vertices to a single z coordinate.

Hi @jouni.valli,

You can select sub objects of rhino objects. In case of a mesh object, valid sub objects are vertices, edges or faces. Each of these subobjects can be accessed by using indices of the respective tables. Once you have the index (number) you’ll need to define a component index type and set it’s index. For a mesh object’s face with index 0 it would look like this:

import Rhino
import scriptcontext
import rhinoscriptsyntax as rs

def SelFirstMeshFace():
    mesh_id = rs.GetObject("Select a mesh", rs.filter.mesh, True, False)
    if not mesh_id: return
    # get the mesh as rhino object
    mesh_obj = rs.coercerhinoobject(mesh_id, True, True)
    # define the component type and component index (0)
    comp_type = Rhino.Geometry.ComponentIndexType.MeshFace
    comp_index = Rhino.Geometry.ComponentIndex(comp_type, 0)
    # perform persistent subobject selection
    mesh_obj.SelectSubObject(comp_index, True, True, True) 

Yes, but you should first try to understand how to select all naked mesh vertices, below does this for multiple meshes, it defines a component index for each naked vertex as demonstrated above, but uses the component index type of mesh vertices:

import Rhino
import scriptcontext
import rhinoscriptsyntax as rs

def SelNakedMeshEdgePt():
    message = "Select polygon meshes for naked edge point search"
    mesh_ids = rs.GetObjects(message, rs.filter.mesh, True, True, False)
    if not mesh_ids: return
    mesh_objs = [rs.coercerhinoobject(m, True, True) for m in mesh_ids]
    comp_type = Rhino.Geometry.ComponentIndexType.MeshVertex
    for m_obj in mesh_objs:
        rc = [i for i, n in enumerate(m_obj.Geometry.GetNakedEdgePointStatus()) if n]
        for index in rc:
            comp_index = Rhino.Geometry.ComponentIndex(comp_type, index)
            m_obj.SelectSubObject(comp_index, True, True, True) 

I think some scripting is required to do this, one approach for a single mesh would be:

  1. get mesh border(s) as closed polyline(s) using mesh.GetNakedEdges()
  2. then split polyline(s) by angle (at the corners)
  3. from the results, find out which open polylines defines the “upper edge”
  4. select only those vertices which are on the open polyline


Wow @clement, that answered everything in detail. Thanks so much, this made my day! In particular the approach for my ultimate goal given often coming up with one requires familiarity with a language and its possibilities before beginning scripting…

1 Like