diff --git a/source/blender/src/meshlaplacian.c b/source/blender/src/meshlaplacian.c index 2fa85c56b04..5e8fdac80da 100644 --- a/source/blender/src/meshlaplacian.c +++ b/source/blender/src/meshlaplacian.c @@ -380,7 +380,8 @@ float laplacian_system_get_solution(int v) Ilya Baran and Jovan Popovic, SIGGRAPH 2007 */ #define C_WEIGHT 1.0f -#define WEIGHT_LIMIT 0.05f +#define WEIGHT_LIMIT_START 0.05f +#define WEIGHT_LIMIT_END 0.025f #define DISTANCE_EPSILON 1e-4f /* Raytracing for vertex to bone visibility */ @@ -601,6 +602,21 @@ static void heat_laplacian_create(LaplacianSystem *sys) heat_set_H(sys, a); } +static float heat_limit_weight(float weight) +{ + float t; + + if(weight < WEIGHT_LIMIT_END) { + return 0.0f; + } + else if(weight < WEIGHT_LIMIT_START) { + t= (weight - WEIGHT_LIMIT_END)/(WEIGHT_LIMIT_START - WEIGHT_LIMIT_END); + return t*WEIGHT_LIMIT_START; + } + else + return weight; +} + void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numbones, bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3], int *selected) { LaplacianSystem *sys; @@ -673,8 +689,9 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numbones, WEIGHT_ADD); } else { - if(solution > WEIGHT_LIMIT) - add_vert_to_defgroup(ob, dgrouplist[j], a, solution, + weight= heat_limit_weight(solution); + if(weight > 0.0f) + add_vert_to_defgroup(ob, dgrouplist[j], a, weight, WEIGHT_REPLACE); else remove_vert_defgroup(ob, dgrouplist[j], a); @@ -688,9 +705,10 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numbones, solution, WEIGHT_ADD); } else { - if(solution > WEIGHT_LIMIT) + weight= heat_limit_weight(solution); + if(weight > 0.0f) add_vert_to_defgroup(ob, dgroupflip[j], vertsflipped[a], - solution, WEIGHT_REPLACE); + weight, WEIGHT_REPLACE); else remove_vert_defgroup(ob, dgroupflip[j], vertsflipped[a]); } @@ -708,12 +726,14 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numbones, if(bbone && lastsegment) { for(a=0; atotvert; a++) { weight= get_vert_defgroup(ob, dgrouplist[j], a); - if(weight > 0.0f && weight <= WEIGHT_LIMIT) + weight= heat_limit_weight(weight); + if(weight <= 0.0f) remove_vert_defgroup(ob, dgrouplist[j], a); if(vertsflipped && dgroupflip[j] && vertsflipped[a] >= 0) { weight= get_vert_defgroup(ob, dgroupflip[j], vertsflipped[a]); - if(weight > 0.0f && weight <= WEIGHT_LIMIT) + weight= heat_limit_weight(weight); + if(weight <= 0.0f) remove_vert_defgroup(ob, dgroupflip[j], vertsflipped[a]); } }