[#24045] heat weight fails on specific geometry.

The error for heat weighting was only being printed in the console, while the problem remains at least a warning is now given that there was a problem calculating the heat weight.

also fixed a memory leak from the mesh octree not being freed after assigning vertex groups. (ModNode error)
This commit is contained in:
2010-10-11 00:15:49 +00:00
parent 159cf6e5dd
commit 4ad2e4a383
6 changed files with 24 additions and 14 deletions

View File

@@ -4723,7 +4723,7 @@ static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], i
}
}
void add_verts_to_dgroups(Scene *scene, Object *ob, Object *par, int heat, int mirror)
void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob, Object *par, int heat, int mirror)
{
/* This functions implements the automatic computation of vertex group
* weights, either through envelopes or using a heat equilibrium.
@@ -4870,14 +4870,22 @@ void add_verts_to_dgroups(Scene *scene, Object *ob, Object *par, int heat, int m
/* compute the weights based on gathered vertices and bones */
if (heat) {
const char *error= NULL;
heat_bone_weighting(ob, mesh, verts, numbones, dgrouplist, dgroupflip,
root, tip, selected);
root, tip, selected, &error);
if(error) {
BKE_report(reports, RPT_WARNING, error);
}
}
else {
envelope_bone_weighting(ob, mesh, verts, numbones, bonelist, dgrouplist,
dgroupflip, root, tip, selected, mat4_to_scale(par->obmat));
}
/* only generated in some cases but can call anyway */
mesh_octree_table(ob, NULL, NULL, 'e');
/* free the memory allocated */
MEM_freeN(bonelist);
MEM_freeN(dgrouplist);
@@ -4888,7 +4896,7 @@ void add_verts_to_dgroups(Scene *scene, Object *ob, Object *par, int heat, int m
MEM_freeN(verts);
}
void create_vgroups_from_armature(Scene *scene, Object *ob, Object *par, int mode, int mirror)
void create_vgroups_from_armature(ReportList *reports, Scene *scene, Object *ob, Object *par, int mode, int mirror)
{
/* Lets try to create some vertex groups
* based on the bones of the parent armature.
@@ -4909,7 +4917,7 @@ void create_vgroups_from_armature(Scene *scene, Object *ob, Object *par, int mod
* that are populated with the vertices for which the
* bone is closest.
*/
add_verts_to_dgroups(scene, ob, par, (mode == ARM_GROUPS_AUTO), mirror);
add_verts_to_dgroups(reports, scene, ob, par, (mode == ARM_GROUPS_AUTO), mirror);
}
}
/* ************* Clear Pose *****************************/

View File

@@ -642,13 +642,15 @@ static float heat_limit_weight(float weight)
return weight;
}
void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource, bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3], int *selected)
void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource, bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3], int *selected, const char **err_str)
{
LaplacianSystem *sys;
MFace *mface;
float solution, weight;
int *vertsflipped = NULL, *mask= NULL;
int a, totface, j, bbone, firstsegment, lastsegment, thrownerror = 0;
*err_str= NULL;
/* count triangles and create mask */
if(me->editflag & ME_EDIT_PAINT_MASK)
@@ -760,8 +762,7 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource,
}
}
else if(!thrownerror) {
error("Bone Heat Weighting:"
" failed to find solution for one or more bones");
*err_str= "Bone Heat Weighting: failed to find solution for one or more bones";
thrownerror= 1;
break;
}

View File

@@ -66,7 +66,7 @@ float laplacian_system_get_solution(int v);
void heat_bone_weighting(struct Object *ob, struct Mesh *me, float (*verts)[3],
int numbones, struct bDeformGroup **dgrouplist,
struct bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3],
int *selected);
int *selected, const char **error);
#ifdef RIGID_DEFORM
/* As-Rigid-As-Possible Deformation */

View File

@@ -42,6 +42,7 @@ struct ListBase;
struct MeshDeformModifierData;
struct Object;
struct RegionView3D;
struct ReportList;
struct Scene;
struct SK_Sketch;
struct View3D;
@@ -132,7 +133,7 @@ void ED_armature_apply_transform(struct Object *ob, float mat[4][4]);
#define ARM_GROUPS_ENVELOPE 2
#define ARM_GROUPS_AUTO 3
void create_vgroups_from_armature(struct Scene *scene, struct Object *ob, struct Object *par, int mode, int mirror);
void create_vgroups_from_armature(struct ReportList *reports, struct Scene *scene, struct Object *ob, struct Object *par, int mode, int mirror);
void auto_align_armature(struct Scene *scene, struct View3D *v3d, short mode);
void unique_editbone_name(struct ListBase *ebones, char *name, EditBone *bone); /* if bone is already in list, pass it as param to ignore it */

View File

@@ -641,11 +641,11 @@ static int parent_set_exec(bContext *C, wmOperator *op)
}
else if(pararm && ob->type==OB_MESH && par->type == OB_ARMATURE) {
if(partype == PAR_ARMATURE_NAME)
create_vgroups_from_armature(scene, ob, par, ARM_GROUPS_NAME, 0);
create_vgroups_from_armature(op->reports, scene, ob, par, ARM_GROUPS_NAME, 0);
else if(partype == PAR_ARMATURE_ENVELOPE)
create_vgroups_from_armature(scene, ob, par, ARM_GROUPS_ENVELOPE, 0);
create_vgroups_from_armature(op->reports, scene, ob, par, ARM_GROUPS_ENVELOPE, 0);
else if(partype == PAR_ARMATURE_AUTO)
create_vgroups_from_armature(scene, ob, par, ARM_GROUPS_AUTO, 0);
create_vgroups_from_armature(op->reports, scene, ob, par, ARM_GROUPS_AUTO, 0);
/* get corrected inverse */
ob->partype= PAROBJECT;

View File

@@ -1971,7 +1971,7 @@ static int weight_from_bones_exec(bContext *C, wmOperator *op)
Mesh *me= ob->data;
int type= RNA_enum_get(op->ptr, "type");
create_vgroups_from_armature(scene, ob, armob, type, (me->editflag & ME_EDIT_MIRROR_X));
create_vgroups_from_armature(op->reports, scene, ob, armob, type, (me->editflag & ME_EDIT_MIRROR_X));
DAG_id_flush_update(&me->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);