Iterate Through Picked SubD Vertices

Is there a way to use a simple rhinoscriptsyntax as a Getter for a SubD, and to then be able to return the Point3Ds of all the vertices of the cage?

I can get the SubDVertexList, but can’t iterate through that to get the vertices.

I’m trying to get all the point 3D locations of the cage, and then convert that to selecting the control ‘points’ of the SubD.

Hi @Jonathan_Hutchinson,

I’m not sure I understand everything you want to do. But lets start with this:

import Rhino
import scriptcontext as sc

def test_subd_verts():
    filter = Rhino.DocObjects.ObjectType.SubD
    rc, objref = Rhino.Input.RhinoGet.GetOneObject("Select SubD", False, filter)
    if not objref or rc != Rhino.Commands.Result.Success: return
    
    subd = objref.SubD()
    if not subd: return
        
    vert = subd.Vertices.First
    while vert:
        sc.doc.Objects.AddPoint(vert.ControlNetPoint)
        vert = vert.Next
    
    sc.doc.Views.Redraw();
    
test_subd_verts()

– Dale

1 Like

Thanks for this Dale! I thought this would be a good first step for what I wanted to achieve, also I was curious since noticing the structure of vertices is different to edges and faces, both of the latter list all the objects (as opposed to the first and count, perhaps this is for efficiency?).

In fact, all I need is a way to get a list of the ‘currently’ selected SubD verts. So it would be a ‘pre-select’ utility, rather than running and performing a Get. I saw PickContext and IsSelected as options but doesn’t seem clear if they will do the trick. Or, Rhino.Geometry.ComponentStatus.IsSelected. Or… RhinoObject.GetSelectedSubObjects. I’m really not sure which.

rs.EnableObjectGrips ( ParentId ) # Assuming here that user is picking from one SubD only
grip_list = [1, 2, 3] # Example of the crrrently picked indices that would be fed in

for grip in grip_list:
    rs.SelectObjectGrip(guid, grip)

This would converta set of picked SubD vertices into picked SubD control points. As messy as it probably is, for now.

I tried with a Get, but this was equally messy. Sadly it seems to have blown my theory that SubVert indices are coincident with the grip indices. The problem with the GetMultipleObjects too, is that It doesn’t enable double slicking to select verts in between two extremes (for 3 verts between two picked points, for example).

import Rhino
import rhinoscriptsyntax as rs

filter = Rhino.DocObjects.ObjectType.MeshVertex
rc, objref = Rhino.Input.RhinoGet.GetMultipleObjects("Select SubD Verts for CP conversion", False, filter)

grip_list = []
parent_id = objref [0].ObjectId

for ref in objref:
	grip_list.append(ref.GeometryComponentIndex.Index)

rs.EnableObjectGrips ( parent_id )
for grip in grip_list:
    rs.SelectObjectGrip(parent_id, grip)

Hi @dale
Are there other methods to access ControlNetPoint and SurfacePoint lists/arrays?
Doing .Next 1 by 1 is slow.

How so?

– Dale

Currently i’m using this 2 methods:

  public List<Rhino.Geometry.Point3d> SubDControlPoints(Rhino.Geometry.SubD subd){
    List<Point3d> pts = new List<Point3d>();
    Rhino.Geometry.SubDVertex vert = subd.Vertices.First;
    for(int i = 0;i < subd.Vertices.Count;i++){
      pts.Add(vert.ControlNetPoint);
      vert = vert.Next;
    }
    return pts;
  }
  public List<Rhino.Geometry.Point3d> SubDSurfacePoints(Rhino.Geometry.SubD subd){
    List<Point3d> pts = new List<Point3d>();
    Rhino.Geometry.SubDVertex vert = subd.Vertices.First;
    for(int i = 0;i < subd.Vertices.Count;i++){
      pts.Add(vert.SurfacePoint());
      vert = vert.Next;
    }
    return pts;
  }

Which iterate 1 by 1 and add each element to a list, but there are clearly faster methods:

2022-02-09 23_40_41-Window
subd control points.gh (941.4 KB)

Even converting the subd to a mesh and then getting the points is faster…

Is my code wrong? Can .Next be used in a parrallel-ized way? I’m missing something…

1 Like

Hi @maje90,

Unlike meshes, subd vertices are not stored in an array. So you’d have to build one in order to return it, which isn’t very efficient.

I don’t know - sorry.

@Jussi_Aaltonen - is this something you know about?

– Dale

Sorry, I don’t have deep enough understanding how iterators work in C#.