Index: source/blender/editors/sculpt_paint/paint_vertex.c |
=================================================================== |
--- source/blender/editors/sculpt_paint/paint_vertex.c (revision 40192) |
+++ source/blender/editors/sculpt_paint/paint_vertex.c (working copy) |
@@ -64,6 +64,7 @@ |
#include "RNA_enum_types.h" |
#include "BKE_DerivedMesh.h" |
+#include "BKE_armature.h" |
#include "BKE_action.h" |
#include "BKE_brush.h" |
#include "BKE_context.h" |
@@ -398,11 +399,15 @@ |
unsigned char i; |
int vgroup_mirror= -1; |
int selected; |
- |
+ // Jason |
+ int use_vert_sel; |
+ |
me= ob->data; |
if(me==NULL || me->totface==0 || me->dvert==NULL || !me->mface) return; |
selected= (me->editflag & ME_EDIT_PAINT_MASK); |
+ // Jason |
+ use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; |
indexar= get_indexarray(me); |
@@ -437,7 +442,12 @@ |
faceverts[2]= mface->v3; |
faceverts[3]= mface->v4; |
for (i=0; i<3 || faceverts[i]; i++) { |
- if(!((me->dvert+faceverts[i])->flag)) { |
+ if(!me->dvert[faceverts[i]].flag) { |
+ // Jason |
+ if(use_vert_sel && ((me->mvert[faceverts[i]].flag & SELECT) == 0)) { |
+ continue; |
+ } |
+ |
dw= defvert_verify_index(me->dvert+faceverts[i], vgroup); |
if(dw) { |
uw= defvert_verify_index(wp->wpaint_prev+faceverts[i], vgroup); |
@@ -792,7 +802,7 @@ |
return alpha; |
} |
-static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float alpha, float paintval, int flip) |
+static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float alpha, float paintval, int flip, int multipaint) |
{ |
Brush *brush = paint_brush(&wp->paint); |
int tool = brush->vertexpaint_tool; |
@@ -830,7 +840,8 @@ |
if (dw->weight > paintval) |
dw->weight = paintval*alpha + dw->weight*(1.0f-alpha); |
} |
- CLAMP(dw->weight, 0.0f, 1.0f); |
+ // Jason delay clamping until the end so multi-paint can function when the active group is at the limits |
+ //CLAMP(dw->weight, 0.0f, 1.0f); |
/* if no spray, clip result with orig weight & orig alpha */ |
if((wp->flag & VP_SPRAY)==0) { |
@@ -857,16 +868,17 @@ |
else |
testw = uw->weight; |
} |
- CLAMP(testw, 0.0f, 1.0f); |
- |
- if( testw<uw->weight ) { |
- if(dw->weight < testw) dw->weight= testw; |
- else if(dw->weight > uw->weight) dw->weight= uw->weight; |
+ //CLAMP(testw, 0.0f, 1.0f); |
+ if(!multipaint) { |
+ if( testw<uw->weight ) { |
+ if(dw->weight < testw) dw->weight= testw; |
+ else if(dw->weight > uw->weight) dw->weight= uw->weight; |
+ } |
+ else { |
+ if(dw->weight > testw) dw->weight= testw; |
+ else if(dw->weight < uw->weight) dw->weight= uw->weight; |
+ } |
} |
- else { |
- if(dw->weight > testw) dw->weight= testw; |
- else if(dw->weight < uw->weight) dw->weight= uw->weight; |
- } |
} |
} |
@@ -1062,6 +1074,7 @@ |
} |
+#if 0 /* UNUSED */ |
ideasman42
2011/09/15 03:00:08
left in commented code, once merged into trunk we
|
static void do_weight_paint_auto_normalize(MDeformVert *dvert, |
int paint_nr, char *map) |
{ |
@@ -1096,15 +1109,436 @@ |
} |
} |
} |
+#endif |
+// Jason was here: the active group should be involved in auto normalize |
+static void do_weight_paint_auto_normalize_all_groups(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 */ |
+/* |
+See if the current deform vertex has a locked group |
+*/ |
+static char has_locked_group(MDeformVert *dvert, char *flags) |
+{ |
+ int i; |
+ for(i = 0; i < dvert->totweight; i++) { |
+ if(flags[(dvert->dw+i)->def_nr] && (dvert->dw+i)->weight > 0.0f) { |
+ return TRUE; |
+ } |
+ } |
+ return FALSE; |
+} |
+/* Jason was here |
+ * gen_lck_flags gets the status of "flag" for each bDeformGroup |
+ *in ob->defbase and returns an array containing them |
+ */ |
+static char *gen_lck_flags(Object* ob, int defbase_len) |
+{ |
+ char is_locked = FALSE; |
+ int i; |
+ //int defbase_len = BLI_countlist(&ob->defbase); |
+ char *flags = MEM_mallocN(defbase_len*sizeof(char), "defflags"); |
+ bDeformGroup *defgroup; |
+ |
+ for(i = 0, defgroup = ob->defbase.first; i < defbase_len && defgroup; defgroup = defgroup->next, i++) { |
+ flags[i] = ((defgroup->flag & DG_LOCK_WEIGHT) != 0); |
+ is_locked |= flags[i]; |
+ } |
+ if(is_locked){ |
+ return flags; |
+ } |
+ // don't forget to free it if it is unneeded |
+ MEM_freeN(flags); |
+ return NULL; |
+} |
+/* Jason was here */ |
+static int has_locked_group_selected(int defbase_len, char *defbase_sel, char *flags) { |
+ int i; |
+ for(i = 0; i < defbase_len; i++) { |
+ if(defbase_sel[i] && flags[i]) { |
+ return TRUE; |
+ } |
+ } |
+ return FALSE; |
+} |
+ |
+/* Jason was here */ |
+#if 0 /* UNUSED */ |
nazgul
2011/09/15 07:57:10
IMO better to remove unused code. But it can be do
|
+static int has_unselected_unlocked_bone_group(int defbase_len, char *defbase_sel, int selected, char *flags, char *bone_groups) { |
+ int i; |
+ if(defbase_len == selected) { |
+ return FALSE; |
+ } |
+ for(i = 0; i < defbase_len; i++) { |
+ if(bone_groups[i] && !defbase_sel[i] && !flags[i]) { |
+ return TRUE; |
+ } |
+ } |
+ return FALSE; |
+} |
+#endif |
+ |
+/*Jason*/ |
+static void multipaint_selection(MDeformVert *dvert, float change, char *defbase_sel, int defbase_len) { |
+ int i; |
+ MDeformWeight *dw; |
+ float val; |
+ // make sure they are all at most 1 after the change |
+ for(i = 0; i < defbase_len; i++) { |
+ if(defbase_sel[i]) { |
+ dw = defvert_find_index(dvert, i); |
+ if(dw && dw->weight) { |
+ val = dw->weight * change; |
+ if(val > 1) { |
+ // Jason TODO: when the change is reduced, you need to recheck the earlier values to make sure they are not 0 (precision error) |
+ change = 1.0f/dw->weight; |
+ } |
+ // the value should never reach zero while multi-painting if it was nonzero beforehand |
+ if(val <= 0) { |
+ return; |
+ } |
+ } |
+ } |
+ } |
+ // apply the valid change |
+ for(i = 0; i < defbase_len; i++) { |
+ if(defbase_sel[i]) { |
+ dw = defvert_find_index(dvert, i); |
+ if(dw && dw->weight) { |
+ dw->weight = dw->weight * change; |
+ } |
+ } |
+ } |
+} |
+/*Jason*/ |
+// move all change onto valid, unchanged groups. If there is change left over, then return it. |
+// assumes there are valid groups to shift weight onto |
+static float redistribute_change(MDeformVert *ndv, char *change_status, int changeme, int changeto, char *validmap, float totchange, float total_valid) { |
+ float was_change; |
+ float change; |
+ float oldval; |
+ MDeformWeight *ndw; |
+ int i; |
+ do { |
+ // assume there is no change until you see one |
+ was_change = FALSE; |
+ // change each group by the same amount each time |
+ change = totchange/total_valid; |
+ for(i = 0; i < ndv->totweight && total_valid && totchange; i++) { |
+ ndw = (ndv->dw+i); |
+ // change only the groups with a valid status |
+ if(change_status[ndw->def_nr] == changeme) { |
+ oldval = ndw->weight; |
+ // if auto normalize is active, don't worry about upper bounds |
+ if(!validmap && ndw->weight + change > 1) { |
+ totchange -= 1-ndw->weight; |
+ ndw->weight = 1; |
+ // stop the changes to this group |
+ change_status[ndw->def_nr] = changeto; |
+ total_valid--; |
+ } else if(ndw->weight + change < 0) { // check the lower bound |
+ totchange -= ndw->weight; |
+ ndw->weight = 0; |
+ change_status[ndw->def_nr] = changeto; |
+ total_valid--; |
+ } else {// a perfectly valid change occurred to ndw->weight |
+ totchange -= change; |
+ ndw->weight += change; |
+ } |
+ // see if there was a change |
+ if(oldval != ndw->weight) { |
+ was_change = TRUE; |
+ } |
+ } |
+ } |
+ // don't go again if there was no change, if there is no valid group, or there is no change left |
+ }while(was_change && total_valid && totchange); |
+ // left overs |
+ return totchange; |
+} |
+/*Jason*/ |
+// observe the changes made to the weights of groups. |
+// make sure all locked groups on the vertex have the same deformation |
+// by moving the changes made to groups onto other unlocked groups |
+static void enforce_locks(MDeformVert *odv, MDeformVert *ndv, int defbase_len, char *flags, char *bone_groups, char *validmap) { |
+ float totchange = 0.0f; |
+ float totchange_allowed = 0.0f; |
+ float left_over; |
+ |
+ int total_valid = 0; |
+ int total_changed = 0; |
+ int i; |
+ MDeformWeight *ndw; |
+ MDeformWeight *odw; |
+ MDeformWeight *ndw2; |
+ MDeformWeight *odw2; |
+ int designatedw = -1; |
+ int designatedw_changed = FALSE; |
+ float storedw; |
+ char *change_status; |
+ char new_weight_has_zero = FALSE; |
+ |
+ if(!flags || !has_locked_group(ndv, flags)) { |
+ return; |
+ } |
+ // record if a group was changed, unlocked and not changed, or locked |
+ change_status = MEM_callocN(sizeof(char)*defbase_len, "unlocked_unchanged"); |
+ |
+ for(i = 0; i < defbase_len; i++) { |
+ ndw = defvert_find_index(ndv, i); |
+ odw = defvert_find_index(odv, i); |
+ // the weights are zero, so we can assume a lot |
+ if(!ndw || !odw) { |
+ if (!flags[i] && bone_groups[i]){ |
+ defvert_verify_index(odv, i); |
+ defvert_verify_index(ndv, i); |
+ total_valid++; |
+ change_status[i] = 1; // can be altered while redistributing |
+ } |
+ continue; |
+ } |
+ // locked groups should not be changed |
+ if(flags[i]) { |
+ ndw->weight = odw->weight; |
+ } else if(ndw->weight != odw->weight) { // changed groups are handled here |
+ totchange += ndw->weight-odw->weight; |
+ change_status[i] = 2; // was altered already |
+ total_changed++; |
+ if(ndw->weight == 0) { |
+ new_weight_has_zero = TRUE; |
+ } else if(designatedw == -1){ |
+ designatedw = i; |
+ } |
+ } // unchanged, unlocked bone groups are handled here |
+ else if (bone_groups[i]){ |
+ totchange_allowed += ndw->weight; |
+ total_valid++; |
+ change_status[i] = 1; // can be altered while redistributing |
+ } |
+ } |
+ // if there was any change, redistribute it |
+ if(total_changed) { |
+ // auto normalize will allow weights to temporarily go above 1 in redistribution |
+ if(validmap && total_changed < 0 && total_valid) { |
+ totchange_allowed = total_valid; |
+ } |
+ // there needs to be change allowed, or you should not bother |
+ if(totchange_allowed) { |
+ // the way you modify the unlocked+unchanged groups is different depending |
+ // on whether or not you are painting the weight(s) up or down |
+ if(totchange < 0) { |
+ totchange_allowed = total_valid - totchange_allowed; |
+ } else { |
+ totchange_allowed *= -1; |
+ } |
+ left_over = 0; |
+ if(fabs(totchange_allowed) < fabs(totchange)) { |
+ // this amount goes back onto the changed, unlocked weights |
+ left_over = fabs(fabs(totchange)-fabs(totchange_allowed)); |
+ if(totchange > 0) { |
+ left_over *= -1; |
+ } |
+ }else { |
+ // all of the change will be permitted |
+ totchange_allowed = -totchange; |
+ } |
+ // move the weight evenly between the allowed groups, move excess back onto the used groups based on the change |
+ totchange_allowed = redistribute_change(ndv, change_status, 1, -1, validmap, totchange_allowed, total_valid); |
+ left_over += totchange_allowed; |
+ if(left_over) { |
+ // more than one nonzero weights were changed with the same ratio, so keep them changed that way! |
+ if(total_changed > 1 && !new_weight_has_zero && designatedw >= 0) { |
+ // this dw is special, it is used as a base to determine how to change the others |
+ ndw = defvert_find_index(ndv, designatedw); |
+ odw = defvert_find_index(odv, designatedw); |
+ storedw = ndw->weight; |
+ for(i = 0; i < ndv->totweight; i++) { |
+ if(change_status[ndw->def_nr] == 2) { |
+ odw2 = (odv->dw+i); |
+ ndw2 = (ndv->dw+i); |
+ if(!designatedw_changed) { |
+ ndw->weight = (totchange_allowed + odw->weight + odw2->weight)/(1 + ndw2->weight/ndw->weight); |
+ designatedw_changed = TRUE; |
+ } |
+ ndw2->weight = ndw->weight*ndw2->weight/storedw; |
+ } |
+ } |
+ } |
+ // a weight was changed to zero, only one weight was changed, or designatedw is still -1 |
+ // put weight back as evenly as possible |
+ else { |
+ redistribute_change(ndv, change_status, 2, -2, validmap, left_over, total_changed); |
+ } |
+ } |
+ } else { |
+ // reset the weights |
+ for(i = 0; i < ndv->totweight; i++) { |
+ (ndv->dw+i)->weight = (odv->dw+i)->weight; |
+ } |
+ } |
+ } |
+ |
+ MEM_freeN(change_status); |
+} |
+/*Jason*/ |
+// multi-paint's initial, potential change is computed here based on the user's stroke |
+static float get_mp_change(MDeformVert *odv, char *defbase_sel, float brush_change) { |
+ float selwsum = 0.0f; |
+ int i; |
+ MDeformWeight *dw; |
+ for(i=0; i < odv->totweight; i++) { |
+ if(defbase_sel[(dw = (odv->dw+i))->def_nr]) { |
+ selwsum += dw->weight; |
+ } |
+ } |
+ if(selwsum && selwsum+brush_change > 0) { |
+ return (selwsum+brush_change)/selwsum; |
+ } |
+ return 0.0f; |
+} |
+/*Jason*/ |
+// change the weights back to the wv's weights |
+// it assumes you already have the correct pointer index |
+static void reset_to_prev(MDeformVert *wv, MDeformVert *dv) { |
+ int i; |
+ MDeformWeight *d; |
+ MDeformWeight *w; |
+ for(i = 0; i < dv->totweight; i++) { |
+ d = dv->dw+i; |
+ w = defvert_find_index(wv, d->def_nr); |
+ // if there was no w when there is a d, then the old weight was 0 |
+ if(w) { |
+ d->weight = w->weight; |
+ } else { |
+ d->weight = 0; |
+ } |
+ } |
+} |
+/* Jason */ |
+static void clamp_weights(MDeformVert *dvert) { |
+ int i; |
+ for (i = 0; i < dvert->totweight; i++) { |
+ CLAMP((dvert->dw+i)->weight, 0.0f, 1.0f); |
+ } |
+} |
+/*Jason*/ |
+/* fresh start to make multi-paint and locking modular */ |
+/* returns TRUE if it thinks you need to reset the weights due to normalizing while multi-painting */ |
+static int apply_mp_lcks_normalize(Mesh *me, int index, MDeformWeight *dw, MDeformWeight *tdw, int defbase_len, float change, float oldChange, float oldw, float neww, char *defbase_sel, int selected, char *bone_groups, char *validmap, char *flags, int multipaint) { |
+ MDeformVert *dvert = me->dvert+index; |
+ MDeformVert dv= {NULL}; |
+ |
+ dv.dw= MEM_dupallocN(dvert->dw); |
+ dv.flag = dvert->flag; |
+ dv.totweight = dvert->totweight; |
+ // do not multi-paint if a locked group is selected or the active group is locked |
+ // !flags[dw->def_nr] helps if nothing is selected, but active group is locked |
+ if((flags == NULL) || (has_locked_group_selected(defbase_len, defbase_sel, flags) == FALSE && flags[dw->def_nr] == FALSE)) { |
+ if(multipaint && selected > 1) { |
+ if(change && change!=1) { |
+ multipaint_selection(dvert, change, defbase_sel, defbase_len); |
+ } |
+ } else {// this lets users paint normally, but don't let them paint locked groups |
+ dw->weight = neww; |
+ } |
+ } |
+ clamp_weights(dvert); |
+ |
+ enforce_locks(&dv, dvert, defbase_len, flags, bone_groups, validmap); |
+ |
+ do_weight_paint_auto_normalize_all_groups(dvert, validmap); |
+ |
+ if(oldChange && multipaint && selected > 1) { |
+ if(tdw->weight != oldw) { |
+ if( neww > oldw ) { |
+ if(tdw->weight <= oldw) { |
+ MEM_freeN(dv.dw); |
+ return TRUE; |
+ } |
+ } else { |
+ if(tdw->weight >= oldw) { |
+ MEM_freeN(dv.dw); |
+ return TRUE; |
+ } |
+ } |
+ } |
+ } |
+ MEM_freeN(dv.dw); |
+ return FALSE; |
+} |
+ |
+// within the current dvert index, get the dw that is selected and has a weight above 0 |
+// this helps multi-paint |
+static int get_first_selected_nonzero_weight(MDeformVert *dvert, char *defbase_sel) { |
+ int i; |
+ MDeformWeight *dw; |
+ for(i=0; i< dvert->totweight; i++) { |
+ dw = dvert->dw+i; |
+ if(defbase_sel[dw->def_nr] && dw->weight > 0) { |
+ return i; |
+ } |
+ } |
+ return -1; |
+} |
+// Jason |
+static char *wpaint_make_validmap(Object *ob); |
+ |
static void do_weight_paint_vertex(VPaint *wp, Object *ob, int index, |
ideasman42
2011/09/15 03:00:08
I'd like to see if do_weight_paint_vertex() can be
|
float alpha, float paintweight, int flip, |
- int vgroup_mirror, char *validmap) |
+ int vgroup_mirror, char *validmap, int multipaint) |
{ |
Mesh *me= ob->data; |
- MDeformWeight *dw, *uw; |
+ // Jason: tdw, tuw |
+ MDeformWeight *dw, *uw, *tdw = NULL, *tuw; |
int vgroup= ob->actdef-1; |
+ /* Jason was here */ |
+ char *flags; |
+ char *bone_groups; |
+ char *defbase_sel; |
+ int selected; |
+ float oldw; |
+ float neww; |
+ float testw=0; |
+ int defbase_len; |
+ float change = 0; |
+ float oldChange = 0; |
+ int i; |
+ MDeformVert *dv = NULL; |
+ |
+ // Need to know which groups are bone groups |
+ if(validmap) { |
+ bone_groups = validmap; |
+ }else { |
+ bone_groups = wpaint_make_validmap(ob); |
+ } |
+ |
if(wp->flag & VP_ONLYVGROUP) { |
dw= defvert_find_index(me->dvert+index, vgroup); |
uw= defvert_find_index(wp->wpaint_prev+index, vgroup); |
@@ -1115,10 +1549,78 @@ |
} |
if(dw==NULL || uw==NULL) |
return; |
+ /* Jason was here */ |
+ flags = gen_lck_flags(ob, defbase_len = BLI_countlist(&ob->defbase)); |
+ defbase_sel = MEM_mallocN(defbase_len * sizeof(char), "dg_selected_flags"); |
+ selected = get_selected_defgroups(ob, defbase_sel, defbase_len); |
+ if(!selected && ob->actdef) { |
+ selected = 1; |
+ } |
- wpaint_blend(wp, dw, uw, alpha, paintweight, flip); |
- do_weight_paint_auto_normalize(me->dvert+index, vgroup, validmap); |
+ oldw = dw->weight; |
+ wpaint_blend(wp, dw, uw, alpha, paintweight, flip, multipaint && selected >1); |
+ neww = dw->weight; |
+ dw->weight = oldw; |
+ |
+ // setup multi-paint |
+ if(selected > 1 && multipaint) { |
+ dv = MEM_mallocN(sizeof (*(me->dvert+index)), "prevMDeformVert"); |
+ dv->dw= MEM_dupallocN((me->dvert+index)->dw); |
+ dv->flag = me->dvert[index].flag; |
+ dv->totweight = (me->dvert+index)->totweight; |
+ tdw = dw; |
+ tuw = uw; |
+ change = get_mp_change(wp->wpaint_prev+index, defbase_sel, neww-oldw); |
+ if(change) { |
+ if(!tdw->weight) { |
+ i = get_first_selected_nonzero_weight(me->dvert+index, defbase_sel); |
+ if(i>=0) { |
+ tdw = ((me->dvert+index)->dw+i); |
+ tuw = defvert_verify_index(wp->wpaint_prev+index, tdw->def_nr); |
+ } else { |
+ change = 0; |
+ } |
+ } |
+ if(change && tuw->weight && tuw->weight * change) { |
+ if(tdw->weight != tuw->weight) { |
+ oldChange = tdw->weight/tuw->weight; |
+ testw = tuw->weight*change; |
+ if( testw > tuw->weight ) { |
+ if(change > oldChange) { |
+ // reset the weights and use the new change |
+ reset_to_prev(wp->wpaint_prev+index, me->dvert+index); |
+ } else { |
+ // the old change was more significant, |
+ // so set the change to 0 so that it will not do another multi-paint |
+ change = 0; |
+ } |
+ } else { |
+ if(change < oldChange) { |
+ reset_to_prev(wp->wpaint_prev+index, me->dvert+index); |
+ } else { |
+ change = 0; |
+ } |
+ } |
+ } |
+ } else { |
+ change = 0; |
+ } |
+ } |
+ } |
+ /* Jason was here */ |
+ if(apply_mp_lcks_normalize(me, index, dw, tdw, defbase_len, change, oldChange, oldw, neww, defbase_sel, selected, bone_groups, validmap, flags, multipaint)) { |
+ reset_to_prev(dv, me->dvert+index); |
+ change = 0; |
+ oldChange = 0; |
+ } |
+ if(dv) { |
+ MEM_freeN(dv->dw); |
+ MEM_freeN(dv); |
+ } |
+ // dvert may have been altered greatly |
+ dw = defvert_find_index(me->dvert+index, vgroup); |
+ |
if(me->editflag & ME_EDIT_MIRROR_X) { /* x mirror painting */ |
int j= mesh_get_x_mirror_vert(ob, index); |
if(j>=0) { |
@@ -1127,12 +1629,20 @@ |
uw= defvert_verify_index(me->dvert+j, vgroup_mirror); |
else |
uw= defvert_verify_index(me->dvert+j, vgroup); |
- |
- uw->weight= dw->weight; |
- |
- do_weight_paint_auto_normalize(me->dvert+j, vgroup, validmap); |
+ /* Jason */ |
+ //uw->weight= dw->weight; |
+ /* Jason */ |
+ apply_mp_lcks_normalize(me, j, uw, tdw, defbase_len, change, oldChange, oldw, neww, defbase_sel, selected, bone_groups, validmap, flags, multipaint); |
} |
} |
+ /* Jason */ |
+ if(flags) { |
+ MEM_freeN(flags); |
+ } |
+ MEM_freeN(defbase_sel); |
+ if(!validmap) { |
+ MEM_freeN(bone_groups); |
+ } |
} |
@@ -1389,6 +1899,9 @@ |
float alpha; |
float mval[2], pressure; |
+ // Jason |
+ int use_vert_sel; |
+ |
/* cannot paint if there is no stroke data */ |
if (wpd == NULL) { |
// XXX: force a redraw here, since even though we can't paint, |
@@ -1414,10 +1927,16 @@ |
mval[1]-= vc->ar->winrct.ymin; |
swap_m4m4(wpd->vc.rv3d->persmat, mat); |
- |
+ |
+ // Jason |
+ use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; |
+ |
/* which faces are involved */ |
if(wp->flag & VP_AREA) { |
+ // Ugly hack, to avoid drawing vertex index when getting the face index buffer - campbell |
ideasman42
2011/09/15 03:00:08
I had to add this, but should have made more compr
|
+ me->editflag &= ~ME_EDIT_VERT_SEL; |
totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], brush_size(brush)); |
+ me->editflag |= use_vert_sel ? ME_EDIT_VERT_SEL : 0; |
} |
else { |
indexar[0]= view3d_sample_backbuf(vc, mval[0], mval[1]); |
@@ -1436,7 +1955,7 @@ |
} |
} |
} |
- |
+ |
if((me->editflag & ME_EDIT_PAINT_MASK) && me->mface) { |
for(index=0; index<totindex; index++) { |
if(indexar[index] && indexar[index]<=me->totface) { |
@@ -1460,12 +1979,20 @@ |
for(index=0; index<totindex; index++) { |
if(indexar[index] && indexar[index]<=me->totface) { |
MFace *mface= me->mface + (indexar[index]-1); |
+ |
+ if(use_vert_sel) { |
+ me->dvert[mface->v1].flag = (me->mvert[mface->v1].flag & SELECT); |
+ me->dvert[mface->v2].flag = (me->mvert[mface->v2].flag & SELECT); |
+ me->dvert[mface->v3].flag = (me->mvert[mface->v3].flag & SELECT); |
+ if(mface->v4) me->dvert[mface->v4].flag = (me->mvert[mface->v4].flag & SELECT); |
+ } |
+ else { |
+ me->dvert[mface->v1].flag= 1; |
+ me->dvert[mface->v2].flag= 1; |
+ me->dvert[mface->v3].flag= 1; |
+ if(mface->v4) me->dvert[mface->v4].flag= 1; |
+ } |
- (me->dvert+mface->v1)->flag= 1; |
- (me->dvert+mface->v2)->flag= 1; |
- (me->dvert+mface->v3)->flag= 1; |
- if(mface->v4) (me->dvert+mface->v4)->flag= 1; |
- |
if(brush->vertexpaint_tool==VP_BLUR) { |
MDeformWeight *dw, *(*dw_func)(MDeformVert *, const int); |
@@ -1501,7 +2028,7 @@ |
if(alpha) { |
do_weight_paint_vertex(wp, ob, mface->v1, |
alpha, paintweight, flip, wpd->vgroup_mirror, |
- wpd->vgroup_validmap); |
+ wpd->vgroup_validmap, ts->multipaint); |
} |
(me->dvert+mface->v1)->flag= 0; |
} |
@@ -1511,7 +2038,7 @@ |
if(alpha) { |
do_weight_paint_vertex(wp, ob, mface->v2, |
alpha, paintweight, flip, wpd->vgroup_mirror, |
- wpd->vgroup_validmap); |
+ wpd->vgroup_validmap, ts->multipaint); |
} |
(me->dvert+mface->v2)->flag= 0; |
} |
@@ -1521,7 +2048,7 @@ |
if(alpha) { |
do_weight_paint_vertex(wp, ob, mface->v3, |
alpha, paintweight, flip, wpd->vgroup_mirror, |
- wpd->vgroup_validmap); |
+ wpd->vgroup_validmap, ts->multipaint); |
} |
(me->dvert+mface->v3)->flag= 0; |
} |
@@ -1532,7 +2059,7 @@ |
if(alpha) { |
do_weight_paint_vertex(wp, ob, mface->v4, |
alpha, paintweight, flip, wpd->vgroup_mirror, |
- wpd->vgroup_validmap); |
+ wpd->vgroup_validmap, ts->multipaint); |
} |
(me->dvert+mface->v4)->flag= 0; |
} |
@@ -1645,7 +2172,7 @@ |
/* api callbacks */ |
ot->exec= weight_paint_set_exec; |
- ot->poll= facemask_paint_poll; |
+ ot->poll= mask_paint_poll; // Jason, it was facemask_paint_poll |
/* flags */ |
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; |