pymomentum.diff_geometry

Differentiable geometry and forward kinematics for momentum models using PyTorch tensors.

pymomentum.diff_geometry.apply_inverse_parameter_transform(inverse_parameter_transform: pymomentum.geometry.InverseParameterTransform, joint_parameters: torch.Tensor) → torch.Tensor

Apply the inverse parameter transform to a [nBatch x nJointParams] tensor of joint parameters. This is functionally identical to pymomentum.geometry.InverseParameterTransform.apply() except that it supports automatic differentiation.

Parameters:
Returns:

a tensor of model parameters.

pymomentum.diff_geometry.apply_model_param_limits(character: pymomentum.geometry.Character, model_params: torch.Tensor) → torch.Tensor

Clamp model parameters by parameter limits stored in Character.

Note the function is differentiable.

Parameters:
  • character – The Character to use.

  • model_params – the (can be batched) body model parameters.

Returns:

clamped model parameters. Same tensor shape as the input.

pymomentum.diff_geometry.apply_parameter_transform(character: object, model_parameters: torch.Tensor) → torch.Tensor

Apply the parameter transform to a [nBatch x nParams] tensor of model parameters. This is functionally identical to pymomentum.geometry.ParameterTransform.apply() except that it allows batching on the character.

Parameters:
Returns:

a tensor of joint parameters.

pymomentum.diff_geometry.compute_blend_shape(blend_shape: object, coeffs: torch.Tensor) → torch.Tensor

Apply the blend shape coefficients to compute the rest shape.

The resulting shape is equal to a linear combination of the shape vectors (plus the base shape, if it is a BlendShape object).

Parameters:
  • blend_shape – A BlendShape or BlendShapeBase object.

  • coeffs – A torch.Tensor of size [n_batch x n_shapes] containing blend shape coefficients.

Result:

A [n_batch x n_vertices x 3] tensor containing the vertex positions.

pymomentum.diff_geometry.compute_vertex_normals(vertex_positions: torch.Tensor, triangles: torch.Tensor) → torch.Tensor

Computes vertex normals for a triangle mesh given its positions.

Parameters:
  • vertex_positions – [nBatch] x nVert x 3 Tensor of vertex positions.

  • triangles – nTriangles x 3 Tensor of triangle indices.

Returns:

Smooth per-vertex normals.

pymomentum.diff_geometry.find_closest_points(*args, **kwargs)

Overloaded function.

  1. find_closest_points(points_source: torch.Tensor, points_target: torch.Tensor, max_dist: float = 3.4028234663852886e+38) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]

For each point in the points_source tensor, find the closest point in the points_target tensor. This version of find_closest points supports both 2- and 3-dimensional point sets.

Parameters:
  • points_source – [nBatch x nPoints x dim] tensor of source points (dim must be 2 or 3).

  • points_target – [nBatch x nPoints x dim] tensor of target points (dim must be 2 or 3).

  • max_dist – Maximum distance to search, can be used to speed up the method by allowing the search to return early. Defaults to FLT_MAX.

Returns:

A tuple of three tensors. The first is [nBatch x nPoints x dim] and contains the closest point for each point in the target set. The second is [nBatch x nPoints] and contains the index of each closest point in the target set (or -1 if none). The third is [nBatch x nPoints] and is a boolean tensor indicating whether a valid closest point was found for each source point.

  1. find_closest_points(points_source: torch.Tensor, normals_source: torch.Tensor, points_target: torch.Tensor, normals_target: torch.Tensor, max_dist: float = 3.4028234663852886e+38, max_normal_dot: float = 0.0) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]

For each point in the points_source tensor, find the closest point in the points_target tensor whose normal is compatible (n_source . n_target > max_normal_dot). Using the normal is a good way to avoid certain kinds of bad matches, such as matching the front of the body against depth values from the back of the body.

Parameters:
  • points_source – [nBatch x nPoints x 3] tensor of source points.

  • normals_source – [nBatch x nPoints x 3] tensor of source normals (must be normalized).

  • points_target – [nBatch x nPoints x 3] tensor of target points.

  • normals_target – [nBatch x nPoints x 3] tensor of target normals (must be normalized).

  • max_dist – Maximum distance to search, can be used to speed up the method by allowing the search to return early. Defaults to FLT_MAX.

  • max_normal_dot – Maximum dot product allowed between the source and target normal. Defaults to 0.

Returns:

A tuple of three tensors. The first is [nBatch x nPoints x dim] and contains the closest point for each point in the target set. The second is [nBatch x nPoints] and contains the index of each closest point in the target set (or -1 if none). The third is [nBatch x nPoints] and is a boolean tensor indicating whether a valid closest point was found for each source point.

pymomentum.diff_geometry.find_closest_points_on_mesh(points_source: torch.Tensor, vertices_target: torch.Tensor, faces_target: torch.Tensor) → tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]

For each point in the points_source tensor, find the closest point in the target mesh.

Parameters:
  • points_source – [nBatch x nPoints x 3] tensor of source points.

  • vertices_target – [nBatch x nVerts x 3] tensor of target mesh vertices.

  • faces_target – [nFaces x 3] tensor of target mesh triangle indices.

Returns:

A tuple of three tensors. The first is [nBatch x nPoints x 3] and contains the closest point on the target mesh. The second is [nBatch x nPoints] and contains the index of the closest triangle (-1 if none). The third is [nBatch x nPoints] and is a boolean tensor indicating whether a valid closest point was found.

pymomentum.diff_geometry.joint_parameters_to_local_skeleton_state(character: object, joint_parameters: torch.Tensor) → torch.Tensor

Map from the 7*nJoints jointParameters (representing transforms to the parent joint) to the 8*nJoints local skeleton state.

The skeletonState is stored (tx, ty, tz; rx, ry, rz, rw; s) and each maps the transform from the joint’s local space to its parent joint space. Rotations are Quaternions in the ((x, y, z), w) format. This is deliberately identical to the representation used in a legacy format.)

Parameters:
Returns:

torch.Tensor of size (nBatch x nJoints x 8) containing the skeleton state; should be also compatible with a legacy format’s skeleton state representation.

pymomentum.diff_geometry.joint_parameters_to_positions(character: object, joint_parameters: torch.Tensor, parents: torch.Tensor, offsets: torch.Tensor) → torch.Tensor

Convert joint parameters to 3D positions relative to skeleton joints using forward kinematics. You can use this (for example) to supervise a model to produce the correct 3D ground truth.

You should prefer model_parameters_to_positions() when working from modelParameters because it is better able to exploit sparsity; this function is provided as a convenience because motion read from external files generally uses jointParameters.

Parameters:
  • character (Union[pymomentum.geometry.Character, List[pymomentum.geometry.Character]]) – Character to use.

  • joint_parameters – Joint parameter tensor, with dimension (nBatch x (7*nJoints)).

  • parents – Joint parents, on for each target position.

  • offsets – 3-d offset in each joint’s local space.

Returns:

Tensor of size (nBatch x nParents x 3), representing the world-space position of each point.

pymomentum.diff_geometry.joint_parameters_to_skeleton_state(character: object, joint_parameters: torch.Tensor) → torch.Tensor

Map from the 7*nJoints jointParameters to the 8*nJoints global skeleton state.

The skeletonState is stored (tx, ty, tz; rx, ry, rz, rw; s) and each maps the transform from the joint’s local space to worldspace. Rotations are Quaternions in the ((x, y, z), w) format. This is deliberately identical to the representation used in a legacy format.)

Parameters:
Returns:

torch.Tensor of size (nBatch x nJoints x 8) containing the skeleton state; should be also compatible with a legacy format’s skeleton state representation.

pymomentum.diff_geometry.local_skeleton_state_to_joint_parameters(character: pymomentum.geometry.Character, local_skel_state: torch.Tensor) → torch.Tensor

Map from the 8*nJoints local skeleton state to the 7*nJoints jointParameters. This performs the following operations:

  • Removing the translation offset.

  • Inverting out the pre-rotation.

  • Converting to Euler angles.

The local skeleton state is stored (tx, ty, tz; rx, ry, rz, rw; s) and each maps the transform from the joint’s local space to its parent joint space. The joint parameters are stored (tx, ty, tz; ry, rz, ry; s) where rotations are in Euler angles and are relative to the parent joint.

Parameters:
  • character – Character to use.

  • local_skel_state – torch.Tensor containing the ([nBatch] x nJoints x 8) skeleton state.

Returns:

torch.Tensor of size ([nBatch] x nJoints x 7) containing the joint parameters.

pymomentum.diff_geometry.map_joint_parameters(motion_data: torch.Tensor, source_character: pymomentum.geometry.Character, target_character: pymomentum.geometry.Character) → torch.Tensor

Remap joint parameters from one character to another.

Parameters:
  • motion_data – The source motion data as a [nFrames x (nBones * 7)] torch.Tensor.

  • source_character – The source character.

  • target_character – The target character to remap onto.

Returns:

The motion with the parameters remapped to match the passed-in Character. The fields with no match are filled with zero.

pymomentum.diff_geometry.map_model_parameters(*args, **kwargs)

Overloaded function.

  1. map_model_parameters(motion_data: torch.Tensor, source_parameter_names: list[str], target_character: pymomentum.geometry.Character, verbose: bool = False) -> torch.Tensor

Remap model parameters from one character to another.

Parameters:
  • motion_data – The source motion data as a nFrames x nParams torch.Tensor.

  • source_parameter_names – The source parameter names as a list of strings (e.g. c.parameterTransform.name).

  • target_character – The target character to remap onto.

Returns:

The motion with the parameters remapped to match the passed-in Character. The fields with no match are filled with zero.

  1. map_model_parameters(motion_data: torch.Tensor, source_character: pymomentum.geometry.Character, target_character: pymomentum.geometry.Character, verbose: bool = True) -> torch.Tensor

Remap model parameters from one character to another.

Parameters:
  • motion_data – The source motion data as a nFrames x nParams torch.Tensor.

  • source_character – The source character.

  • target_character – The target character to remap onto.

  • verbose – If true, print out warnings about missing parameters.

Returns:

The motion with the parameters remapped to match the passed-in Character. The fields with no match are filled with zero.

pymomentum.diff_geometry.model_parameters_to_blend_shape_coefficients(character: pymomentum.geometry.Character, model_parameters: torch.Tensor) → torch.Tensor

Extract the model parameters that correspond to the blend shape coefficients, in the order required to call meth:BlendShape.compute_shape.

Parameters:
  • character – A character.

  • model_parameters – A [nBatch x nParams] tensor of model parameters.

Returns:

A [nBatch x nBlendShape] torch.Tensor of blend shape coefficients.

pymomentum.diff_geometry.model_parameters_to_face_expression_coefficients(character: pymomentum.geometry.Character, model_parameters: torch.Tensor) → torch.Tensor

Extract the model parameters that correspond to the face expression coefficients.

Parameters:
  • character – A character.

  • model_parameters – A [nBatch x nParams] tensor of model parameters.

Returns:

A [nBatch x nFaceExpressions] torch.Tensor of face expression coefficients.

pymomentum.diff_geometry.model_parameters_to_local_skeleton_state(character: object, model_parameters: torch.Tensor) → torch.Tensor

Map from the k modelParameters to the 8*nJoints local skeleton state.

The skeletonState is stored (tx, ty, tz; rx, ry, rz, rw; s) and each maps the transform from the joint’s local space to its parent joint space. Rotations are Quaternions in the ((x, y, z), w) format. This is deliberately identical to the representation used in a legacy format.)

Parameters:
Returns:

torch.Tensor of size (nBatch x nJoints x 8) containing the skeleton state; should be also compatible with a legacy format’s skeleton state representation.

pymomentum.diff_geometry.model_parameters_to_positions(character: object, model_parameters: torch.Tensor, parents: torch.Tensor, offsets: torch.Tensor) → torch.Tensor

Convert model parameters to 3D positions relative to skeleton joints using forward kinematics. You can use this (for example) to supervise a model to produce the correct 3D ground truth.

Working directly from modelParameters is preferable to mapping to jointParameters first because it does a better job exploiting the sparsity in the model and therefore can be made somewhat faster.

Parameters:
  • character (Union[pymomentum.geometry.Character, List[pymomentum.geometry.Character]]) – Character to use.

  • model_parameters – Model parameter tensor, with dimension (nBatch x nModelParams).

  • parents – Joint parents, on for each target position.

  • offsets – 3-d offset in each joint’s local space.

Returns:

Tensor of size (nBatch x nParents x 3), representing the world-space position of each point.

pymomentum.diff_geometry.model_parameters_to_skeleton_state(character: object, model_parameters: torch.Tensor) → torch.Tensor

Map from the k modelParameters to the 8*nJoints global skeleton state.

The skeletonState is stored (tx, ty, tz; rx, ry, rz, rw; s) and each maps the transform from the joint’s local space to worldspace. Rotations are Quaternions in the ((x, y, z), w) format. This is deliberately identical to the representation used in a legacy format.)

Parameters:
Returns:

torch.Tensor of size (nBatch x nJoints x 8) containing the skeleton state; should be also compatible with a legacy format’s skeleton state representation.

pymomentum.diff_geometry.reduce_to_selected_model_parameters(character: pymomentum.geometry.Character, active_parameters: torch.Tensor) → pymomentum.geometry.Character

Strips out unused parameters from the parameter transform.

Parameters:
  • character – Full-body character.

  • active_parameters – A boolean tensor marking which parameters should be retained.

Returns:

A new character whose parameter transform only includes the marked parameters.

pymomentum.diff_geometry.skeleton_state_to_joint_parameters(character: pymomentum.geometry.Character, skel_state: torch.Tensor) → torch.Tensor

Map from the 8*nJoints skeleton state (representing transforms to world-space) to the 7*nJoints jointParameters. This performs the following operations:

  • Removing the translation offset.

  • Inverting out the pre-rotation.

  • Converting to Euler angles.

The skeleton state is stored (tx, ty, tz; rx, ry, rz, rw; s) and transforms from the joint’s local space to world-space. The joint parameters are stored (tx, ty, tz; ry, rz, ry; s) where rotations are in Euler angles and are relative to the parent joint.

Parameters:
  • character – Character to use.

  • skel_state – torch.Tensor containing the ([nBatch] x nJoints x 8) skeleton state.

Returns:

torch.Tensor of size ([nBatch] x nJoints x 7) containing the joint parameters.

pymomentum.diff_geometry.skin_points(character: object, skel_state: torch.Tensor, rest_vertices: torch.Tensor | None = None) → torch.Tensor

Skins the points using the character’s linear blend skinning.

Parameters:
  • character – The Character to use for skinning.

  • skel_state – A torch.Tensor containing either a [nBatch x nJoints x 8] skeleton state or a [nBatch x nJoints x 4 x 4] transforms.

  • rest_vertices – An optional torch.Tensor containing the rest points; if not passed, the ones stored inside the character are used.

Returns:

The vertex positions in worldspace.

pymomentum.diff_geometry.skin_skinned_locators(character: pymomentum.geometry.Character, skel_state: torch.Tensor, rest_positions: torch.Tensor | None = None) → torch.Tensor

Apply linear blend skinning to compute the world-space positions of the character’s skinned locators.

This function uses the character’s built-in skinned locators and applies linear blend skinning to compute their world-space positions given a skeleton state.

Parameters:
  • character – The Character to use.

  • skel_state – Skeleton state tensor with shape [nJoints x 8] or [nBatch x nJoints x 8].

  • rest_positions – Optional rest positions tensor with shape [nLocators x 3] or [nBatch x nLocators x 3]. If not provided, uses the position stored in each SkinnedLocator.

Returns:

Tensor of shape [nLocators x 3] or [nBatch x nLocators x 3] containing the world-space positions of the skinned locators.

pymomentum.diff_geometry.uniform_random_to_model_parameters(character: pymomentum.geometry.Character, unif_noise: torch.Tensor) → torch.Tensor

Convert a uniform noise vector into a valid body pose.

Parameters:
  • character – The character to use.

  • unif_noise – A uniform noise tensor, with dimensions (nBatch x nModelParams).

Returns:

A torch.Tensor with dimensions (nBatch x nModelParams).