soma.io#
The soma.io module provides the file-format boundary for the library.
The main responsibilities are:
USD mesh and skeleton import/export
SOMA NPZ save/load helpers
convenience export helpers built around
SOMALayer
I/O helpers for SOMA: NPZ animation files and USD mesh/skeleton I/O.
An .npz file contains everything needed to replay an animation with SOMALayer: identity model type, identity coefficients, poses, root translation, and metadata describing the representation.
- class soma.io.UVPrimvarEntry#
-
Serialized UV primvar data returned by
load_usd_mesh.Behaves like a
dictfor backwards compatibility (entry["coordinates"]) while also supporting attribute access (entry.coordinates).
- class soma.io.SOMANPZData#
-
Dictionary returned by
load_soma_npz.Behaves like a
dictfor backwards compatibility (data["poses"]) while also supporting attribute access (data.poses). Optional fields (scale_params,joint_orient,global_scale,hand_type) are present only if they were saved.
- class soma.io.RigUSDData#
-
Dictionary returned by
load_rig_from_usd.Behaves like a
dictfor backwards compatibility (rig["joint_names"]) while also supporting attribute access (rig.joint_names). Mesh-related fields (face_vert_indices,face_vert_counts,uv_data) are present only when the body skin mesh carries polygon/UV data.
- soma.io.list_usd_meshes(usd_file_path)#
Return prim paths of all Mesh prims in a USD file.
- soma.io.load_usd_mesh(usd_file_path, mesh_name)#
Load a mesh from a USD file.
- Parameters:
- Returns:
(vertices, face_vert_indices, face_vert_counts, uv_data)wherevertices:
(V, 3)float32face_vert_indices:
(sum(counts),)int32 — flattenedface_vert_counts:
(F,)int32 — verts-per-faceuv_data:
{name: {"coordinates": (M,2), "indices": ..., "interpolation": str}}
- Return type:
- soma.io.write_usd_mesh(
- usd_file_path,
- mesh_name,
- vertices,
- face_vert_indices,
- face_vert_counts,
- uv_data=None,
Write a mesh to a new USD file.
- soma.io.fan_triangulate(face_vert_indices, face_vert_counts)#
Convert a polygon soup to triangles via fan triangulation.
- soma.io.load_usd_skeleton(usd_file_path)#
Extract skeleton from a USD file.
- Parameters:
- Returns:
Tuple
(joint_paths, bind_transforms, parent_ids).joint_pathsis the list of J joint path strings (for example"Root/Hips"),bind_transformsis a(J, 4, 4)float32 array of world-space bind transforms in USD row-major convention (point * M), andparent_idscontains the J parent indices with-1for the root.- Return type:
- soma.io.load_usd_animation(usd_file_path)#
Extract SkelAnimation rotations and translations from a USD file.
- soma.io.load_usd_skinning(usd_file_path, mesh_prim_path=None)#
Extract skinning weights from a skinned mesh in a USD file.
The mesh binding may define its own joint order (a subset of the skeleton joints). The returned weight matrix is indexed by the skeleton joint order so it aligns with
load_usd_skeleton.- Parameters:
- Returns:
(skinning_weights, num_joints)whereskinning_weights:
(V, J_skel)float32 dense weight matrixnum_joints: number of skeleton joints
- Return type:
- soma.io.missing_soma_neutral_rig_keys(data)#
Return rig keys absent from a loaded
SOMA_neutral.npzmapping.
- soma.io.find_lod_skin_mesh_name(usd_path, lod)#
Find the skinned mesh leaf name for a body LOD in a UsdSkel asset.
The nvHuman publishes use naming conventions such as
c_skin_xloorc_bodyRig_xlo. This helper keeps the runtime tolerant to small naming differences while still requiring a skinned mesh, not just any mesh whose name contains the LOD token.
- soma.io.load_lod_rig_from_usd(usd_path, lod, *, skin_mesh_name=None)#
Load rig data for a specific body LOD from a UsdSkel USD file.
- soma.io.load_lod_rigs_from_usd(usd_path, lods, *, skin_mesh_names=None)#
Load multiple LOD rigs from one UsdSkel USD file with a shared stage.
- soma.io.load_rig_from_usd(usd_path, *, skin_mesh_name=None)#
Load SOMA template rig data from a UsdSkel USD file.
Extracts the joint hierarchy, bind/T-pose transforms, bind-shape vertex positions, and skinning weights from the USD skeleton. Returns the rig-related keys that used to be stored in
SOMA_neutral.npzso they can be merged with the slim core asset when initializingSOMALayer.Shape PCA data (
mean,shapedirs,eigenvalues) and mesh topology (triangles,triangles_low, LOD maps, facial segments) are not included; they must still be loaded fromSOMA_neutral.npz.- Parameters:
usd_path (str | Path) – Path to the
.usda,.usdc, or.usdtemplate rig.skin_mesh_name (str | None) – Name of the
UsdGeomMeshprim holding the body skin (leaf path component, not full path). IfNone(the default), look forDEFAULT_SKIN_MESH_NAMEfirst, and fall back to the firstUsdGeomMeshdescendant of anyUsdSkelRoot. Pass an explicit name to pin the search.
- Returns:
Dictionary with rig keys supplied by
SOMA_template_rig.usda–joint_names,joint_parent_ids,bind_pose_world,bind_pose_local,t_pose_world,t_pose_local,bind_shape,skinning_weights_data,skinning_weights_indices,skinning_weights_indptr, andskinning_weights_shape. When the body skin mesh carries polygon or UV data, the result also includesface_vert_indices,face_vert_counts, anduv_dataforsave_soma_usd.- Raises:
FileNotFoundError – if the USD file does not exist.
RuntimeError – if the file cannot be opened, has no
UsdSkelSkeleton, has nobindTransforms, has joint/ transform count mismatches, or has malformed skinning primvars.ValueError – if the skin mesh cannot be located under skin_mesh_name (or the auto-discovery fallback), or has no points.
- Return type:
- soma.io.add_npz_args(parser)#
Add common NPZ output arguments to an argparse parser.
- soma.io.load_soma_npz(path)#
Load a SOMA animation .npz saved by
save_soma_npz.Returns a dict with the following keys:
poses:(N, J, 3)rotvec or(N, J, 3, 3)matrices.transl:(N, 3)root translation.joint_names: list of J joint name strings.identity_model_type: e.g."mhr","smpl".identity_coeffs:(N, C)or(1, C).rotation_repr:"rotvec"or"matrix".absolute_pose: bool — True if poses are absolute (no joint orient).unit: unit label string (e.g."meters").keep_root: bool — whether the Root joint (index 0) is included.
Optional keys (present only if saved):
scale_params:(N, S)or(1, S).joint_orient:(J, 3, 3)per-joint orient (present whenabsolute_pose=False).global_scale: scalar uniform scale factor.hand_type:"left"or"right"(absent for body animations).
Any extra arrays stored via extra_arrays are included as-is.
- Parameters:
- Returns:
dict of numpy arrays and Python scalars.
- Return type:
- soma.io.save_soma_usd(
- out_path,
- rotations=None,
- root_translation=None,
- *,
- joint_names,
- joint_parent_ids,
- bind_transforms_world,
- bind_transforms_local,
- rest_shape,
- faces=None,
- face_vert_indices=None,
- face_vert_counts=None,
- uv_data=None,
- skinning_weights,
- unit='meters',
- fps=30.0,
- topk=8,
- root_joint_idx=None,
- skin_mesh_name=DEFAULT_SKIN_MESH_NAME,
Save a SOMA skeletal rig (and optionally animation) to a USD file with UsdSkel.
When rotations and root_translation are omitted, only the static rig is written (skeleton bind pose + skinned mesh) with no SkelAnimation prim.
The rotations and root_translation should come directly from
fit(local-space,absolute_pose=Trueconvention).- Parameters:
out_path (str | Path) – Output
.usd,.usda, or.usdcfile path.rotations (ndarray | Tensor | None) – (N, J, 3, 3) local rotation matrices, or
Nonefor a static rig.root_translation (ndarray | Tensor | None) – (N, 3) root joint local translation, or
Nonefor a static rig.joint_names (Sequence[str]) – list of J joint name strings (including Root).
joint_parent_ids (Sequence[int] | ndarray | Tensor) – (J,) parent index array.
bind_transforms_world (ndarray | Tensor) – (J, 4, 4) or (1, J, 4, 4) world-space bind transforms.
bind_transforms_local (ndarray | Tensor) – (J, 4, 4) or (1, J, 4, 4) local-space bind transforms.
rest_shape (ndarray | Tensor) – (V, 3) bind-pose vertex positions.
faces (ndarray | Tensor | None) – (F, 3) triangle face indices. Used as fallback when face_vert_indices/face_vert_counts are not provided.
face_vert_indices (ndarray | Tensor | None) – Flattened polygon face-vertex indices (e.g. quads from the template USD). Takes priority over faces when provided.
face_vert_counts (ndarray | Tensor | None) – Per-face vertex counts matching face_vert_indices.
uv_data (Mapping[str, UVPrimvarEntry] | None) – Optional UV sets in nested-dict format
{name: {"coordinates": (M,2), "indices": ..., "interpolation": str}}, as returned byload_usd_meshorload_rig_from_usd.skinning_weights (ndarray | Tensor) – (V, J) dense skinning weights.
unit (str) –
"meters","centimeters", or"millimeters".fps (float) – Frames per second (timeCodesPerSecond).
topk (int) – Max joint influences per vertex for sparse skinning.
root_joint_idx (int | None) – Index of the joint that receives root_translation. Defaults to 1 (SOMA body Hips); pass 0 for hand models.
skin_mesh_name (str) – Leaf name for the skinned mesh prim under the
UsdSkelRoot. Defaults toDEFAULT_SKIN_MESH_NAMEso that files written here round-trip cleanly throughload_rig_from_usd.
- soma.io.save_vertex_animation_usd(
- out_path,
- vertices,
- faces,
- *,
- unit='meters',
- fps=30.0,
- prim_path='/Mesh',
Save a mesh with per-frame vertex positions to USD.
No skeleton or skinning – just animated
Pointson aMeshprim. Useful for exporting target meshes, blendshape sequences, or any topology-constant vertex animation.- Parameters:
out_path (str | Path) – Output
.usd,.usda, or.usdcfile path.vertices (ndarray | Tensor) – (N, V, 3) per-frame vertex positions.
faces (ndarray | Tensor) – (F, 3) triangle face indices (constant across frames).
unit (str) –
"meters","centimeters", or"millimeters".fps (float) – Frames per second.
prim_path (str) – USD prim path for the mesh (default
"/Mesh").