1#include <Core/Animation/HandleWeightOperation.hpp>
2#include <Core/Math/LinearAlgebra.hpp>
3#include <Core/Utils/Log.hpp>
12WeightMatrix extractWeightMatrix(
const MeshWeight& weight,
const uint weight_size ) {
13 WeightMatrix W( weight.size(), weight_size );
15 for ( uint i = 0; i < weight.size(); ++i ) {
16 for (
const auto& w : weight[i] ) {
17 W.coeffRef( i, w.first ) = w.second;
23MeshWeight extractMeshWeight( Eigen::Ref<const WeightMatrix> matrix ) {
24 MeshWeight W( matrix.rows() );
25 for (
int i = 0; i < matrix.rows(); ++i ) {
26 for (
int j = 0; j < matrix.cols(); ++j ) {
27 if ( matrix.coeff( i, j ) != 0.0 ) {
36WeightMatrix partitionOfUnity( Eigen::Ref<const WeightMatrix> weights ) {
37 WeightMatrix W = weights;
38 normalizeWeights( W );
42uint getMaxWeightIndex( Eigen::Ref<const WeightMatrix> weights,
const uint vertexID ) {
43 uint maxId = uint( -1 );
44 VectorN row = weights.row( vertexID );
45 row.maxCoeff( &maxId );
49void getMaxWeightIndex( Eigen::Ref<const WeightMatrix> weights,
std::vector<uint>& handleID ) {
50 handleID.
resize( weights.rows() );
51 for (
int i = 0; i < weights.rows(); ++i ) {
52 handleID[i] = getMaxWeightIndex( weights, i );
56bool checkWeightMatrix( Eigen::Ref<const WeightMatrix> matrix,
57 const bool FAIL_ON_ASSERT,
60 checkNoWeightVertex( matrix, FAIL_ON_ASSERT, MT );
62 if ( !ok ) { LOG( logDEBUG ) <<
"Matrix is not good."; }
67bool checkNoWeightVertex( Eigen::Ref<const WeightMatrix> matrix,
68 const bool FAIL_ON_ASSERT,
71 LOG( logDEBUG ) <<
"Searching for empty rows in the matrix...";
73#pragma omp parallel for
74 for (
int i = 0; i < matrix.rows(); ++i ) {
75 Sparse row = matrix.row( i );
76 const int check = ( row.nonZeros() > 0 ) ? 1 : 0;
81 if ( FAIL_ON_ASSERT ) { CORE_ASSERT(
false,
"At least a vertex as no weights" ); }
82 else { LOG( logDEBUG ) <<
"At least a vertex as no weights"; }
86 for (
int i = 0; i < matrix.rows(); ++i ) {
87 Sparse row = matrix.row( i );
88 if ( row.nonZeros() == 0 ) {
92 if ( FAIL_ON_ASSERT ) { CORE_ASSERT(
false, text.
c_str() ); }
93 else { LOG( logDEBUG ) << text; }
100bool normalizeWeights( Eigen::Ref<WeightMatrix> matrix,
const bool MT ) {
103 bool skinningWeightOk =
true;
105#pragma omp parallel for if ( MT )
106 for (
int k = 0; k < matrix.innerSize(); ++k ) {
107 const Scalar sum = matrix.row( k ).sum();
110 skinningWeightOk =
false;
111 matrix.row( k ) /= sum;
115 return !skinningWeightOk;
std::enable_if<!std::numeric_limits< T >::is_integer, bool >::type areApproxEqual(T x, T y, T espilonBoostFactor=T(10))
Compare two numbers such that |x-y| < espilon*epsilonBoostFactor.
bool checkInvalidNumbers(Eigen::Ref< Eigen::Quaternion< S > > q, const bool FAIL_ON_ASSERT=false)
Call std::isfinite on quaternion entries.
hepler function to manage enum as underlying types in VariableSet