From 4ad2e4a3830535d62aadd035bd5a714bca20a816 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 Oct 2010 00:15:49 +0000 Subject: [#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) --- source/blender/editors/armature/editarmature.c | 18 +++++++++++++----- source/blender/editors/armature/meshlaplacian.c | 7 ++++--- source/blender/editors/armature/meshlaplacian.h | 2 +- source/blender/editors/include/ED_armature.h | 3 ++- source/blender/editors/object/object_relations.c | 6 +++--- source/blender/editors/sculpt_paint/paint_vertex.c | 2 +- 6 files changed, 24 insertions(+), 14 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 26a89c4de02..49c3ac06b94 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -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 *****************************/ diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 84b02b4796a..38372850ff8 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -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; } diff --git a/source/blender/editors/armature/meshlaplacian.h b/source/blender/editors/armature/meshlaplacian.h index 640eb33c945..cba43043e8d 100644 --- a/source/blender/editors/armature/meshlaplacian.h +++ b/source/blender/editors/armature/meshlaplacian.h @@ -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 */ diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 809b86d65f3..e91bafc9056 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -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 */ diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 11175958fba..6a107b8e204 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -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; diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 399ba535e57..f033c2aac83 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -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); -- cgit v1.2.3