Scripting to convert scene containing .obj files to .usd

Hello, I’m new to the USD format. I was looking through the documentation for generating a .usda file via the Python API here. However, since the models are all generated via the sphere primitive (in the end to end example), I’m unclear on how I could achieve something like this with .obj files defining other objects. I’d like to know if there is documentation available on this matter. Thanks.

I don’t have a Python example ready to go but in C++ you can create a mesh as below. The Python code would be very similar.


    // create a USD prim for the mesh
    auto prim = pxr::UsdGeomMesh::Define(stage, primPath);
    GfMatrix4d m;
    m.SetTranslate(pos);
    SetTransformMatrix(prim, m, UsdTimeCode::Default());

    // first populate the points attr with the points from the mesh
    pxr::UsdAttribute pointsAttr = prim.GetPointsAttr();
    pxr::VtArray<GfVec3f> points;
    for (int i = 0; i < mesh->npoints; ++i) {
        points.push_back(GfVec3f(mesh->points[i*3], mesh->points[i*3+1], mesh->points[i*3+2]));
    }
    pointsAttr.Set(points);

    pxr::UsdAttribute normalsAttr = prim.GetNormalsAttr();
    pxr::VtArray<GfVec3f> normals;
    if (mesh->normals) {
        // then the normals
        for (int i = 0; i < mesh->npoints; ++i) {
            normals.push_back(GfVec3f(mesh->normals[i*3], mesh->normals[i*3+1], mesh->normals[i*3+2]));
        }
    }
    
    // the face vertex counts
    pxr::UsdAttribute faceVertexCountsAttr = prim.GetFaceVertexCountsAttr();
    pxr::VtArray<int> faceVertexCounts;
    for (int i = 0; i < mesh->ntriangles; ++i) {
        faceVertexCounts.push_back(3);
    }

    // the face vertex indices
    pxr::UsdAttribute faceVertexIndicesAttr = prim.GetFaceVertexIndicesAttr();
    pxr::VtArray<int> faceVertexIndices;
    for (int i = 0; i < mesh->ntriangles*3; ++i) {
        faceVertexIndices.push_back(mesh->triangles[i]);
    }

    // set the attributes
    if (mesh->normals)
        normalsAttr.Set(normals);
 
    faceVertexCountsAttr.Set(faceVertexCounts);
    faceVertexIndicesAttr.Set(faceVertexIndices);
1 Like

It’s also with noting that adobe recently released a collection of file format plugins, including one for obj. Depending on your needs, you may just be able to use that… And if not, it will likely be a good resource for your own development.

https://github.com/adobe/USD-Fileformat-plugins

2 Likes

Cool, thanks for the comments too! I’ll try to see if I can find something in the Python library but this is very helpful.

Thanks for the note, the direct conversion is very convenient. My use case is actually a little different, I have a bunch of .obj files in a scene (with associated positions). I’ll look into this more.

A file format plugin may be exactly what you’re looking for, then - they provide a way to reference in other file formats (.obj, in your case) into a USD scene, while preserving them in their original format.

(You can also use them to do a one time conversion, as well, but it sounds like that’s not what you’re after.)

Note that I haven’t had a chance to check out the Adobe .obj plug-in myself, so I can’t speak to any specifics is it’s behavior.