Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/src/editarmature.c')
-rw-r--r--source/blender/src/editarmature.c149
1 files changed, 102 insertions, 47 deletions
diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c
index 24c8382a445..9dcb190509f 100644
--- a/source/blender/src/editarmature.c
+++ b/source/blender/src/editarmature.c
@@ -2552,7 +2552,7 @@ int bone_looper(Object *ob, Bone *bone, void *data,
}
-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 @@ static int bone_skinnable(Object *ob, Bone *bone, void *data)
* 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 @@ static int add_defgroup_unique_bone(Object *ob, Bone *bone, void *data)
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 @@ static int dgroup_skinnable(Object *ob, Bone *bone, void *data)
* 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 @@ static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], i
/* 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 @@ void add_verts_to_dgroups(Object *ob, Object *par, int heat, int mirror)
* 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);
- Mat4MulVecfl(par->obmat, root[j]);
+ 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);
+ }
- VECCOPY(tip[j], bone->arm_tail);
+ Mat4MulVecfl(par->obmat, root[j]);
Mat4MulVecfl(par->obmat, tip[j]);
/* set selected */