Get UVs from a mesh extracted from SubD

Hi, I’m using opennurbs to read .3dm files. Right now I’m adding support for subD objects and use the v7_rhino_logo_subd.3dm file for testing.
I can get a subdivided mesh using GlobalSubdivide and then GetControlNetMesh(NULL, ON_SubDGetControlNetMeshPriority::TextureCoordinates).
Unfortunately I’m not able to get any useful UV coordinates from the model. Maybe I’m looking the wrong place, but the ON_Mesh::m_T consist of NANs, the same goes for ON_Mesh::m_S.
When calling ON_SubD::TextureCoordinateType() on the subD object I get ON_SubDTextureCoordinateType::Packed, but how do I use this?

I hope my issue makes sense and someone is able to help me :slight_smile:

Getting a limit surface representation of the SubD is not available in public OpenNURBS, neither in mesh or NURBS form. You will need to use another library to get the Catmull-Clark limit surface from the control mesh.

Thank you for getting back to me so quickly.
Which library can you recommend to get the information I need?
It seems like the opennurbs library is made ready for it so hopefully it will be added in the next version.

I think I misread your original question. Do you want to get texture information on the control net mesh, o or on the limit surface mesh?

While the limit surface mesh is not available in public OpenNURBS, the control net mesh is and should have its texture information set from the SubD. This happens in Internal_GetTextureCoordinatesGeometryControlNetMesh, file opennurbs_subd_mesh.cpp. For it to work you need to get the control mesh with the priority: ON_SubDGetControlNetMeshPriority::TextureCoordinates

For example, reading the v7_rhino_logo_subd.3dm file from within example_read.cpp in OpenNURBS, the following gets me to a mesh that has its m_S and m_T arrays properly set:

  ON_ModelGeometryComponent comp = model.ModelGeometryComponentFromId(ON_UuidFromString("0c781ba0-3a7c-4d27-8e9c-80182cc6b8f1"));
  const ON_Geometry* geom{comp.Geometry(nullptr)};
  const ON_SubD* subd{ON_SubD::Cast(geom)};

  ON_Mesh* mesh = subd->GetControlNetMesh(
      nullptr, ON_SubDGetControlNetMeshPriority::TextureCoordinates);

Hi Pierre

I tried this in my search for the texture coordinates, and use it for getting the mesh, but the m_T array seems to be filled witd nans. I didn’t really expect that.
I also subdivided the subD to get more triangles. Does this interfere with the texture coordinates?

Regards, Maiken

So, I just tried not to subdivide and then I got the texture coordinates out correctly.
Unfortunately I will need to subdivide the subd to get a nice mesh.
Is it known that subdividing a subD does not apply to the texture coordinates?
Or am I missing someting?
In order to subdivide the subD it’s cast to non const.

Hi Maiken,

As you’ve seen, subdividing the SubD currently loses the texture coordinates information. We are only able to extract these on the level 0 control net mesh because there is enough information saved by Rhino in the .3dm file to fill in the m_S and m_T array. Subdividing does not propagate enough information to the next SubD level to do that.

Public OpenNURBS does not provide much in the way of creating the necessary information on a SubD to get the texture coordinates on its control net mesh (i.e. SubD face packing, generating mesh fragments and texture coordinates in the SubD faces). So I don’t think you will be able to get these m_S and m_T arrays filled in a subdivided SubD control net mesh.

Can you provide a bit more context on why you would like to do that? @dalelear is going to look into this some more, understanding the use case here will help us decide how we should deal with this in public OpenNURBS.



Hi Pierre and Dale

Thank you very much for clarifying this.
I’m currently working on improving our Rhino importer for KeyShot i order to support SubD. We do not have subD internally and therefore need the mesh.
When we get a mesh from Rhino we extract geometry information like normals and UVs from it.