1212#include " momentum/character/blend_shape_skinning.h"
1313#include " momentum/character/character.h"
1414#include " momentum/character/linear_skinning.h"
15+ #include " momentum/character/mesh_state.h"
1516#include " momentum/character/skeleton.h"
1617#include " momentum/character/skeleton_state.h"
1718#include " momentum/character/skin_weights.h"
@@ -36,9 +37,6 @@ VertexProjectionErrorFunctionT<T>::VertexProjectionErrorFunctionT(
3637 maxThreads_(maxThreads) {
3738 MT_CHECK (static_cast <bool >(character_in.mesh ));
3839 MT_CHECK (static_cast <bool >(character_in.skinWeights ));
39- this ->neutralMesh_ = std::make_unique<MeshT<T>>(character_in.mesh ->template cast <T>());
40- this ->restMesh_ = std::make_unique<MeshT<T>>(character_in.mesh ->template cast <T>());
41- this ->posedMesh_ = std::make_unique<MeshT<T>>(character_in.mesh ->template cast <T>());
4240}
4341
4442template <typename T>
@@ -64,10 +62,11 @@ template <typename T>
6462double VertexProjectionErrorFunctionT<T>::getError(
6563 const ModelParametersT<T>& modelParameters,
6664 const SkeletonStateT<T>& state,
67- const MeshStateT<T>& /* meshState */ ) {
65+ const MeshStateT<T>& meshState) {
6866 MT_PROFILE_FUNCTION ();
6967
70- updateMeshes (modelParameters, state);
68+ MT_CHECK_NOTNULL (meshState.posedMesh_ );
69+ MT_CHECK_NOTNULL (meshState.restMesh_ );
7170
7271 // loop over all constraints and calculate the error
7372 double error = 0.0 ;
@@ -76,7 +75,7 @@ double VertexProjectionErrorFunctionT<T>::getError(
7675 const VertexProjectionConstraintT<T>& constr = constraints_[i];
7776
7877 const Eigen::Vector3<T> p_projected =
79- constr.projection * this -> posedMesh_ ->vertices [constr.vertexIndex ].homogeneous ();
78+ constr.projection * meshState. posedMesh_ ->vertices [constr.vertexIndex ].homogeneous ();
8079
8180 // Behind camera:
8281 if (p_projected.z () < _nearClip) {
@@ -115,9 +114,10 @@ template <typename T>
115114double VertexProjectionErrorFunctionT<T>::calculateGradient(
116115 const ModelParametersT<T>& /* modelParameters */ ,
117116 const SkeletonStateT<T>& state,
117+ const MeshStateT<T>& meshState,
118118 const VertexProjectionConstraintT<T>& constr,
119119 Eigen::Ref<Eigen::VectorX<T>> gradient) const {
120- const Eigen::Vector3<T>& p_world_cm = this -> posedMesh_ ->vertices [constr.vertexIndex ];
120+ const Eigen::Vector3<T>& p_world_cm = meshState. posedMesh_ ->vertices [constr.vertexIndex ];
121121 const Eigen::Vector3<T> p_projected_cm = constr.projection * p_world_cm.homogeneous ();
122122
123123 // Behind camera:
@@ -148,7 +148,7 @@ double VertexProjectionErrorFunctionT<T>::calculateGradient(
148148 };
149149
150150 SkinningWeightIteratorT<T> skinningIter (
151- this ->character_ , *this -> restMesh_ , state, constr.vertexIndex );
151+ this ->character_ , *meshState. restMesh_ , state, constr.vertexIndex );
152152
153153 // IN handle derivatives wrt jointParameters
154154 while (!skinningIter.finished ()) {
@@ -244,10 +244,11 @@ template <typename T>
244244double VertexProjectionErrorFunctionT<T>::calculateJacobian(
245245 const ModelParametersT<T>& /* modelParameters */ ,
246246 const SkeletonStateT<T>& state,
247+ const MeshStateT<T>& meshState,
247248 const VertexProjectionConstraintT<T>& constr,
248249 Ref<Eigen::MatrixX<T>> jac,
249250 Ref<Eigen::VectorX<T>> res) const {
250- const Eigen::Vector3<T>& p_world_cm = this -> posedMesh_ ->vertices [constr.vertexIndex ];
251+ const Eigen::Vector3<T>& p_world_cm = meshState. posedMesh_ ->vertices [constr.vertexIndex ];
251252 const Eigen::Vector3<T> p_projected_cm = constr.projection * p_world_cm.homogeneous ();
252253
253254 // Behind camera:
@@ -277,7 +278,7 @@ double VertexProjectionErrorFunctionT<T>::calculateJacobian(
277278 };
278279
279280 SkinningWeightIteratorT<T> skinningIter (
280- this ->character_ , *this -> restMesh_ , state, constr.vertexIndex );
281+ this ->character_ , *meshState. restMesh_ , state, constr.vertexIndex );
281282
282283 // IN handle derivatives wrt jointParameters
283284 while (!skinningIter.finished ()) {
@@ -373,9 +374,10 @@ template <typename T>
373374double VertexProjectionErrorFunctionT<T>::getGradient(
374375 const ModelParametersT<T>& modelParameters,
375376 const SkeletonStateT<T>& state,
376- const MeshStateT<T>& /* meshState */ ,
377+ const MeshStateT<T>& meshState,
377378 Eigen::Ref<Eigen::VectorX<T>> gradient) {
378- updateMeshes (modelParameters, state);
379+ MT_CHECK (
380+ meshState.posedMesh_ , " MeshState must have posed mesh for VertexProjectionErrorFunction" );
379381
380382 double error = 0 ;
381383 std::vector<std::tuple<double , VectorX<T>>> errorGradThread;
@@ -393,7 +395,8 @@ double VertexProjectionErrorFunctionT<T>::getGradient(
393395 [&](std::tuple<double , VectorX<T>>& errorGradLocal, const size_t iCons) {
394396 double & errorLocal = std::get<0 >(errorGradLocal);
395397 auto & gradLocal = std::get<1 >(errorGradLocal);
396- errorLocal += calculateGradient (modelParameters, state, constraints_[iCons], gradLocal);
398+ errorLocal +=
399+ calculateGradient (modelParameters, state, meshState, constraints_[iCons], gradLocal);
397400 },
398401 dispensoOptions);
399402
@@ -418,7 +421,7 @@ template <typename T>
418421double VertexProjectionErrorFunctionT<T>::getJacobian(
419422 const ModelParametersT<T>& modelParameters,
420423 const SkeletonStateT<T>& state,
421- const MeshStateT<T>& /* meshState */ ,
424+ const MeshStateT<T>& meshState,
422425 Eigen::Ref<Eigen::MatrixX<T>> jacobian,
423426 Eigen::Ref<Eigen::VectorX<T>> residual,
424427 int & usedRows) {
@@ -427,7 +430,8 @@ double VertexProjectionErrorFunctionT<T>::getJacobian(
427430 MT_CHECK (jacobian.rows () >= (Eigen::Index)(1 * constraints_.size ()));
428431 MT_CHECK (residual.rows () >= (Eigen::Index)(1 * constraints_.size ()));
429432
430- updateMeshes (modelParameters, state);
433+ MT_CHECK_NOTNULL (meshState.posedMesh_ );
434+ MT_CHECK (meshState.restMesh_ );
431435
432436 double error = 0 ;
433437 std::vector<double > errorThread;
@@ -444,6 +448,7 @@ double VertexProjectionErrorFunctionT<T>::getJacobian(
444448 errorLocal += calculateJacobian (
445449 modelParameters,
446450 state,
451+ meshState,
447452 constraints_[iCons],
448453 jacobian.block (2 * iCons, 0 , 2 , modelParameters.size ()),
449454 residual.middleRows (2 * iCons, 2 ));
@@ -463,49 +468,6 @@ size_t VertexProjectionErrorFunctionT<T>::getJacobianSize() const {
463468 return 2 * constraints_.size ();
464469}
465470
466- template <typename T>
467- void VertexProjectionErrorFunctionT<T>::updateMeshes(
468- const ModelParametersT<T>& modelParameters,
469- const SkeletonStateT<T>& state) {
470- MT_PROFILE_FUNCTION ();
471-
472- bool doUpdateNormals = false ;
473- if (this ->character_ .blendShape ) {
474- const BlendWeightsT<T> blendWeights =
475- extractBlendWeights (this ->parameterTransform_ , modelParameters);
476- this ->character_ .blendShape ->computeShape (blendWeights, this ->restMesh_ ->vertices );
477- doUpdateNormals = true ;
478- }
479- if (this ->character_ .faceExpressionBlendShape ) {
480- if (!this ->character_ .blendShape ) {
481- // Set restMesh back to neutral, removing potential previous expressions.
482- // Note that if the character comes with (shape) blendShape, the previous if block already
483- // takes care of this step.
484- Eigen::Map<Eigen::VectorX<T>> outputVec (
485- &this ->restMesh_ ->vertices [0 ][0 ], this ->restMesh_ ->vertices .size () * 3 );
486- const Eigen::Map<Eigen::VectorX<T>> baseVec (
487- &this ->neutralMesh_ ->vertices [0 ][0 ], this ->neutralMesh_ ->vertices .size () * 3 );
488- outputVec = baseVec.template cast <T>();
489- }
490- const BlendWeightsT<T> faceExpressionBlendWeights =
491- extractFaceExpressionBlendWeights (this ->parameterTransform_ , modelParameters);
492- this ->character_ .faceExpressionBlendShape ->applyDeltas (
493- faceExpressionBlendWeights, this ->restMesh_ ->vertices );
494- doUpdateNormals = true ;
495- }
496- if (doUpdateNormals) {
497- this ->restMesh_ ->updateNormals ();
498- }
499-
500- applySSD (
501- cast<T>(character_.inverseBindPose ),
502- *this ->character_ .skinWeights ,
503- *this ->restMesh_ ,
504- state,
505- *this ->posedMesh_ );
506- // TODO should we call updateNormals() here too or trust the ones from skinning?
507- }
508-
509471template class VertexProjectionErrorFunctionT <float >;
510472template class VertexProjectionErrorFunctionT <double >;
511473
0 commit comments