[#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:
@@ -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 *****************************/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user