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"
@@ -38,9 +39,6 @@ PointTriangleVertexErrorFunctionT<T>::PointTriangleVertexErrorFunctionT(
3839 character_in.faceExpressionBlendShape && (type != VertexConstraintType::Position),
3940 " Constraint type {} not implemented yet for face. Only Position type is supported." ,
4041 toString (type));
41- this ->neutralMesh_ = std::make_unique<MeshT<T>>(character_in.mesh ->template cast <T>());
42- this ->restMesh_ = std::make_unique<MeshT<T>>(character_in.mesh ->template cast <T>());
43- this ->posedMesh_ = std::make_unique<MeshT<T>>(character_in.mesh ->template cast <T>());
4442}
4543
4644template <typename T>
@@ -97,10 +95,10 @@ template <typename T>
9795double PointTriangleVertexErrorFunctionT<T>::getError(
9896 const ModelParametersT<T>& modelParameters,
9997 const SkeletonStateT<T>& state,
100- const MeshStateT<T>& /* meshState */ ) {
98+ const MeshStateT<T>& meshState) {
10199 MT_PROFILE_FUNCTION ();
102100
103- updateMeshes (modelParameters, state );
101+ MT_CHECK_NOTNULL (meshState. posedMesh_ );
104102
105103 // loop over all constraints and calculate the error
106104 double error = 0.0 ;
@@ -109,8 +107,8 @@ double PointTriangleVertexErrorFunctionT<T>::getError(
109107 for (size_t i = 0 ; i < constraints_.size (); ++i) {
110108 const PointTriangleVertexConstraintT<T>& constr = constraints_[i];
111109
112- const Eigen::Vector3<T> srcPoint = this -> posedMesh_ ->vertices [constr.srcVertexIndex ];
113- const Eigen::Vector3<T> tgtPoint = computeTargetPosition (*this -> posedMesh_ , constr);
110+ const Eigen::Vector3<T> srcPoint = meshState. posedMesh_ ->vertices [constr.srcVertexIndex ];
111+ const Eigen::Vector3<T> tgtPoint = computeTargetPosition (*meshState. posedMesh_ , constr);
114112 const Eigen::Vector3<T> diff = srcPoint - tgtPoint;
115113 error += constr.weight * diff.squaredNorm () * kPositionWeight ;
116114 }
@@ -119,13 +117,13 @@ double PointTriangleVertexErrorFunctionT<T>::getError(
119117 for (size_t i = 0 ; i < constraints_.size (); ++i) {
120118 const PointTriangleVertexConstraintT<T>& constr = constraints_[i];
121119
122- const Eigen::Vector3<T> srcPoint = this -> posedMesh_ ->vertices [constr.srcVertexIndex ];
120+ const Eigen::Vector3<T> srcPoint = meshState. posedMesh_ ->vertices [constr.srcVertexIndex ];
123121
124- const Eigen::Vector3<T> sourceNormal = this -> posedMesh_ ->normals [constr.srcVertexIndex ];
125- Eigen::Vector3<T> targetNormal = computeTargetTriangleNormal (*this -> posedMesh_ , constr);
122+ const Eigen::Vector3<T> sourceNormal = meshState. posedMesh_ ->normals [constr.srcVertexIndex ];
123+ Eigen::Vector3<T> targetNormal = computeTargetTriangleNormal (*meshState. posedMesh_ , constr);
126124
127125 const Eigen::Vector3<T> tgtPoint =
128- computeTargetBaryPosition (*this -> posedMesh_ , constr) + constr.depth * targetNormal;
126+ computeTargetBaryPosition (*meshState. posedMesh_ , constr) + constr.depth * targetNormal;
129127
130128 if (sourceNormal.dot (targetNormal) < 0 ) {
131129 targetNormal *= -1 ;
@@ -215,18 +213,19 @@ template <typename T>
215213double PointTriangleVertexErrorFunctionT<T>::calculatePositionGradient(
216214 const ModelParametersT<T>& modelParameters,
217215 const SkeletonStateT<T>& state,
216+ const MeshStateT<T>& meshState,
218217 const PointTriangleVertexConstraintT<T>& constr,
219218 Eigen::Ref<Eigen::VectorX<T>> gradient) const {
220- const Eigen::Vector3<T> srcPos = this -> posedMesh_ ->vertices [constr.srcVertexIndex ];
221- const Eigen::Vector3<T> tgtPos = computeTargetPosition (*this -> posedMesh_ , constr);
219+ const Eigen::Vector3<T> srcPos = meshState. posedMesh_ ->vertices [constr.srcVertexIndex ];
220+ const Eigen::Vector3<T> tgtPos = computeTargetPosition (*meshState. posedMesh_ , constr);
222221
223222 const Eigen::Vector3<T> diff = srcPos - tgtPos;
224223
225224 // calculate the difference between target and position and error
226225 const T wgt = constr.weight * 2 .0f * kPositionWeight * this ->weight_ ;
227226
228227 const auto d_targetPos_d_tgtTriVertexPos =
229- compute_d_targetPos_d_vertexPos (constr, *this -> posedMesh_ );
228+ compute_d_targetPos_d_vertexPos (constr, *meshState. posedMesh_ );
230229
231230 // To simplify things we'll have one loop that goes through all 3 target triangle vertices _and_
232231 // the source vertex.
@@ -240,7 +239,8 @@ double PointTriangleVertexErrorFunctionT<T>::calculatePositionGradient(
240239 ? Eigen::Matrix3<T>(-d_targetPos_d_tgtTriVertexPos[iTriVert])
241240 : Eigen::Matrix3<T>::Identity ();
242241
243- SkinningWeightIteratorT<T> skinningIter (this ->character_ , *this ->restMesh_ , state, vertexIndex);
242+ SkinningWeightIteratorT<T> skinningIter (
243+ this ->character_ , *meshState.restMesh_ , state, vertexIndex);
244244
245245 // IN handle derivatives wrt jointParameters
246246 while (!skinningIter.finished ()) {
@@ -394,22 +394,23 @@ template <typename T>
394394double PointTriangleVertexErrorFunctionT<T>::calculatePositionJacobian(
395395 const ModelParametersT<T>& modelParameters,
396396 const SkeletonStateT<T>& state,
397+ const MeshStateT<T>& meshState,
397398 const PointTriangleVertexConstraintT<T>& constr,
398399 Ref<Eigen::MatrixX<T>> jac,
399400 Ref<Eigen::VectorX<T>> res) const {
400401 // calculate the difference between target and position and error
401- const Eigen::Vector3<T> srcPos = this -> posedMesh_ ->vertices [constr.srcVertexIndex ];
402- const Eigen::Vector3<T> tgtPos = computeTargetPosition (*this -> posedMesh_ , constr);
402+ const Eigen::Vector3<T> srcPos = meshState. posedMesh_ ->vertices [constr.srcVertexIndex ];
403+ const Eigen::Vector3<T> tgtPos = computeTargetPosition (*meshState. posedMesh_ , constr);
403404
404405 // The derivative of the target position wrt the triangle vertices:
405406 // p_tgt = bary_0 * p_0 + bary_1 * p_1 + bary_2 * p_2 + depth * n
406407
407- const Eigen::Vector3<T> diff = this -> posedMesh_ ->vertices [constr.srcVertexIndex ] - tgtPos;
408+ const Eigen::Vector3<T> diff = meshState. posedMesh_ ->vertices [constr.srcVertexIndex ] - tgtPos;
408409
409410 const T wgt = std::sqrt (constr.weight * kPositionWeight * this ->weight_ );
410411
411412 const auto d_targetPos_d_tgtTriVertexPos =
412- compute_d_targetPos_d_vertexPos (constr, *this -> posedMesh_ );
413+ compute_d_targetPos_d_vertexPos (constr, *meshState. posedMesh_ );
413414
414415// Verify derivative:
415416#if 0
@@ -450,7 +451,8 @@ double PointTriangleVertexErrorFunctionT<T>::calculatePositionJacobian(
450451 ? Eigen::Matrix3<T>(-d_targetPos_d_tgtTriVertexPos[iTriVert])
451452 : Eigen::Matrix3<T>::Identity ();
452453
453- SkinningWeightIteratorT<T> skinningIter (this ->character_ , *this ->restMesh_ , state, vertexIndex);
454+ SkinningWeightIteratorT<T> skinningIter (
455+ this ->character_ , *meshState.restMesh_ , state, vertexIndex);
454456
455457 // IN handle derivatives wrt jointParameters
456458 while (!skinningIter.finished ()) {
@@ -547,13 +549,14 @@ template <typename T>
547549double PointTriangleVertexErrorFunctionT<T>::calculateNormalGradient(
548550 const ModelParametersT<T>& modelParameters,
549551 const SkeletonStateT<T>& state,
552+ const MeshStateT<T>& meshState,
550553 const PointTriangleVertexConstraintT<T>& constr,
551554 const T sourceNormalWeight,
552555 const T targetNormalWeight,
553556 Eigen::Ref<Eigen::VectorX<T>> gradient) const {
554- const Eigen::Vector3<T> sourceNormal = posedMesh_->normals [constr.srcVertexIndex ];
555- Eigen::Vector3<T> targetNormal = computeTargetTriangleNormal (*this -> posedMesh_ , constr);
556- const Eigen::Vector3<T> tgtPosition = computeTargetPosition (*this -> posedMesh_ , constr);
557+ const Eigen::Vector3<T> sourceNormal = meshState. posedMesh_ ->normals [constr.srcVertexIndex ];
558+ Eigen::Vector3<T> targetNormal = computeTargetTriangleNormal (*meshState. posedMesh_ , constr);
559+ const Eigen::Vector3<T> tgtPosition = computeTargetPosition (*meshState. posedMesh_ , constr);
557560
558561 T targetNormalSign = 1 ;
559562 if (sourceNormal.dot (targetNormal) < 0 ) {
@@ -564,15 +567,16 @@ double PointTriangleVertexErrorFunctionT<T>::calculateNormalGradient(
564567 sourceNormalWeight * sourceNormal + targetNormalWeight * targetNormal;
565568
566569 // calculate the difference between target and position and error
567- const Eigen::Vector3<T> diff = this ->posedMesh_ ->vertices [constr.srcVertexIndex ] - tgtPosition;
570+ const Eigen::Vector3<T> diff =
571+ meshState.posedMesh_ ->vertices [constr.srcVertexIndex ] - tgtPosition;
568572 const T dist = diff.dot (normal);
569573
570574 const T wgt = constr.weight * 2 .0f * kPlaneWeight * this ->weight_ ;
571575
572576 const auto d_targetPos_d_tgtTriVertexPos =
573- compute_d_targetPos_d_vertexPos (constr, *this -> posedMesh_ );
577+ compute_d_targetPos_d_vertexPos (constr, *meshState. posedMesh_ );
574578 const auto d_targetNormal_d_tgtTriVertexPos =
575- compute_d_targetNormal_d_vertexPos (constr, *this -> posedMesh_ );
579+ compute_d_targetNormal_d_vertexPos (constr, *meshState. posedMesh_ );
576580
577581 for (int iTriVert = 0 ; iTriVert < 4 ; ++iTriVert) {
578582 const auto vertexIndex =
@@ -582,7 +586,8 @@ double PointTriangleVertexErrorFunctionT<T>::calculateNormalGradient(
582586 ? Eigen::Matrix3<T>(-d_targetPos_d_tgtTriVertexPos[iTriVert])
583587 : Eigen::Matrix3<T>::Identity ();
584588
585- SkinningWeightIteratorT<T> skinningIter (this ->character_ , *this ->restMesh_ , state, vertexIndex);
589+ SkinningWeightIteratorT<T> skinningIter (
590+ this ->character_ , *meshState.restMesh_ , state, vertexIndex);
586591
587592 // IN handle derivatives wrt jointParameters
588593 while (!skinningIter.finished ()) {
@@ -681,14 +686,15 @@ template <typename T>
681686double PointTriangleVertexErrorFunctionT<T>::calculateNormalJacobian(
682687 const ModelParametersT<T>& modelParameters,
683688 const SkeletonStateT<T>& state,
689+ const MeshStateT<T>& meshState,
684690 const PointTriangleVertexConstraintT<T>& constr,
685691 const T sourceNormalWeight,
686692 const T targetNormalWeight,
687693 Ref<Eigen::MatrixX<T>> jac,
688694 T& res) const {
689- const Eigen::Vector3<T> sourceNormal = posedMesh_->normals [constr.srcVertexIndex ];
690- Eigen::Vector3<T> targetNormal = computeTargetTriangleNormal (*this -> posedMesh_ , constr);
691- const Eigen::Vector3<T> tgtPosition = computeTargetPosition (*this -> posedMesh_ , constr);
695+ const Eigen::Vector3<T> sourceNormal = meshState. posedMesh_ ->normals [constr.srcVertexIndex ];
696+ Eigen::Vector3<T> targetNormal = computeTargetTriangleNormal (*meshState. posedMesh_ , constr);
697+ const Eigen::Vector3<T> tgtPosition = computeTargetPosition (*meshState. posedMesh_ , constr);
692698
693699 T targetNormalSign = 1 ;
694700 if (sourceNormal.dot (targetNormal) < 0 ) {
@@ -699,15 +705,16 @@ double PointTriangleVertexErrorFunctionT<T>::calculateNormalJacobian(
699705 sourceNormalWeight * sourceNormal + targetNormalWeight * targetNormal;
700706
701707 // calculate the difference between target and position and error
702- const Eigen::Vector3<T> diff = this ->posedMesh_ ->vertices [constr.srcVertexIndex ] - tgtPosition;
708+ const Eigen::Vector3<T> diff =
709+ meshState.posedMesh_ ->vertices [constr.srcVertexIndex ] - tgtPosition;
703710 const T dist = diff.dot (normal);
704711
705712 const T wgt = std::sqrt (constr.weight * kPositionWeight * this ->weight_ );
706713
707714 const auto d_targetPos_d_tgtTriVertexPos =
708- compute_d_targetPos_d_vertexPos (constr, *this -> posedMesh_ );
715+ compute_d_targetPos_d_vertexPos (constr, *meshState. posedMesh_ );
709716 const auto d_targetNormal_d_tgtTriVertexPos =
710- compute_d_targetNormal_d_vertexPos (constr, *this -> posedMesh_ );
717+ compute_d_targetNormal_d_vertexPos (constr, *meshState. posedMesh_ );
711718
712719 for (int iTriVert = 0 ; iTriVert < 4 ; ++iTriVert) {
713720 const auto vertexIndex =
@@ -717,7 +724,8 @@ double PointTriangleVertexErrorFunctionT<T>::calculateNormalJacobian(
717724 ? Eigen::Matrix3<T>(-d_targetPos_d_tgtTriVertexPos[iTriVert])
718725 : Eigen::Matrix3<T>::Identity ();
719726
720- SkinningWeightIteratorT<T> skinningIter (this ->character_ , *this ->restMesh_ , state, vertexIndex);
727+ SkinningWeightIteratorT<T> skinningIter (
728+ this ->character_ , *meshState.restMesh_ , state, vertexIndex);
721729
722730 // IN handle derivatives wrt jointParameters
723731 while (!skinningIter.finished ()) {
@@ -827,15 +835,16 @@ template <typename T>
827835double PointTriangleVertexErrorFunctionT<T>::getGradient(
828836 const ModelParametersT<T>& modelParameters,
829837 const SkeletonStateT<T>& state,
830- const MeshStateT<T>& /* meshState */ ,
838+ const MeshStateT<T>& meshState,
831839 Eigen::Ref<Eigen::VectorX<T>> gradient) {
832- updateMeshes (modelParameters, state );
840+ MT_CHECK_NOTNULL (meshState. posedMesh_ );
833841
834842 double error = 0 ;
835843
836844 if (constraintType_ == VertexConstraintType::Position) {
837845 for (size_t iCons = 0 ; iCons < constraints_.size (); ++iCons) {
838- error += calculatePositionGradient (modelParameters, state, constraints_[iCons], gradient);
846+ error += calculatePositionGradient (
847+ modelParameters, state, meshState, constraints_[iCons], gradient);
839848 }
840849 } else {
841850 T sourceNormalWeight;
@@ -846,6 +855,7 @@ double PointTriangleVertexErrorFunctionT<T>::getGradient(
846855 error += calculateNormalGradient (
847856 modelParameters,
848857 state,
858+ meshState,
849859 constraints_[iCons],
850860 sourceNormalWeight,
851861 targetNormalWeight,
@@ -860,7 +870,7 @@ template <typename T>
860870double PointTriangleVertexErrorFunctionT<T>::getJacobian(
861871 const ModelParametersT<T>& modelParameters,
862872 const SkeletonStateT<T>& state,
863- const MeshStateT<T>& /* meshState */ ,
873+ const MeshStateT<T>& meshState,
864874 Eigen::Ref<Eigen::MatrixX<T>> jacobian,
865875 Eigen::Ref<Eigen::VectorX<T>> residual,
866876 int & usedRows) {
@@ -869,7 +879,7 @@ double PointTriangleVertexErrorFunctionT<T>::getJacobian(
869879 MT_CHECK (jacobian.rows () >= (Eigen::Index)(1 * constraints_.size ()));
870880 MT_CHECK (residual.rows () >= (Eigen::Index)(1 * constraints_.size ()));
871881
872- updateMeshes (modelParameters, state );
882+ MT_CHECK_NOTNULL (meshState. posedMesh_ );
873883
874884 double error = 0 ;
875885
@@ -880,6 +890,7 @@ double PointTriangleVertexErrorFunctionT<T>::getJacobian(
880890 error += calculatePositionJacobian (
881891 modelParameters,
882892 state,
893+ meshState,
883894 constraints_[iCons],
884895 jacobian.block (3 * iCons, 0 , 3 , modelParameters.size ()),
885896 residual.middleRows (3 * iCons, 3 ));
@@ -895,6 +906,7 @@ double PointTriangleVertexErrorFunctionT<T>::getJacobian(
895906 error += calculateNormalJacobian (
896907 modelParameters,
897908 state,
909+ meshState,
898910 constraints_[iCons],
899911 sourceNormalWeight,
900912 targetNormalWeight,
@@ -921,49 +933,6 @@ size_t PointTriangleVertexErrorFunctionT<T>::getJacobianSize() const {
921933 }
922934}
923935
924- template <typename T>
925- void PointTriangleVertexErrorFunctionT<T>::updateMeshes(
926- const ModelParametersT<T>& modelParameters,
927- const SkeletonStateT<T>& state) {
928- MT_PROFILE_FUNCTION ();
929-
930- bool doUpdateNormals = false ;
931- if (this ->character_ .blendShape ) {
932- const BlendWeightsT<T> blendWeights =
933- extractBlendWeights (this ->parameterTransform_ , modelParameters);
934- this ->character_ .blendShape ->computeShape (blendWeights, this ->restMesh_ ->vertices );
935- doUpdateNormals = true ;
936- }
937- if (this ->character_ .faceExpressionBlendShape ) {
938- if (!this ->character_ .blendShape ) {
939- // Set restMesh back to neutral, removing potential previous expressions.
940- // Note that if the character comes with (shape) blendShape, the previous if block already
941- // takes care of this step.
942- Eigen::Map<Eigen::VectorX<T>> outputVec (
943- &this ->restMesh_ ->vertices [0 ][0 ], this ->restMesh_ ->vertices .size () * 3 );
944- const Eigen::Map<Eigen::VectorX<T>> baseVec (
945- &this ->neutralMesh_ ->vertices [0 ][0 ], this ->neutralMesh_ ->vertices .size () * 3 );
946- outputVec = baseVec.template cast <T>();
947- }
948- const BlendWeightsT<T> faceExpressionBlendWeights =
949- extractFaceExpressionBlendWeights (this ->parameterTransform_ , modelParameters);
950- this ->character_ .faceExpressionBlendShape ->applyDeltas (
951- faceExpressionBlendWeights, this ->restMesh_ ->vertices );
952- doUpdateNormals = true ;
953- }
954- if (doUpdateNormals) {
955- this ->restMesh_ ->updateNormals ();
956- }
957-
958- applySSD (
959- cast<T>(character_.inverseBindPose ),
960- *this ->character_ .skinWeights ,
961- *this ->restMesh_ ,
962- state,
963- *this ->posedMesh_ );
964- // TODO should we call updateNormals() here too or trust the ones from skinning?
965- }
966-
967936template class PointTriangleVertexErrorFunctionT <float >;
968937template class PointTriangleVertexErrorFunctionT <double >;
969938
0 commit comments