SubDEdge Selection Cast to Mesh for Operations

I’ve started a script to adapt a subd edge. The first hurdle I’ve come across is I’m going to need to operate on the subd with the mesh class, casting it with Rhino.Geometry.Mesh.CreateFromSubDControlNet() method.

From a first look, all the vertex/face ids and such will be completely different at this point. So I need to be able to obtain what the controlnet mesh AS a mesh class object ids of faces of what I selected in the subd were. That might not make sense. In short, how do I translate what I’ve selected on a SubD into something on the mesh. Is there something other than mesh closest point?

# SPIN EDGE V1

import Rhino
import Rhino.Geometry as rg
import rhinoscriptsyntax as rs

go = Rhino.Input.Custom.GetObject()
go.SetCommandPrompt("Select edge to orient")
go.GeometryAttributeFilter = Rhino.Input.Custom.GeometryAttributeFilter.InnerLoop
#go.GeometryAttributeFilter = Rhino.Input.Custom.GeometryAttributeFilter.EdgeCurve
go.GeometryFilter = Rhino.DocObjects.ObjectType.EdgeFilter
#go.GeometryFilter = Rhino.DocObjects.ObjectType.MeshEdge

go.Get()

objref = go.Object(0)
guid = objref.ObjectId
subd = rs.coercegeometry(guid)
print "subd:", subd

geo = objref.Geometry()
picked_edge_id = objref.GeometryComponentIndex.Index

picked_subd_edge = subd.Edges.Find(picked_edge_id)
if picked_subd_edge.FaceCount == 2:
    face1 = picked_subd_edge.FaceAt(0)
    face2 = picked_subd_edge.FaceAt(1)
else: print "Cannot rotate naked edge"

verts = [picked_subd_edge.VertexFrom.Id, picked_subd_edge.VertexTo.Id]

print "vertid_from:", verts [0], "vertid_to", verts [1]

face1_id, face2_id = face1.Id, face2.Id

print "face1:", face1_id, "face2:", face2_id
#print face1.ComponentIndex().Index, face2.ComponentIndex().Index

face1, face2 = subd.Faces.Find(face1_id), subd.Faces.Find(face2_id)

# convert to list comprehension
face1_verts = [face1.VertexAt(0).Id, face1.VertexAt(1).Id, face1.VertexAt(2).Id, face1.VertexAt(3).Id]
face2_verts = [face2.VertexAt(0).Id, face2.VertexAt(1).Id, face2.VertexAt(2).Id, face2.VertexAt(3).Id]

face2_verts.reverse()
print face1_verts, face2_verts

mesh = rg.Mesh.CreateFromSubDControlNet(subd)
meshfaces = mesh.Faces

#meshfacelist.DeleteFaces
#mesh topolyedge list class?
#GetEdgesForFace
#Get TopologyVertices
#MehFaceList.DeleteFaces
#MeshFaceList.Insert #insert a face at a defined index
#MeshFaceList.RemoveAt
#meshfacelist.SetFace # set a face at a specific index
#rg.MeshNgons.Create(meshvertexindexlist, faceindexlist)
# then get / access the mesh ngon

Below is my latest code, using closest point to go what feels like quite a long way round to getting underlying mesh faces from a selected subd edge. For the purpose of editing the subd net with the mesh class (since subd doesn’t really have anything to manipulate in that way).


# SPIN EDGE V1

import Rhino
import Rhino.Geometry as rg
import rhinoscriptsyntax as rs

go = Rhino.Input.Custom.GetObject()
go.SetCommandPrompt("Select edge to orient")
go.GeometryAttributeFilter = Rhino.Input.Custom.GeometryAttributeFilter.InnerLoop
#go.GeometryAttributeFilter = Rhino.Input.Custom.GeometryAttributeFilter.EdgeCurve
go.GeometryFilter = Rhino.DocObjects.ObjectType.EdgeFilter
#go.GeometryFilter = Rhino.DocObjects.ObjectType.MeshEdge

go.Get()

objref = go.Object(0)
guid = objref.ObjectId
subd = rs.coercegeometry(guid)
print "subd:", subd

geo = objref.Geometry()
picked_edge_id = objref.GeometryComponentIndex.Index

picked_subd_edge = subd.Edges.Find(picked_edge_id)
if picked_subd_edge.FaceCount == 2:
    face1 = picked_subd_edge.FaceAt(0)
    face2 = picked_subd_edge.FaceAt(1)
else: print "Cannot rotate naked edge"

verts = [picked_subd_edge.VertexFrom.Id, picked_subd_edge.VertexTo.Id]

print "vertid_from:", verts [0], "vertid_to", verts [1]

face1_id, face2_id = face1.Id, face2.Id

print "face1:", face1_id, "face2:", face2_id
#print face1.ComponentIndex().Index, face2.ComponentIndex().Index

face1, face2 = subd.Faces.Find(face1_id), subd.Faces.Find(face2_id)

# convert to list comprehension
face1_verts = [face1.VertexAt(0).Id, face1.VertexAt(1).Id, face1.VertexAt(2).Id, face1.VertexAt(3).Id]
face2_verts = [face2.VertexAt(0).Id, face2.VertexAt(1).Id, face2.VertexAt(2).Id, face2.VertexAt(3).Id]

face2_verts.reverse()
print face1_verts, face2_verts

mesh = rg.Mesh.CreateFromSubDControlNet(subd)
meshfaces = mesh.Faces
meshverts = mesh.Vertices
meshverts.UseDoublePrecisionVertices = True
p3d = meshverts.ToPoint3dArray()

# verts [0], verts [1]

picked_mesh_indices = []

#probably need to make dictionary of vertex ids with distance to point1 or point2
for index, i in enumerate(p3d):
    if i.DistanceTo(subd.Vertices.Find(verts [0]).ControlNetPoint) == 0:
        picked_mesh_indices.append(index)

for index, i in enumerate(p3d):
    if i.DistanceTo(subd.Vertices.Find(verts [1]).ControlNetPoint) == 0:
        picked_mesh_indices.append(index)

print "Vertex Indices are", picked_mesh_indices
#now, find the two faces that share these verts?
all_assoc_faces =  [ meshverts.GetVertexFaces(i) for i in picked_mesh_indices ]

face_verts = []

for i in all_assoc_faces:
    for vert in i:
        face_verts.append(vert)

myset = set(face_verts)

selected_faces = []

for i in myset:
    if face_verts.count(i) > 1:
        selected_faces.append(i)

print "Face Indices are", selected_faces
#meshfacelist.DeleteFaces
#mesh topolyedge list class?
#GetEdgesForFace
#Get TopologyVertices
#MehFaceList.DeleteFaces
#MeshFaceList.Insert #insert a face at a defined index
#MeshFaceList.RemoveAt
#meshfacelist.SetFace # set a face at a specific index
#rg.MeshNgons.Create(meshvertexindexlist, faceindexlist)
# then get / access the mesh ngon

# mesh.CopyFrom(subd) #? would this help? mimic other list?