SOMALayer#

SOMALayer is the full-body entry point for the library: a 78-joint parametric human model.

It combines:

  • a selected identity backend: mhr (default), soma, smpl / smplh / smplx, anny, or garment

  • identity-dependent skeleton fitting

  • Warp-accelerated or dense linear blend skinning

  • optional pose-dependent corrective vertex offsets

Two-phase API:

  1. prepare_identity(...) when the identity changes

  2. pose(...) for each new pose

forward(...) is the one-call convenience wrapper.

See the module overview below for the full parameter reference (joint grouping, per-backend identity dims, scale_params layout, units). The class reference follows.

Full-body SOMA layer and identity-aware posing pipeline.

This module defines SOMALayer, the full-body entry point of the library. SOMA maps every supported identity backend to a single canonical mesh topology and 78-joint skeleton, enabling a shared LBS pipeline across backends.

The sections below describe the SOMA skeleton joint layout and the shapes / semantics of the tensors that SOMALayer consumes. Shapes use B for batch size, V for the LOD-dependent body vertex count, and J = 78 for the full-body joint count.

LOD vertex counts#

The posed vertex tensor has shape (B, V, 3), where V depends on the selected lod:

lod

Vertices

"mid"

18,056

"low"

4,505

"xlo"

612

low_lod=True is the legacy alias for lod="low".

SOMA skeleton (78 joints)#

The full-body SOMA skeleton has J = 78 joints indexed 0-77. Joint 0 is a virtual Root that is always identity (padded internally, not user-controllable). Joint 1 is Hips.

User-facing poses and joints tensors have J - 1 = 77 entries. poses[k] maps to internal joint k + 1; so poses[0] is the Hips rotation, which is effectively the global body rotation in the caller’s frame.

User idx

Internal idx

Count

Region

0

1

Root (virtual, always identity)

0-3

1-4

4

Hips, Spine1, Spine2, Chest

4-10

5-11

7

Neck1, Neck2, Head, HeadEnd, Jaw, LeftEye, RightEye

11-38

12-39

28

Left arm + hand (shoulder, arm, forearm, hand, 5 fingers)

39-66

40-67

28

Right arm + hand (mirror)

67-71

68-72

5

Left leg + foot (leg, shin, foot, toe-base, toe-end)

72-76

73-77

5

Right leg + foot (mirror)

Public joint names are available at runtime via layer._public_joint_names (78-element array including the virtual Root at index 0). In the legacy 78-joint rig this is the same as layer.rig_data["joint_names"]; in procedural mode rig_data is the expanded internal skinning skeleton.

Procedural transforms#

By default, SOMALayer keeps the expanded v0026 nvHuman twist-joint skeleton from the universal SOMA_template_rig.usda template, or from an explicit template_rig_path override. Passing enable_procedural_transforms=False opts out to the legacy 78-joint rig derived from that same template by pruning procedural/auxiliary joints and aggregating their skin weights to the nearest kept parent. The public poses input and all returned public outputs keep the 78-joint SOMA contract: joints has the 77 user-facing non-Root joints and transforms has the 78 public joints including Root. The expanded twist skeleton is used internally for FK/LBS and cached bind data, but is not returned from pose() / forward().

Procedural transforms require SOMA_procedural_transforms.json in data_root. That sidecar is the runtime source of truth for twist topology and parameter metadata, including the rotation extraction policy and sparse parameter matrices. The template USD supplies the concrete skeleton and bind/T-pose data.

Procedural mode uses a single SOMA-owned procedural parameter transform with compiled rotation and translation matrices matching the segment driver topology: forearm and shin twist come from hand and foot twist, while upper arm and thigh twist use reverse start/end compensation. The SOMA implementation is a sidecar-driven parameter-matrix path with SOMA-owned translations. The JSON rotation_extraction policy selects "local_x_euler", "local_x_swing_twist", "aligned_x_swing_twist", or per-procedural-joint mixes of those extractors. "local_x_euler" reads the configured SOMA local-X twist channel from local Euler angles. "local_x_swing_twist" extracts the same configured channel by projecting a half-angle stabilized source quaternion onto its SOMA twist axis. "aligned_x_swing_twist" extracts segment-aligned virtual twist from source world transforms and bind alignment. The current pose-channel convention maps arm local-X twist to axis X, left leg local-X twist to negative axis Y, and right leg local-X twist to positive axis Y. The JSON translation matrix places twist helpers along the fitted public segment, preserving identity and body-part stretch instead of trusting independently fitted twist translations. Pose correctives are supported only in this procedural-transform mode.

Pose tensor (poses)#

Shape (B, 77, 3) axis-angle, or (B, 77, 3, 3) rotation matrices when pose2rot=False.

  • poses[0] = Hips rotation = global body rotation in the caller’s frame.

  • Remaining entries are joint-local rotations, interpreted relative to the T-pose joint orient by default. This T-pose-relative convention matches SMPL-style pose parameters. Pass absolute_pose=True to treat them as already-oriented absolute local rotations instead.

Root translation (transl, optional)#

Shape (B, 3). Hips translation in output_unit. None keeps the Hips at the origin.

Identity coefficients (identity_coeffs)#

Shape (B, K). K = num_shape_components is backend-dependent, selected via the identity_model_type constructor argument.

identity_model_type

K

Source

"mhr" (default)

45

MHR body-shape identity

"soma"

128

PCA in SOMA_neutral.npz

"smpl" / "smplh" / "smplx"

varies (typ. 10)

SMPL / SMPL-H / SMPL-X betas

"anny"

data-driven

Anny phenotype dims

"garment"

data-driven

Garment-measurement PCA

Body-part scales (scale_params, optional)#

Backend-dependent. Pass None to skip.

Backend

Shape

When applied

Semantics

mhr

(B, 68)

prepare_identity()

Required for MHR. Native MHR body-part scale vector.

soma

(B, layer.num_scale_params)

pose()

Active limb-segment and finger bone-length scale ratios only. layer.scale_param_names gives the ordered child public-joint names and layer.scale_param_segments gives matching (parent, child) local-translation edges. Each value multiplies that edge’s local parent-to-child translation; 1.0 = no change. Hip/shoulder-width and other inactive joints are not exposed.

anny

data-driven

prepare_identity()

Optional Anny local-change adjustments (per-body-part shape tweaks).

Others

unused

Pass None.

Correctives#

Pose-dependent corrective vertex offsets are applied by default (apply_correctives=True on pose() / forward()) when a corrective checkpoint is loaded. Body correctives require procedural transforms. Pass apply_correctives=False for a pure LBS output, or construct with correctives_model_path=None to skip loading the checkpoint entirely.

Units#

Native unit of the SOMA rig is centimeters. Output unit is configurable via output_unit in __init__ (default Unit.METERS). All translational quantities returned by pose() / forward() – vertices, joints, transforms – are in output_unit. Up axis +Y, forward axis +Z, right-handed.

class soma.soma.SOMALayer(
data_root=None,
low_lod=False,
device='cuda',
identity_model_type='mhr',
mode='warp',
output_unit=Unit.METERS,
identity_model_kwargs=None,
lod=None,
template_rig_path=None,
enable_procedural_transforms=True,
load_correctives_model=None,
correctives_model_path=_DEFAULT_CORRECTIVES_MODEL_PATH,
)#

Bases: Module

Full-body parametric human model with a 78-joint SOMA skeleton.

Combines a pluggable identity backend, identity-dependent skeleton fitting, LBS skinning (Warp-accelerated or dense), and optional pose-dependent corrective vertex offsets.

Two-phase API:

  1. prepare_identity(identity_coeffs, scale_params=None) – cache rest shape + fitted skeleton for an identity.

  2. pose(poses, transl=None) – apply articulation to the cached identity.

forward() is a convenience wrapper that calls both.

See the soma.soma module docstring for the SOMA skeleton joint layout, pose tensor conventions, per-backend identity dimensions, and scale_params semantics.

Build a SOMALayer with the selected identity backend.

Parameters:
  • data_root (str | Path | None) – Directory containing SOMA_neutral.npz, SOMA_template_rig.usda, and the per-backend model folders. If None or missing, assets are downloaded from HuggingFace automatically.

  • low_lod (bool) – If True, use the low-LOD mesh (4,505 vertices). Faster inference at the cost of detail. Legacy alias for lod="low".

  • device (str | device) – Torch device for all buffers and intermediate tensors (e.g. "cuda", "cpu").

  • identity_model_type (str) – Identity backend. One of "mhr" (default), "soma", "smpl", "smplh", "smplx", "anny", "garment". See soma.soma for per-backend identity dimensions and scale_params semantics.

  • mode (str) – Skinning backend. "warp" uses the NVIDIA Warp accelerated LBS kernel; other values fall back to the dense PyTorch implementation.

  • output_unit (Unit) – Unit for all translational outputs of pose() / forward() (vertices, joints, transforms). Default Unit.METERS.

  • identity_model_kwargs (Mapping[str, Any] | None) – Extra keyword arguments forwarded to the identity-model constructor. Used e.g. by SMPL/SMPL-X to pass model_path.

  • lod (str | None) – Body mesh level of detail: "mid" (18,056 vertices), "low" (4,505 vertices), or "xlo" (612 vertices). "xlo" loads mesh topology, bind shape, skinning weights, and UVs from the xlo mesh in SOMA_template_rig.usda in data_root.

  • template_rig_path (str | Path | None) – Optional override path to a v0026 nvHuman nvHuman_male_skel.usda twist-joint rig. If omitted, data_root/SOMA_template_rig.usda is used as the universal template.

  • enable_procedural_transforms (bool) – If True (default), keep the expanded v0026 twist-joint rig and drive SOMA-owned twist joints from the JSON procedural definition. False opts out to the legacy 78-joint public rig.

  • load_correctives_model (bool | None) – Deprecated compatibility alias. Use correctives_model_path=None instead of False.

  • correctives_model_path (str | Path | None) – Path to a pose-corrective checkpoint. Defaults to data_root/correctives_model.pt when procedural transforms are enabled. Pass None to skip loading correctives.

property default_skin_mesh_name: str#

Default USD skin-mesh prim name for this layer’s topology.

Consumed by export_soma_usd when the caller does not pass an explicit skin_mesh_name. Uses the c_skin_<lod> convention (mid for mid-LOD, lo for low-LOD, xlo for extra-low LOD).

property public_joint_names: tuple[str, ...]#

Names of the public SOMA joints returned by pose().

property target_joint_names: tuple[str, ...]#

Names of the internal target skinning joints.

property output_joint_parent_ids: Tensor#

Parent ids for the public transforms returned by pose().

public_skinning_weights()#

Return target skinning weights folded onto the public SOMA hierarchy.

public_bind_transforms_world(bind_transforms_world=None)#

Select public-joint world bind transforms from target bind transforms.

public_rig_view(bind_transforms_world=None)#

Return the public-joint view of this layer’s current fitted rig.

to_public_rotations(rotations)#

Reduce target-joint rotations to the public SOMA joint order.

prepare_identity(
identity_coeffs,
scale_params=None,
repose_to_bind_pose=True,
global_scale=1.0,
kwargs=None,
)#

Cache rest shape and fitted skeleton for the given identity.

Call once per identity, then call pose() for each new frame. This avoids recomputing the identity model and skeleton transfer per frame.

Parameters:
  • identity_coeffs (Tensor) – (B, K) identity coefficients.

  • scale_params (Tensor | None) – backend-dependent per-identity scale tensor (SOMA: (B, layer.num_scale_params), active bone-length scale ratios ordered by layer.scale_param_names and described by layer.scale_param_segments; MHR: (B, 68), required; Anny: optional local-change adjustments; other backends: unused). See class docstring.

  • repose_to_bind_pose (bool) – if True, rebind skinning to the bind pose after fitting. Keep enabled when apply_correctives is used.

  • global_scale (float | Tensor) – uniform scale scalar or (B,) tensor. Default 1.0.

  • kwargs (Mapping[str, Any] | None) – optional dict forwarded to the identity model’s get_rest_shape.

pose(
poses,
transl=None,
pose2rot=True,
apply_correctives=True,
absolute_pose=False,
fk_only=False,
return_transforms=None,
)#

Pose the cached identity. Call prepare_identity() first.

Parameters:
  • poses (Tensor) – (B, 77, 3) axis-angle, or (B, 77, 3, 3) rot matrices. poses[0] = Hips rotation (global body rotation); remaining entries = joint-local articulation.

  • transl (Tensor | None) – (B, 3) Hips translation in output_unit. If None, Hips stays at origin.

  • pose2rot (bool) – convert axis-angle to rot matrices if True.

  • apply_correctives (bool) – if True, apply pose-dependent corrective offsets.

  • absolute_pose (bool) – if True, rotations are absolute (not relative to T-pose joint orient).

  • fk_only (bool) – if True, run forward kinematics only and skip LBS.

  • return_transforms (bool | None) – deprecated"transforms" is always included in the result. Emits DeprecationWarning and has no effect.

Returns:

SOMAPoseOutput (all translations in output_unit) –

  • vertices: (B, V, 3). Omitted if fk_only=True.

  • joints: (B, 77, 3).

  • transforms: (B, 78, 4, 4). Public skeleton (includes Root). In procedural mode, internal twist-joint FK/LBS transforms are intentionally not returned.

Return type:

SOMAPoseOutput

forward(
poses,
identity_coeffs,
scale_params=None,
transl=None,
pose2rot=True,
apply_correctives=True,
absolute_pose=False,
global_scale=1.0,
kwargs=None,
return_transforms=None,
)#

Combined prepare_identity + pose (convenience).

Parameters:
  • poses (Tensor) – (B, 77, 3) axis-angle, or (B, 77, 3, 3) rot matrices. poses[0] = Hips rotation (global body rotation); remaining entries = joint-local articulation.

  • identity_coeffs (Tensor) – (B, K) identity coefficients.

  • scale_params (Tensor | None) – backend-dependent per-identity scale tensor (SOMA: (B, layer.num_scale_params), active bone-length scale ratios ordered by layer.scale_param_names and described by layer.scale_param_segments; MHR: (B, 68), required; Anny: optional local-change adjustments; other backends: unused). See class docstring.

  • transl (Tensor | None) – (B, 3) Hips translation in output_unit. If None, Hips stays at origin.

  • pose2rot (bool) – convert axis-angle to rot matrices if True.

  • apply_correctives (bool) – if True, apply pose-dependent corrective offsets.

  • absolute_pose (bool) – if True, rotations are absolute (not relative to T-pose joint orient).

  • global_scale (float | Tensor) – uniform scale scalar or (B,) tensor. Default 1.0.

  • kwargs (Mapping[str, Any] | None) – optional dict forwarded to the identity model’s get_rest_shape.

  • return_transforms (bool | None) – deprecated"transforms" is always included in the result. Emits DeprecationWarning and has no effect.

Returns:

SOMAPoseOutput (all translations in output_unit) –

  • vertices: (B, V, 3).

  • joints: (B, 77, 3).

  • transforms: (B, 78, 4, 4). Public skeleton (includes Root). In procedural mode, internal twist-joint FK/LBS transforms are intentionally not returned.

Return type:

SOMAPoseOutput