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, orgarmentidentity-dependent skeleton fitting
Warp-accelerated or dense linear blend skinning
optional pose-dependent corrective vertex offsets
Two-phase API:
prepare_identity(...)when the identity changespose(...)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:
|
Vertices |
|---|---|
|
18,056 |
|
4,505 |
|
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 |
|
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=Trueto 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.
|
K |
Source |
|---|---|---|
|
45 |
MHR body-shape identity |
|
128 |
PCA in |
|
varies (typ. 10) |
SMPL / SMPL-H / SMPL-X betas |
|
data-driven |
Anny phenotype dims |
|
data-driven |
Garment-measurement PCA |
Body-part scales (scale_params, optional)#
Backend-dependent. Pass None to skip.
Backend |
Shape |
When applied |
Semantics |
|---|---|---|---|
|
|
|
Required for MHR. Native MHR body-part scale vector. |
|
|
|
Active limb-segment and finger bone-length scale ratios only.
|
|
data-driven |
|
Optional Anny local-change adjustments (per-body-part shape tweaks). |
Others |
unused |
– |
Pass |
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:
ModuleFull-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:
prepare_identity(identity_coeffs, scale_params=None)– cache rest shape + fitted skeleton for an identity.pose(poses, transl=None)– apply articulation to the cached identity.
forward()is a convenience wrapper that calls both.See the
soma.somamodule docstring for the SOMA skeleton joint layout, pose tensor conventions, per-backend identity dimensions, andscale_paramssemantics.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. IfNoneor 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 forlod="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". Seesoma.somafor per-backend identity dimensions andscale_paramssemantics.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). DefaultUnit.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 inSOMA_template_rig.usdaindata_root.template_rig_path (str | Path | None) – Optional override path to a v0026 nvHuman
nvHuman_male_skel.usdatwist-joint rig. If omitted,data_root/SOMA_template_rig.usdais 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.Falseopts out to the legacy 78-joint public rig.load_correctives_model (bool | None) – Deprecated compatibility alias. Use
correctives_model_path=Noneinstead ofFalse.correctives_model_path (str | Path | None) – Path to a pose-corrective checkpoint. Defaults to
data_root/correctives_model.ptwhen procedural transforms are enabled. PassNoneto skip loading correctives.
- property default_skin_mesh_name: str#
Default USD skin-mesh prim name for this layer’s topology.
Consumed by
export_soma_usdwhen the caller does not pass an explicitskin_mesh_name. Uses thec_skin_<lod>convention (midfor mid-LOD,lofor low-LOD,xlofor extra-low LOD).
- 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_namesand described bylayer.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_correctivesis 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. EmitsDeprecationWarningand has no effect.
- Returns:
SOMAPoseOutput (all translations in
output_unit) –vertices: (B, V, 3). Omitted iffk_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_namesand described bylayer.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. EmitsDeprecationWarningand 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