[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [37301] branches/soc-2011-radish/source/ blender/editors: editarmature.c and paint_vertex.c
Jason Hays
jason_hays22 at mymail.eku.edu
Tue Jun 7 19:59:38 CEST 2011
Revision: 37301
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=37301
Author: jason_hays22
Date: 2011-06-07 17:59:38 +0000 (Tue, 07 Jun 2011)
Log Message:
-----------
editarmature.c and paint_vertex.c
I added the first version of multi-bone selection for faster, temporary locking/unlocking; right now, if multiple bones are selected, the selection is considered unlocked, despite any vgroup checkbox status.
Every other group is considered locked.
paint_vertex.c
A modified Auto Normalize was inserted to normalize the active group normally instead of locking the values: it was causing the active group to steal weights from locked groups if the active group had a weight of 1.0, and that destroyed the locked groups deformations.
Modified Paths:
--------------
branches/soc-2011-radish/source/blender/editors/armature/editarmature.c
branches/soc-2011-radish/source/blender/editors/sculpt_paint/paint_vertex.c
Modified: branches/soc-2011-radish/source/blender/editors/armature/editarmature.c
===================================================================
--- branches/soc-2011-radish/source/blender/editors/armature/editarmature.c 2011-06-07 17:21:56 UTC (rev 37300)
+++ branches/soc-2011-radish/source/blender/editors/armature/editarmature.c 2011-06-07 17:59:38 UTC (rev 37301)
@@ -4385,14 +4385,30 @@
return count;
}
+// Jason
+Bone* get_other_selected_bone(Object *ob) {
+ Bone *bone;
+ int i;
+ bone = get_indexed_bone(ob, 0);
+ for(i = 0; bone;){
+ if(bone->flag & BONE_SELECTED) {
+ return bone;
+ }
+ i++;
+ bone = get_indexed_bone(ob, i);
+ }
+ return NULL;
+}
+
/* called from editview.c, for mode-less pose selection */
/* assumes scene obact and basact is still on old situation */
int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, short extend)
{
Object *ob= base->object;
Bone *nearBone;
-
+ // Jason
+ Bone *new_act_bone;
if (!ob || !ob->pose) return 0;
nearBone= get_bone_from_selectbuffer(scene, base, buffer, hits, 1);
@@ -4402,11 +4418,37 @@
bArmature *arm= ob->data;
/* since we do unified select, we don't shift+select a bone if the armature object was not active yet */
- if (!(extend) || (base != scene->basact)) {
- ED_pose_deselectall(ob, 0);
- nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
- arm->act_bone= nearBone;
-
+ /* Jason was here, I'm doing a unified select for locking now */
+ if ((base != scene->basact)) {//if (!(extend) || (base != scene->basact)) {
+ /* Jason was here */
+ /* only deselect all if they aren't using 'shift' */
+ if(!extend) {
+ ED_pose_deselectall(ob, 0);
+ nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+ arm->act_bone= nearBone;
+ ED_vgroup_select_by_name(OBACT, nearBone->name);
+ DAG_id_tag_update(&OBACT->id, OB_RECALC_DATA);
+ }
+ // Jason deselect this bone specifically if it is selected already
+ else {
+ if (nearBone->flag & BONE_SELECTED) {
+ nearBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+ if(nearBone == arm->act_bone) {
+ // make a different bone the active one if it exists
+
+ new_act_bone = get_other_selected_bone(ob);
+ if(new_act_bone) {
+ new_act_bone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+ arm->act_bone = new_act_bone;
+ ED_vgroup_select_by_name(OBACT, new_act_bone->name);
+ DAG_id_tag_update(&OBACT->id, OB_RECALC_DATA);
+ }
+ }
+ } else {
+ nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+ arm->act_bone= nearBone;
+ }
+ }
// XXX old cruft! use notifiers instead
//select_actionchannel_by_name(ob->action, nearBone->name, 1);
}
Modified: branches/soc-2011-radish/source/blender/editors/sculpt_paint/paint_vertex.c
===================================================================
--- branches/soc-2011-radish/source/blender/editors/sculpt_paint/paint_vertex.c 2011-06-07 17:21:56 UTC (rev 37300)
+++ branches/soc-2011-radish/source/blender/editors/sculpt_paint/paint_vertex.c 2011-06-07 17:59:38 UTC (rev 37301)
@@ -1028,6 +1028,35 @@
}
}
}
+// Jason was here: the active group should be involved in auto normalize
+static void do_weight_paint_auto_normalize_change_act_group(MDeformVert *dvert, char *map)
+{
+// MDeformWeight *dw = dvert->dw;
+ float sum=0.0f, fac=0.0f;
+ int i, tot=0;
+
+ if (!map)
+ return;
+
+ for (i=0; i<dvert->totweight; i++) {
+ if (map[dvert->dw[i].def_nr]) {
+ tot += 1;
+ sum += dvert->dw[i].weight;
+ }
+ }
+
+ if (!tot || sum == 1.0f)
+ return;
+
+ fac = sum;
+ fac = fac==0.0f ? 1.0f : 1.0f / fac;
+
+ for (i=0; i<dvert->totweight; i++) {
+ if (map[dvert->dw[i].def_nr]) {
+ dvert->dw[i].weight *= fac;
+ }
+ }
+}
/* Jason was here
this function will handle normalize with locked groups
it assumes that the current ratios (of locked groups)
@@ -1109,7 +1138,7 @@
}*/
/* Jason was here */
/*
-See if the current deform group has a locked group
+See if the current deform vertex has a locked group
*/
static char has_locked_group(MDeformVert *dvert, char *flags)
{
@@ -1122,30 +1151,57 @@
return FALSE;
}
/*Jason was here
-not sure where the prototypes belong at the moment
-static char* gen_lck_flags(Object* ob);
-
gen_lck_flags gets the status of "flag" for each bDeformGroup
in ob->defbase and returns an array containing them
+
+if there are multiple bones selected, however, they are the only ones that are treated as "unlocked"
*/
-static char* gen_lck_flags(Object* ob, int defcnt)
+static char* gen_lck_flags(Object* ob, int defcnt, char *map)
{
char is_locked = FALSE;
int i;
//int defcnt = BLI_countlist(&ob->defbase);
char *flags = MEM_mallocN(defcnt*sizeof(char), "defflags");
- bDeformGroup *defgroup = ob->defbase.first;
- for(i = 0; i < defcnt && defgroup; i++) {
- flags[i] = defgroup->flag;
- defgroup = defgroup->next;
- if(flags[i]) {
- is_locked = TRUE;
+ bDeformGroup *defgroup;
+ char was_selected = FALSE;
+ int selected = 0;
+ bPose *pose;
+ bPoseChannel *chan;
+ Bone *bone;
+
+ Object *armob = ED_object_pose_armature(ob);
+
+ if(armob) {
+ pose = armob->pose;
+ for (chan=pose->chanbase.first; chan; chan=chan->next) {
+ bone = chan->bone;
+ was_selected = FALSE;
+ for (i = 0, defgroup = ob->defbase.first; i < defcnt && defgroup; defgroup = defgroup->next, i++) {
+ if(!strcmp(defgroup->name, bone->name)) {
+ flags[i] = !(bone->flag & BONE_SELECTED);
+ if(flags[i]) {
+ is_locked = TRUE;
+ } else if(!was_selected){
+ selected++;
+ was_selected = TRUE;
+ }
+ }
+ }
}
}
+ if(selected <= 1) {
+ is_locked = FALSE;
+ for(i = 0, defgroup = ob->defbase.first; i < defcnt && defgroup; defgroup = defgroup->next, i++) {
+ flags[i] = defgroup->flag;
+ if(flags[i]) {
+ is_locked = TRUE;
+ }
+ }
+ }
if(is_locked){
return flags;
}
- // don't forget to free it
+ // don't forget to free it if it is unneeded
MEM_freeN(flags);
return NULL;
}
@@ -1204,18 +1260,17 @@
(if it has to, then it will put some/all of the change
back onto the original group)
*/
-static void redistribute_weight_change(MDeformVert *dvert, MDeformWeight *pnt_dw, float oldw, char* flags, int defcnt, char *map)
+static void redistribute_weight_change(Object *ob, MDeformVert *dvert, int index, MDeformWeight *pnt_dw, float oldw, char* flags, int defcnt, char *map)
{
int i;
+ float old_change_left;
float change_left = oldw - pnt_dw->weight;
+ // make sure the redistribution the same per loop.
float change;
char was_a_change;
int groups_left_that_can_change = 0;
- // make sure there is no case for division by 0, and make the redistribution the same per loop.
- int groups_currently_left;
char* change_status = MEM_mallocN(defcnt*sizeof(char), "defflags");
MDeformWeight *dw;
- //printf("start\n");
for(i = 0; i < defcnt; i++) {
if(pnt_dw->def_nr == i || !map[i]) {
change_status[i] = FALSE;
@@ -1224,13 +1279,15 @@
}
if(change_status[i]) {
groups_left_that_can_change++;
+ defvert_verify_index(dvert, i);
}
- //printf("group %d, change status: %d flag: %d active?: %d\n", i, change_status[i], flags[i], pnt_dw->def_nr == i);
}
- //printf("\n");
if(groups_left_that_can_change > 0) {
- groups_currently_left = groups_left_that_can_change;
change = change_left/groups_left_that_can_change;
+ /* the division could cause it to be zero, so if it is, forget it*/
+ if(change == 0) {
+ change = change_left;
+ }
do {
was_a_change = FALSE;
for(i = 0; i < dvert->totweight; i++) {
@@ -1240,45 +1297,53 @@
}
dw->weight += change;
+ old_change_left = change_left;
change_left -= change;
- //printf("group %d, change: %f weight: %f groups left: %d\n", dw->def_nr, change, dw->weight, groups_left_that_can_change);
+ // sign change?
+ if(change_left!=0 && change_left/fabs(change_left) != old_change_left/fabs(old_change_left)) {
+ dw->weight -= change;
+ change_left = old_change_left;
+ break;
+ }
if(dw->weight >= 1.0f) {
change_left += dw->weight-1.0f;
dw->weight = 1.0f;
- groups_currently_left--;
+ groups_left_that_can_change--;
change_status[dw->def_nr] = FALSE;
}else if(dw->weight <= 0.0f) {
change_left += dw->weight;
dw->weight = 0.0f;
- groups_currently_left--;
+ groups_left_that_can_change--;
change_status[dw->def_nr] = FALSE;
}
was_a_change = TRUE;
+ /* if it was too small, don't get stuck in an infinite loop! */
+ if(old_change_left == change_left) {
+ change *= 2;
+ }
}
- groups_left_that_can_change = groups_currently_left;
} while(groups_left_that_can_change > 0 && change_left != 0.0f && was_a_change);
}
// add any remaining change back to the original weight
pnt_dw->weight += change_left;
MEM_freeN(change_status);
- //printf("done\n");
}
/* Jason */
-static void check_locks_and_normalize(Mesh *me, int index, int vgroup, MDeformWeight *dw, float oldw, char *validmap, char *flags, int defcnt, char *bone_groups)
+static void check_locks_and_normalize(Object *ob, Mesh *me, int index, int vgroup, MDeformWeight *dw, float oldw, char *validmap, char *flags, int defcnt, char *bone_groups)
{
if(flags && has_locked_group(me->dvert+index, flags)) {
if(flags[dw->def_nr]) {
// cannot change locked groups!
dw->weight = oldw;
} else if(bone_groups[dw->def_nr]) {
- redistribute_weight_change(me->dvert+index, dw, oldw, flags, defcnt, bone_groups);
- do_weight_paint_auto_normalize(me->dvert+index, vgroup, validmap);//do_wp_auto_normalize_locked_groups(me, me->dvert, validmap);
+ redistribute_weight_change(ob, me->dvert+index, index, dw, oldw, flags, defcnt, bone_groups);
+ do_weight_paint_auto_normalize_change_act_group(me->dvert+index, validmap);//do_weight_paint_auto_normalize(me->dvert+index, vgroup, validmap);
}
} else if(bone_groups[dw->def_nr]) {// disable auto normalize if the active group is not a bone group
- do_weight_paint_auto_normalize(me->dvert+index, vgroup, validmap);
+ do_weight_paint_auto_normalize_change_act_group(me->dvert+index, validmap);//do_weight_paint_auto_normalize(me->dvert+index, vgroup, validmap);
}
}
// Jason
@@ -1291,7 +1356,7 @@
Mesh *me= ob->data;
MDeformWeight *dw, *uw;
int vgroup= ob->actdef-1;
-
+
/* Jason was here */
char* flags;
char* bone_groups;
@@ -1314,13 +1379,12 @@
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list