SOMAHandLayer#
SOMAHandLayer is the hand-only counterpart to SOMALayer. It provides a
25-joint parametric hand in wrist-local space for left and right hands at mid,
low, and extra-low LODs.
It combines:
the native SOMA hand identity PCA, or a user-supplied MANO/MHR backend
identity-dependent skeleton fitting
Warp-accelerated or dense linear blend skinning
an optional bind-relative articulation-pose PCA
Use prepare_identity(...) when identity changes and pose(...) for each
new pose. forward(...) is the one-call convenience wrapper.
The pose tensor has shape (B, 25, 3) in axis-angle form, or
(B, 25, 3, 3) when pose2rot=False. Joint zero is the wrist; the
remaining 24 joints articulate the fingers. Outputs contain wrist-local
vertices, joints, and transforms in the requested output unit.
Use constructor reference_pose= for a reusable default, or pass it to
pose() / forward() for a one-call override.
See Data Assets for the shared body/hand lookup API and frames.
See SOMA Hand data assets for the checked-in identity and pose-PCA asset contract and the MANO setup requirements.
Hand-only SOMA-X layers and MANO interoperability.
- class soma.hand.SOMAHandLayer(
- data_root=None,
- hand_type='left',
- device='cuda',
- identity_model_type='soma',
- mode='warp',
- output_unit=Unit.METERS,
- identity_model_kwargs=None,
- lod=None,
- low_lod=False,
- load_correctives_model=None,
- correctives_model_path=_DEFAULT_CORRECTIVES_MODEL_PATH,
- *,
- reference_pose=None,
Bases:
ModuleHand-only parametric model operating in wrist-local coordinate space.
Two-phase API (matching
SOMALayer):prepare_identity(identity_coeffs, scale_params=None)– cache rest shape + fitted skeleton for an identity.pose(poses, global_translation=None)– apply articulation to the cached identity.
forward()is a convenience wrapper that calls both.See the
soma.handmodule docstring for the SOMAHand joint layout (25 joints, strict subset of the full-body SOMA skeleton), pose tensor conventions, per-backend identity dimensions, andscale_paramssemantics.Build a SOMAHandLayer with the selected identity backend.
- Parameters:
data_root (str | Path | None) – Directory containing
SOMAHand.npz,SOMA_neutral.npz, and the per-backend model folders. IfNoneor missing, assets are downloaded from HuggingFace automatically.hand_type (str) –
"left"or"right".device (str | device) – Torch device for all buffers and intermediate tensors (e.g.
"cuda","cpu").identity_model_type (str) – Identity backend. One of
"soma"(default, hand PCA fromSOMAHand.npz),"mano", or"mhr". Seesoma.handfor 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 MANO to pass
model_path.lod (str | None) – Hand mesh level of detail:
"mid"(2,859 vertices per hand),"low"(718 vertices per hand), or"xlo"(134 vertices per hand). Defaults to"mid", or"low"whenlow_lod=True.low_lod (bool) – Legacy alias for
lod="low".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.pt. PassNoneto skip loading correctives.reference_pose (Tensor | dict[str, str] | None) – Default reference tensor or lookup dictionary for
pose()andforward(). Dictionaries resolve once.Noneuses the current T-pose. Seepose()for tensor shapes.
- property default_skin_mesh_name: str#
Default USD skin-mesh prim name for this hand’s topology.
Consumed by
export_soma_usdwhen the caller does not pass an explicitskin_mesh_name. Encodes handedness so left/right exports don’t collide when written into the same stage.
- list_reference_poses()#
List reference keys and metadata in the current core NPZ.
- get_reference_pose(
- reference_id=None,
- *,
- version=None,
- data_key='t_pose_world',
- asset_revision=None,
- alias=None,
Return saved orientations for this hand, including the wrist.
Select one of
version,asset_revision,alias, orreference_id. Version lookup uses the newest stored revision at or before that version; full keys and asset revisions match exactly. No downloads are used.The fresh
(25, 3, 3)tensor uses this layer’s joint order, device, dtype, and current wrist bind frame. Translations are not included.
- convert_reference(rotations, from_ref, to_ref)#
Re-express
(B, 25, 3, 3)rotations in another reference.Both references accept a tensor or
get_reference_pose()dictionary: orientations in this layer’s wrist bind frame, including the wrist. The result preserves absolute local rotations, input device/dtype and gradients. No identity preparation or layer state changes are needed. References are explicit; the constructor default is not used. Pass the result topose(..., pose2rot=False, reference_pose=to_ref).
- get_rest_shape(
- identity_coeffs,
- scale_params=None,
- global_scale=1.0,
- kwargs=None,
Compute hand rest shape from identity coefficients.
- Parameters:
identity_coeffs (Tensor) – (B, K) identity coefficients.
scale_params (Tensor | None) – backend-dependent per-identity scale vector (SOMA: (B, 24); MHR: (B, 26); MANO: unused). See class docstring.
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.
- Returns:
(B, Vh, 3) wrist-local rest shape in output_unit.
- Return type:
Tensor
- 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.
- Parameters:
identity_coeffs (Tensor) – (B, K) identity coefficients.
scale_params (Tensor | None) – backend-dependent per-identity scale vector (SOMA: (B, 24); MHR: (B, 26); MANO: unused). See class docstring. MHR consumes this here; SOMA caches it for
pose().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,
- pose2rot=True,
- apply_correctives=False,
- absolute_pose=False,
- global_translation=None,
- fk_only=False,
- *,
- reference_pose=None,
Pose the cached identity. Call prepare_identity() first.
For the SOMA backend,
scale_paramscached byprepare_identity()are applied here as per-joint bone-length scales (override oflocal_translations). MHR already baked them into the rest shape.- Parameters:
poses (Tensor) – (B, 25, 3) axis-angle, or (B, 25, 3, 3) rot matrices. Joint 0 = global wrist rotation; joints 1-24 = fingers.
pose2rot (bool) – convert axis-angle to rot matrices if True.
apply_correctives (bool) – if True, apply pose-dependent corrective offsets from the shared SOMA body correctives checkpoint.
absolute_pose (bool) – if True, rotations are absolute (not relative to T-pose joint orient). Matches SOMALayer convention.
global_translation (Tensor | None) – (B, 3) or (3,) wrist translation in output_unit. If None, wrist stays at origin.
fk_only (bool) – if True, run forward kinematics only and skip LBS.
reference_pose (Tensor | dict[str, str] | None) –
Noneuses the constructor default, or the current T-pose if none was set. Otherwise, a dictionary ofget_reference_pose()arguments or a(25, 3, 3)/(25, 4, 4)tensor of orientations in this hand’s joint order and current wrist bind frame. Only rotation blocks are used.absolute_pose=Truebypasses the stored default but rejects an explicit reference.
- Returns:
SOMAHandPoseOutput (all translations in
output_unit) –vertices: (B, Vh, 3). Omitted iffk_only=True.joints: (B, 25, 3).transforms: (B, 25, 4, 4).
- Return type:
- forward(
- poses,
- identity_coeffs,
- pose2rot=True,
- apply_correctives=False,
- absolute_pose=False,
- global_translation=None,
- global_scale=1.0,
- scale_params=None,
- kwargs=None,
- *,
- reference_pose=None,
Combined prepare_identity + pose (convenience).
- Parameters:
poses (Tensor) – (B, 25, 3) axis-angle, or (B, 25, 3, 3) rot matrices. Joint 0 = global wrist rotation; joints 1-24 = fingers.
identity_coeffs (Tensor) – (B, K) identity coefficients.
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). Matches SOMALayer convention.
global_translation (Tensor | None) – (B, 3) or (3,) wrist translation in output_unit. If None, wrist stays at origin.
global_scale (float | Tensor) – uniform scale scalar or (B,) tensor. Default 1.0.
scale_params (Tensor | None) – backend-dependent per-identity scale vector (SOMA: (B, 24); MHR: (B, 26); MANO: unused). See class docstring.
kwargs (Mapping[str, Any] | None) – optional dict forwarded to the identity model’s
get_rest_shape.reference_pose (Tensor | dict[str, str] | None) – Reference tensor or lookup dictionary, as in
pose().
- Returns:
SOMAHandPoseOutput (all translations in
output_unit) –vertices: (B, Vh, 3).joints: (B, 25, 3).transforms: (B, 25, 4, 4).
- Return type: