Vertexid not in order

Hi, I am trying to read the Vertex index of the vertices in a subD. The resulting ids corresponds to the list of vertices in Rhino7 (output of List). Please find attached, the sample 3dm file.

############
Vertices:
v1: Crease (-13.9024, -12.2265, 0)
v.SubdivisionPoint: (-11.1219, -12.1979, 0)
v.SurfacePoint: (-10.1951, -12.1884, 0)
v.Edges[2] = { +e1, -e13 }
v.Faces[1] = { f1 }
v3: Crease (12.6836, -12.455, 0)
v.SubdivisionPoint: (9.76977, -9.60789, 0)
v.SurfacePoint: (8.79851, -8.65885, 0)
v.Edges[2] = { -e1, +e5 }
v.Faces[1] = { f1 }
v4: Crease (-19.8442, 3.3899, 0)
v.SubdivisionPoint: (-18.9016, 2.33294, 0)
v.SurfacePoint: (-18.5873, 1.98062, 0)
v.Edges[3] = { +e2, +e6, -e7 }
v.Faces[2] = { f5, f6 }
v7: Crease (-13.9024, 10.0935, 0)
v.SubdivisionPoint: (-13.4929, 9.60789, 0)
v.SurfacePoint: (-13.3565, 9.44602, 0)
v.Edges[2] = { +e7, -e11 }
v.Faces[1] = { f6 }
v8: Crease (-4.68492, 12.9121, 0)
v.SubdivisionPoint: (-4.05645, 12.5217, 0)
v.SurfacePoint: (-3.84697, 12.3915, 0)
v.Edges[3] = { +e9, +e11, -e16 }
v.Faces[2] = { f6, f7 }
v9: Crease (15.9592, 10.0935, 0)
v.SubdivisionPoint: (14.7499, 7.58919, 0)
v.SurfacePoint: (14.3468, 6.75441, 0)
v.Edges[2] = { -e5, +e12 }
v.Faces[1] = { f1 }
v10: Crease (-18.2445, -11.7694, 0)
v.SubdivisionPoint: (-17.9017, -9.93165, 0)
v.SurfacePoint: (-17.7875, -9.31905, 0)
v.Edges[3] = { +e13, -e2, -e17 }
v.Faces[2] = { f5, f1 }
v11: Smooth (-6.7426, -1.06649, 0)
v.SubdivisionPoint: (-9.00136, -0.622802, 0)
v.SurfacePoint: (-8.72803, -0.352382, 0)
v.Edges[3] = { -e6, +e17, -e18 }
v.Faces[3] = { f5, f6, f1 }
v12: Smooth (1.0284, 4.59712, 0)
v.SubdivisionPoint: (-0.621604, 5.86761, 0)
v.SurfacePoint: (-1.0339, 5.61439, 0)
v.Edges[3] = { -e9, +e18, -e19 }
v.Faces[3] = { f6, f7, f1 }
v13: Crease (9.56028, 12.6074, 0)
v.SubdivisionPoint: (8.5795, 12.3312, 0)
v.SurfacePoint: (8.25257, 12.2392, 0)
v.Edges[3] = { +e16, -e12, +e19 }
v.Faces[2] = { f7, f1 }
##################

In the above list v2, v5, v6 is missing. Is there any way to get an ordered vertex list?
subd.3dm (27.3 KB)

Your SubD does not have vertices with these indices (see picture). The vertices, edges and faces id lists in a SubD are not guaranteed to have sequential ids. This is because it is often faster to add new ids at the end of the lists rather than reindex a complete list, and all the other components pointing to it.

Why do you need these ids to be sequential?

I am trying to write an exporter like an OBJ file where the faces are defined by the vertex indices. It would be easy to read through the ids if it were sequential. Maybe I should first read all the vertices sequentially and save the ids into, say an array, so that I could get back the actual index.
Is that the right way to do it?

not sure if this helps - but you might convert to mesh - and query the mesh ?

There are iterators available for vertices, edges and faces of a SubD (example for vertices : Rhino C++ API: ON_SubDVertexIterator Class Reference).

I imagine a SubD exporter would iterate through vertices, and insert them (with position, id, etc) in the new file. Then go through edges and faces and insert these components, at this point you only need the vertices ids used by these components so no need to have the vertices stored in an array. If you need more than a vertex id, ON_SubDFace and ON_SubDEdge actually store pointers to ON_SubDEdges or ON_SubDVertices used in the component.

OpenNURBS defines SubD faces by the edges they use, a bit different from what you are doing. You can get the vertices around a face using ON_SubDFace::Vertex(i) or ON_SubDVertexIterator(ON_SubD, ON_SubDFace).

Thank you very much for the clarification and suggestions. BTW I am using OpenNURBS to read the subdivision objects, and currently using the vertexiterator to read vertices, the faceiterator to read faces.
Unfortunately, I need the vertex indices, to be able to define the faces and edges. If the vertexIDs were ordered, then it would have been very easy…
Although it might be a bit slow on very large meshes, I think this might work.

  1. read VertexID into an array/vector.
  2. reverse search the index from the VertexID, when required.

If you want to iterate vertices in increasing id order, use
ON_SubDVertexIdIterator
(note the Id between Vertex and Iterator).

There may be gaps in the id sequence.

If you need to find a vertex from it’s id, use subd.VertexFromId(id).

When you want to treat SubD components as if they were in an array, I suggest using a local array during your calculation. Note that for huge SubDs, this requires large pieces of contiguous memory.

ON_SubDVertexIdIterator vit(subd);
ON_SimpleArray<const ON_SubDVertex*> a(subd.VertexCount());
for ( const ON_SubDVertex* v = vit.FirstVertex(); nullptr != v; v = vit.NextVertex() )
a.Append(v);

Thank you very much.