Skip to content

Commit 99c018d

Browse files
cdtwiggmeta-codesync[bot]
authored andcommitted
Move parameter transform bindings into their own file. (#721)
Summary: Pull Request resolved: #721 We're trying to break up geometry_pybind to make it easier to deal with. Reviewed By: jeongseok-meta Differential Revision: D85311493 fbshipit-source-id: e9c12e04303ae0f12ac3e0e604e9222be17d2041
1 parent 0373d93 commit 99c018d

File tree

4 files changed

+208
-138
lines changed

4 files changed

+208
-138
lines changed

pymomentum/cmake/build_variables.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ geometry_public_headers = [
103103
"geometry/momentum_geometry.h",
104104
"geometry/momentum_io.h",
105105
"geometry/gltf_builder_pybind.h",
106+
"geometry/parameter_transform_pybind.h",
106107
]
107108

108109
geometry_sources = [
@@ -111,6 +112,7 @@ geometry_sources = [
111112
"geometry/momentum_geometry.cpp",
112113
"geometry/momentum_io.cpp",
113114
"geometry/gltf_builder_pybind.cpp",
115+
"geometry/parameter_transform_pybind.cpp",
114116
]
115117

116118
solver_public_headers = [

pymomentum/geometry/geometry_pybind.cpp

Lines changed: 4 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "pymomentum/geometry/gltf_builder_pybind.h"
99
#include "pymomentum/geometry/momentum_geometry.h"
1010
#include "pymomentum/geometry/momentum_io.h"
11+
#include "pymomentum/geometry/parameter_transform_pybind.h"
1112
#include "pymomentum/geometry/skin_weights_pybind.h"
1213
#include "pymomentum/tensor_momentum/tensor_blend_shape.h"
1314
#include "pymomentum/tensor_momentum/tensor_joint_parameters_to_positions.h"
@@ -2125,144 +2126,6 @@ Create a parameter limit with min and max values for a joint parameter.
21252126
le.offset.z());
21262127
});
21272128

2128-
// =====================================================
2129-
// momentum::ParameterTransform
2130-
// - names
2131-
// - size()
2132-
// - apply(modelParameters)
2133-
// - getScalingParameters()
2134-
// - getRigidParameters()
2135-
// - getParametersForJoints(jointIndices)
2136-
// - createInverseParameterTransform()
2137-
// =====================================================
2138-
parameterTransformClass
2139-
.def(
2140-
py::init([](const std::vector<std::string>& names,
2141-
const mm::Skeleton& skeleton,
2142-
const Eigen::SparseMatrix<float, Eigen::RowMajor>& transform) {
2143-
mm::ParameterTransform parameterTransform;
2144-
parameterTransform.name = names;
2145-
parameterTransform.transform.resize(
2146-
static_cast<int>(skeleton.joints.size()) * mm::kParametersPerJoint,
2147-
static_cast<int>(names.size()));
2148-
2149-
for (int i = 0; i < transform.outerSize(); ++i) {
2150-
for (Eigen::SparseMatrix<float, Eigen::RowMajor>::InnerIterator it(transform, i); it;
2151-
++it) {
2152-
parameterTransform.transform.coeffRef(
2153-
static_cast<long>(it.row()), static_cast<long>(it.col())) = it.value();
2154-
}
2155-
}
2156-
2157-
parameterTransform.offsets.setZero(skeleton.joints.size() * mm::kParametersPerJoint);
2158-
return parameterTransform;
2159-
}),
2160-
py::arg("names"),
2161-
py::arg("skeleton"),
2162-
py::arg("transform"))
2163-
.def_readonly("names", &mm::ParameterTransform::name, "List of model parameter names")
2164-
.def_property_readonly(
2165-
"size",
2166-
&mm::ParameterTransform::numAllModelParameters,
2167-
"Size of the model parameter vector.")
2168-
.def(
2169-
"apply",
2170-
[](const mm::ParameterTransform* paramTransform, torch::Tensor modelParams)
2171-
-> torch::Tensor { return applyParamTransform(paramTransform, modelParams); },
2172-
R"(Apply the parameter transform to a k-dimensional model parameter vector (returns the 7*nJoints joint parameter vector).
2173-
2174-
The modelParameters store the reduced set of parameters (typically around 50) that are actually
2175-
optimized in the IK step.
2176-
2177-
The jointParameters are stored (tx, ty, tz; rx, ry, rz; s) and each represents the transform relative to the parent joint.
2178-
Rotations are in Euler angles.)",
2179-
py::arg("model_parameters"))
2180-
.def_property_readonly(
2181-
"scaling_parameters",
2182-
&getScalingParameters,
2183-
"Boolean torch.Tensor indicating which parameters are used to control the character's scale.")
2184-
.def_property_readonly(
2185-
"rigid_parameters",
2186-
&getRigidParameters,
2187-
"Boolean torch.Tensor indicating which parameters are used to control the character's rigid transform (translation and rotation).")
2188-
.def_property_readonly(
2189-
"all_parameters", &getAllParameters, "Boolean torch.Tensor with all parameters enabled.")
2190-
.def_property_readonly(
2191-
"blend_shape_parameters",
2192-
&getBlendShapeParameters,
2193-
"Boolean torch.Tensor with just the blend shape parameters enabled.")
2194-
.def_property_readonly(
2195-
"pose_parameters",
2196-
&getPoseParameters,
2197-
"Boolean torch.Tensor with all the parameters used to pose the body, excluding and scaling, blend shape, or physics parameters.")
2198-
.def_property_readonly(
2199-
"no_parameters",
2200-
[](const momentum::ParameterTransform& parameterTransform) {
2201-
return parameterSetToTensor(parameterTransform, momentum::ParameterSet());
2202-
},
2203-
"Boolean torch.Tensor with no parameters enabled.")
2204-
.def_property_readonly(
2205-
"parameter_sets",
2206-
&getParameterSets,
2207-
R"(A dictionary mapping names to sets of parameters (as a boolean torch.Tensor) that are defined in the .model file.
2208-
This is convenient for turning off certain body features; for example the 'fingers' parameters
2209-
can be used to enable/disable finger motion in the character model. )")
2210-
.def(
2211-
"parameters_for_joints",
2212-
&getParametersForJoints,
2213-
R"(Gets a boolean torch.Tensor indicating which parameters affect the passed-in joints.
2214-
2215-
:param jointIndices: List of integers of skeleton joints.)",
2216-
py::arg("joint_indices"))
2217-
.def(
2218-
"find_parameters",
2219-
&findParameters,
2220-
R"(Return a boolean tensor with the named parameters set to true.
2221-
2222-
:param parameter_names: Names of the parameters to find.
2223-
:param allow_missng: If false, missing parameters will throw an exception.
2224-
)",
2225-
py::arg("names"),
2226-
py::arg("allow_missing") = false)
2227-
.def(
2228-
"inverse",
2229-
&createInverseParameterTransform,
2230-
R"(Compute the inverse of the parameter transform (a mapping from joint parameters to model parameters).
2231-
2232-
:return: The inverse parameter transform.)")
2233-
.def_property_readonly(
2234-
"transform",
2235-
&getParameterTransformTensor,
2236-
"Returns the parameter transform matrix which when applied maps model parameters to joint parameters.")
2237-
.def("__repr__", [](const mm::ParameterTransform& pt) {
2238-
return fmt::format(
2239-
"ParameterTransform(parameters={}, joints={})",
2240-
pt.numAllModelParameters(),
2241-
pt.transform.rows() / mm::kParametersPerJoint);
2242-
});
2243-
2244-
// =====================================================
2245-
// momentum::InverseParameterTransform
2246-
// - apply()
2247-
// =====================================================
2248-
inverseParameterTransformClass
2249-
.def(
2250-
"apply",
2251-
&applyInverseParamTransform,
2252-
R"(Apply the inverse parameter transform to a 7*nJoints-dimensional joint parameter vector (returns the k-dimensional model parameter vector).
2253-
2254-
Because the number of joint parameters is much larger than the number of model parameters, this will in general have a non-zero residual.
2255-
2256-
:param joint_parameters: Joint parameter tensor with dimensions (nBatch x 7*nJoints).
2257-
:return: A torch.Tensor containing the (nBatch x nModelParameters) model parameters.)",
2258-
py::arg("joint_parameters"))
2259-
.def("__repr__", [](const mm::InverseParameterTransform& ipt) {
2260-
return fmt::format(
2261-
"InverseParameterTransform(parameters={}, joints={})",
2262-
ipt.transform.cols(),
2263-
ipt.transform.rows() / mm::kParametersPerJoint);
2264-
});
2265-
22662129
// =====================================================
22672130
// momentum::Mppca
22682131
// - Mppca()
@@ -3010,6 +2873,9 @@ The character has only one parameter limit: min-max type [-0.1, 0.1] for root.
30102873

30112874
registerSkinWeightsBindings(skinWeightsClass);
30122875

2876+
registerParameterTransformBindings(parameterTransformClass);
2877+
registerInverseParameterTransformBindings(inverseParameterTransformClass);
2878+
30132879
// Register GltfBuilder bindings
30142880
registerGltfBuilderBindings(m);
30152881
}
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#include "pymomentum/geometry/parameter_transform_pybind.h"
9+
10+
#include "pymomentum/geometry/momentum_geometry.h"
11+
#include "pymomentum/tensor_momentum/tensor_parameter_transform.h"
12+
13+
#include <momentum/character/inverse_parameter_transform.h>
14+
#include <momentum/character/parameter_transform.h>
15+
16+
#include <pybind11/eigen.h>
17+
#include <pybind11/pybind11.h>
18+
#include <pybind11/stl.h>
19+
#include <torch/csrc/utils/pybind.h>
20+
#include <torch/python.h>
21+
22+
#include <fmt/format.h>
23+
24+
#include <utility>
25+
26+
namespace py = pybind11;
27+
namespace mm = momentum;
28+
29+
namespace pymomentum {
30+
31+
void registerParameterTransformBindings(
32+
py::class_<mm::ParameterTransform>& parameterTransformClass) {
33+
// =====================================================
34+
// momentum::ParameterTransform
35+
// - names
36+
// - size()
37+
// - apply(modelParameters)
38+
// - getScalingParameters()
39+
// - getRigidParameters()
40+
// - getParametersForJoints(jointIndices)
41+
// - createInverseParameterTransform()
42+
// =====================================================
43+
parameterTransformClass
44+
.def(
45+
py::init([](const std::vector<std::string>& names,
46+
const mm::Skeleton& skeleton,
47+
const Eigen::SparseMatrix<float, Eigen::RowMajor>& transform) {
48+
mm::ParameterTransform parameterTransform;
49+
parameterTransform.name = names;
50+
parameterTransform.transform.resize(
51+
static_cast<int>(skeleton.joints.size()) * mm::kParametersPerJoint,
52+
static_cast<int>(names.size()));
53+
54+
for (int i = 0; i < transform.outerSize(); ++i) {
55+
for (Eigen::SparseMatrix<float, Eigen::RowMajor>::InnerIterator it(transform, i); it;
56+
++it) {
57+
parameterTransform.transform.coeffRef(
58+
static_cast<long>(it.row()), static_cast<long>(it.col())) = it.value();
59+
}
60+
}
61+
62+
parameterTransform.offsets.setZero(skeleton.joints.size() * mm::kParametersPerJoint);
63+
return parameterTransform;
64+
}),
65+
py::arg("names"),
66+
py::arg("skeleton"),
67+
py::arg("transform"))
68+
.def_readonly("names", &mm::ParameterTransform::name, "List of model parameter names")
69+
.def_property_readonly(
70+
"size",
71+
&mm::ParameterTransform::numAllModelParameters,
72+
"Size of the model parameter vector.")
73+
.def(
74+
"apply",
75+
[](const mm::ParameterTransform* paramTransform,
76+
torch::Tensor modelParams) -> torch::Tensor {
77+
return applyParamTransform(paramTransform, std::move(modelParams));
78+
},
79+
R"(Apply the parameter transform to a k-dimensional model parameter vector (returns the 7*nJoints joint parameter vector).
80+
81+
The modelParameters store the reduced set of parameters (typically around 50) that are actually
82+
optimized in the IK step.
83+
84+
The jointParameters are stored (tx, ty, tz; rx, ry, rz; s) and each represents the transform relative to the parent joint.
85+
Rotations are in Euler angles.)",
86+
py::arg("model_parameters"))
87+
.def_property_readonly(
88+
"scaling_parameters",
89+
&getScalingParameters,
90+
"Boolean torch.Tensor indicating which parameters are used to control the character's scale.")
91+
.def_property_readonly(
92+
"rigid_parameters",
93+
&getRigidParameters,
94+
"Boolean torch.Tensor indicating which parameters are used to control the character's rigid transform (translation and rotation).")
95+
.def_property_readonly(
96+
"all_parameters", &getAllParameters, "Boolean torch.Tensor with all parameters enabled.")
97+
.def_property_readonly(
98+
"blend_shape_parameters",
99+
&getBlendShapeParameters,
100+
"Boolean torch.Tensor with just the blend shape parameters enabled.")
101+
.def_property_readonly(
102+
"pose_parameters",
103+
&getPoseParameters,
104+
"Boolean torch.Tensor with all the parameters used to pose the body, excluding and scaling, blend shape, or physics parameters.")
105+
.def_property_readonly(
106+
"no_parameters",
107+
[](const momentum::ParameterTransform& parameterTransform) {
108+
return parameterSetToTensor(parameterTransform, momentum::ParameterSet());
109+
},
110+
"Boolean torch.Tensor with no parameters enabled.")
111+
.def_property_readonly(
112+
"parameter_sets",
113+
&getParameterSets,
114+
R"(A dictionary mapping names to sets of parameters (as a boolean torch.Tensor) that are defined in the .model file.
115+
This is convenient for turning off certain body features; for example the 'fingers' parameters
116+
can be used to enable/disable finger motion in the character model. )")
117+
.def(
118+
"parameters_for_joints",
119+
&getParametersForJoints,
120+
R"(Gets a boolean torch.Tensor indicating which parameters affect the passed-in joints.
121+
122+
:param jointIndices: List of integers of skeleton joints.)",
123+
py::arg("joint_indices"))
124+
.def(
125+
"find_parameters",
126+
&findParameters,
127+
R"(Return a boolean tensor with the named parameters set to true.
128+
129+
:param parameter_names: Names of the parameters to find.
130+
:param allow_missng: If false, missing parameters will throw an exception.
131+
)",
132+
py::arg("names"),
133+
py::arg("allow_missing") = false)
134+
.def(
135+
"inverse",
136+
&createInverseParameterTransform,
137+
R"(Compute the inverse of the parameter transform (a mapping from joint parameters to model parameters).
138+
139+
:return: The inverse parameter transform.)")
140+
.def_property_readonly(
141+
"transform",
142+
&getParameterTransformTensor,
143+
"Returns the parameter transform matrix which when applied maps model parameters to joint parameters.")
144+
.def("__repr__", [](const mm::ParameterTransform& pt) {
145+
return fmt::format(
146+
"ParameterTransform(parameters={}, joints={})",
147+
pt.numAllModelParameters(),
148+
pt.transform.rows() / mm::kParametersPerJoint);
149+
});
150+
}
151+
152+
void registerInverseParameterTransformBindings(
153+
py::class_<mm::InverseParameterTransform>& inverseParameterTransformClass) {
154+
// =====================================================
155+
// momentum::InverseParameterTransform
156+
// - apply()
157+
// =====================================================
158+
inverseParameterTransformClass
159+
.def(
160+
"apply",
161+
&applyInverseParamTransform,
162+
R"(Apply the inverse parameter transform to a 7*nJoints-dimensional joint parameter vector (returns the k-dimensional model parameter vector).
163+
164+
Because the number of joint parameters is much larger than the number of model parameters, this will in general have a non-zero residual.
165+
166+
:param joint_parameters: Joint parameter tensor with dimensions (nBatch x 7*nJoints).
167+
:return: A torch.Tensor containing the (nBatch x nModelParameters) model parameters.)",
168+
py::arg("joint_parameters"))
169+
.def("__repr__", [](const mm::InverseParameterTransform& ipt) {
170+
return fmt::format(
171+
"InverseParameterTransform(parameters={}, joints={})",
172+
ipt.transform.cols(),
173+
ipt.transform.rows() / mm::kParametersPerJoint);
174+
});
175+
}
176+
177+
} // namespace pymomentum
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#pragma once
9+
10+
#include <momentum/character/inverse_parameter_transform.h>
11+
#include <momentum/character/parameter_transform.h>
12+
13+
#include <pybind11/pybind11.h>
14+
15+
#include <ATen/ATen.h>
16+
17+
namespace pymomentum {
18+
19+
void registerParameterTransformBindings(
20+
pybind11::class_<momentum::ParameterTransform>& parameterTransformClass);
21+
22+
void registerInverseParameterTransformBindings(
23+
pybind11::class_<momentum::InverseParameterTransform>& inverseParameterTransformClass);
24+
25+
} // namespace pymomentum

0 commit comments

Comments
 (0)