[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12697] trunk/blender/source/blender:
Brecht Van Lommel
brechtvanlommel at pandora.be
Tue Nov 27 22:16:47 CET 2007
Revision: 12697
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12697
Author: blendix
Date: 2007-11-27 22:16:47 +0100 (Tue, 27 Nov 2007)
Log Message:
-----------
Heat Weighting
==============
Now takes b-bones into account, solving as if each bone segment was
an individual bone, and then adding the weights together.
Modified Paths:
--------------
trunk/blender/source/blender/include/BIF_editdeform.h
trunk/blender/source/blender/src/editarmature.c
trunk/blender/source/blender/src/editdeform.c
trunk/blender/source/blender/src/meshlaplacian.c
Modified: trunk/blender/source/blender/include/BIF_editdeform.h
===================================================================
--- trunk/blender/source/blender/include/BIF_editdeform.h 2007-11-27 19:23:26 UTC (rev 12696)
+++ trunk/blender/source/blender/include/BIF_editdeform.h 2007-11-27 21:16:47 UTC (rev 12697)
@@ -61,6 +61,8 @@
int assignmode);
void remove_vert_defgroup (struct Object *ob, struct bDeformGroup *dg,
int vertnum);
+float get_vert_defgroup (struct Object *ob, struct bDeformGroup *dg,
+ int vertnum);
void create_dverts(ID *id);
void vertexgroup_select_by_name(struct Object *ob, char *name);
Modified: trunk/blender/source/blender/src/editarmature.c
===================================================================
--- trunk/blender/source/blender/src/editarmature.c 2007-11-27 19:23:26 UTC (rev 12696)
+++ trunk/blender/source/blender/src/editarmature.c 2007-11-27 21:16:47 UTC (rev 12697)
@@ -2552,7 +2552,7 @@
}
-static int bone_skinnable(Object *ob, Bone *bone, void *data)
+static int bone_skinnable(Object *ob, Bone *bone, void *datap)
{
/* Bones that are deforming
* are regarded to be "skinnable" and are eligible for
@@ -2576,16 +2576,26 @@
* pointers to bones that point to all
* skinnable bones.
*/
- Bone ***hbone;
+ Bone ***hbone;
+ int a, segments;
+ struct { Object *armob; void *list; int heat; } *data = datap;
if(!(G.f & G_WEIGHTPAINT) || !(bone->flag & BONE_HIDDEN_P)) {
if (!(bone->flag & BONE_NO_DEFORM)) {
- if (data != NULL) {
- hbone = (Bone ***) data;
- **hbone = bone;
- ++*hbone;
+ if(data->heat && data->armob->pose && get_pose_channel(data->armob->pose, bone->name))
+ segments = bone->segments;
+ else
+ segments = 1;
+
+ if (data->list != NULL) {
+ hbone = (Bone ***) &data->list;
+
+ for(a=0; a<segments; a++) {
+ **hbone = bone;
+ ++*hbone;
+ }
}
- return 1;
+ return segments;
}
}
return 0;
@@ -2606,7 +2616,7 @@
return 0;
}
-static int dgroup_skinnable(Object *ob, Bone *bone, void *data)
+static int dgroup_skinnable(Object *ob, Bone *bone, void *datap)
{
/* Bones that are deforming
* are regarded to be "skinnable" and are eligible for
@@ -2632,19 +2642,28 @@
* of skinnable bones.
*/
bDeformGroup ***hgroup, *defgroup;
+ int a, segments;
+ struct { Object *armob; void *list; int heat; } *data= datap;
if(!(G.f & G_WEIGHTPAINT) || !(bone->flag & BONE_HIDDEN_P)) {
if (!(bone->flag & BONE_NO_DEFORM)) {
- if ( !(defgroup = get_named_vertexgroup(ob, bone->name)) ) {
+ if(data->heat && data->armob->pose && get_pose_channel(data->armob->pose, bone->name))
+ segments = bone->segments;
+ else
+ segments = 1;
+
+ if(!(defgroup = get_named_vertexgroup(ob, bone->name)))
defgroup = add_defgroup_name(ob, bone->name);
- }
- if (data != NULL) {
- hgroup = (bDeformGroup ***) data;
- **hgroup = defgroup;
- ++*hgroup;
+ if (data->list != NULL) {
+ hgroup = (bDeformGroup ***) &data->list;
+
+ for(a=0; a<segments; a++) {
+ **hgroup = defgroup;
+ ++*hgroup;
+ }
}
- return 1;
+ return segments;
}
}
return 0;
@@ -2682,7 +2701,7 @@
/* store the distance-factor from the vertex to the bone */
distance = distfactor_to_bone (verts[i], root[j], tip[j],
bone->rad_head * scale, bone->rad_tail * scale, bone->dist * scale);
-
+
/* add the vert to the deform group if weight!=0.0 */
if (distance!=0.0)
add_vert_to_defgroup (ob, dgroup, i, distance, WEIGHT_REPLACE);
@@ -2713,59 +2732,95 @@
* The mesh vertex positions used are either the final deformed coords
* from the derivedmesh in weightpaint mode, the final subsurf coords
* when parenting, or simply the original mesh coords.
- */
+ */
- bArmature *arm;
- Bone **bonelist, **bonehandle, *bone;
- bDeformGroup **dgrouplist, **dgroupflip, **dgrouphandle;
+ bArmature *arm;
+ Bone **bonelist, *bone;
+ bDeformGroup **dgrouplist, **dgroupflip;
bDeformGroup *dgroup, *curdg;
- Mesh *mesh;
- float (*root)[3], (*tip)[3], (*verts)[3];
+ bPoseChannel *pchan;
+ Mesh *mesh;
+ Mat4 *bbone = NULL;
+ float (*root)[3], (*tip)[3], (*verts)[3];
int *selected;
- int numbones, vertsfilled = 0, i, j;
+ int numbones, vertsfilled = 0, i, j, segments = 0;
int wpmode = (G.f & G_WEIGHTPAINT);
+ struct { Object *armob; void *list; int heat; } looper_data;
- /* If the parent object is not an armature exit */
- arm = get_armature(par);
- if (!arm)
- return;
+ /* If the parent object is not an armature exit */
+ arm = get_armature(par);
+ if (!arm)
+ return;
+
+ looper_data.armob = par;
+ looper_data.heat= heat;
+ looper_data.list= NULL;
- /* count the number of skinnable bones */
- numbones = bone_looper(ob, arm->bonebase.first, NULL, bone_skinnable);
+ /* count the number of skinnable bones */
+ numbones = bone_looper(ob, arm->bonebase.first, &looper_data, bone_skinnable);
if (numbones == 0)
return;
- /* create an array of pointer to bones that are skinnable
- * and fill it with all of the skinnable bones */
- bonelist = MEM_callocN(numbones*sizeof(Bone *), "bonelist");
- bonehandle = bonelist;
- bone_looper(ob, arm->bonebase.first, &bonehandle, bone_skinnable);
+ /* create an array of pointer to bones that are skinnable
+ * and fill it with all of the skinnable bones */
+ bonelist = MEM_callocN(numbones*sizeof(Bone *), "bonelist");
+ looper_data.list= bonelist;
+ bone_looper(ob, arm->bonebase.first, &looper_data, bone_skinnable);
- /* create an array of pointers to the deform groups that
- * coorespond to the skinnable bones (creating them
- * as necessary. */
- dgrouplist = MEM_callocN(numbones*sizeof(bDeformGroup *), "dgrouplist");
- dgroupflip = MEM_callocN(numbones*sizeof(bDeformGroup *), "dgroupflip");
+ /* create an array of pointers to the deform groups that
+ * coorespond to the skinnable bones (creating them
+ * as necessary. */
+ dgrouplist = MEM_callocN(numbones*sizeof(bDeformGroup *), "dgrouplist");
+ dgroupflip = MEM_callocN(numbones*sizeof(bDeformGroup *), "dgroupflip");
- dgrouphandle = dgrouplist;
- bone_looper(ob, arm->bonebase.first, &dgrouphandle, dgroup_skinnable);
+ looper_data.list= dgrouplist;
+ bone_looper(ob, arm->bonebase.first, &looper_data, dgroup_skinnable);
- /* create an array of root and tip positions transformed into
+ /* create an array of root and tip positions transformed into
* global coords */
- root = MEM_callocN(numbones*sizeof(float)*3, "root");
- tip = MEM_callocN(numbones*sizeof(float)*3, "tip");
+ root = MEM_callocN(numbones*sizeof(float)*3, "root");
+ tip = MEM_callocN(numbones*sizeof(float)*3, "tip");
selected = MEM_callocN(numbones*sizeof(int), "selected");
for (j=0; j < numbones; ++j) {
bone = bonelist[j];
dgroup = dgrouplist[j];
+ /* handle bbone */
+ if(heat) {
+ if(segments == 0) {
+ segments = 1;
+ bbone = NULL;
+
+ if(par->pose && (pchan=get_pose_channel(par->pose, bone->name))) {
+ if(bone->segments > 1) {
+ segments = bone->segments;
+ bbone = b_bone_spline_setup(pchan, 1);
+ }
+ }
+ }
+
+ segments--;
+ }
+
/* compute root and tip */
- VECCOPY(root[j], bone->arm_head);
+ if(bbone) {
+ VECCOPY(root[j], bbone[segments].mat[3]);
+ Mat4MulVecfl(bone->arm_mat, root[j]);
+ if(segments+1 < bone->segments) {
+ VECCOPY(tip[j], bbone[segments+1].mat[3])
+ Mat4MulVecfl(bone->arm_mat, tip[j]);
+ }
+ else
+ VECCOPY(tip[j], bone->arm_tail)
+ }
+ else {
+ VECCOPY(root[j], bone->arm_head);
+ VECCOPY(tip[j], bone->arm_tail);
+ }
+
Mat4MulVecfl(par->obmat, root[j]);
-
- VECCOPY(tip[j], bone->arm_tail);
Mat4MulVecfl(par->obmat, tip[j]);
/* set selected */
Modified: trunk/blender/source/blender/src/editdeform.c
===================================================================
--- trunk/blender/source/blender/src/editdeform.c 2007-11-27 19:23:26 UTC (rev 12696)
+++ trunk/blender/source/blender/src/editdeform.c 2007-11-27 21:16:47 UTC (rev 12697)
@@ -704,6 +704,53 @@
remove_vert_def_nr (ob, def_nr, vertnum);
}
+/* for mesh in object mode lattice can be in editmode */
+static float get_vert_def_nr (Object *ob, int def_nr, int vertnum)
+{
+ MDeformVert *dvert= NULL;
+ int i;
+
+ /* get the deform vertices corresponding to the
+ * vertnum
+ */
+ if(ob->type==OB_MESH) {
+ if( ((Mesh*)ob->data)->dvert )
+ dvert = ((Mesh*)ob->data)->dvert + vertnum;
+ }
+ else if(ob->type==OB_LATTICE) {
+ Lattice *lt= ob->data;
+
+ if(ob==G.obedit)
+ lt= editLatt;
+
+ if(lt->dvert)
+ dvert = lt->dvert + vertnum;
+ }
+
+ if(dvert==NULL)
+ return 0.0f;
+
+ for(i=dvert->totweight-1 ; i>=0 ; i--)
+ if(dvert->dw[i].def_nr == def_nr)
+ return dvert->dw[i].weight;
+
+ return 0.0f;
+}
+
+/* mesh object mode, lattice can be in editmode */
+float get_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum)
+{
+ int def_nr;
+
+ if(!ob)
+ return 0.0f;
+
+ def_nr = get_defgroup_num(ob, dg);
+ if(def_nr < 0) return 0.0f;
+
+ return get_vert_def_nr (ob, def_nr, vertnum);
+}
+
/* Only available in editmode */
/* removes from active defgroup, if allverts==0 only selected vertices */
void remove_verts_defgroup (int allverts)
Modified: trunk/blender/source/blender/src/meshlaplacian.c
===================================================================
--- trunk/blender/source/blender/src/meshlaplacian.c 2007-11-27 19:23:26 UTC (rev 12696)
+++ trunk/blender/source/blender/src/meshlaplacian.c 2007-11-27 21:16:47 UTC (rev 12697)
@@ -407,7 +407,7 @@
if(v4) CalcNormFloat4(v1, v2, v3, v4, nor);
else CalcNormFloat(v1, v2, v3, nor);
-
+
return (INPR(nor, is->vec) < 0);
}
@@ -605,8 +605,9 @@
{
LaplacianSystem *sys;
MFace *mface;
- float solution;
- int a, aflip, totface, j, thrownerror = 0;
+ float solution, weight;
+ int *vertsflipped = NULL;
+ int a, totface, j, bbone, firstsegment, lastsegment, thrownerror = 0;
/* count triangles */
for(totface=0, a=0, mface=me->mface; a<me->totface; a++, mface++) {
@@ -628,11 +629,31 @@
laplacian_system_construct_end(sys);
+ if(dgroupflip) {
+ vertsflipped = MEM_callocN(sizeof(int)*me->totvert, "vertsflipped");
+ for(a=0; a<me->totvert; a++)
+ vertsflipped[a] = mesh_get_x_mirror_vert(ob, a);
+ }
+
/* compute weights per bone */
for(j=0; j<numbones; j++) {
if(!selected[j])
continue;
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list