Merged 38822-39182
[blender.git] / source / blender / blenkernel / intern / DerivedMesh.c
index 62b8830..dd2f3e2 100644 (file)
@@ -40,6 +40,9 @@
 #include "DNA_cloth_types.h"
 #include "DNA_key_types.h"
 #include "DNA_meshdata_types.h"
+// Jason
+#include "DNA_armature_types.h"
+
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h" // N_T
 
@@ -72,6 +75,8 @@
 #include "GPU_material.h"
 
 #include "ED_sculpt.h" /* for ED_sculpt_modifiers_changed */
+// Jason was here, this is for multi-paint
+#include "ED_armature.h"
 
 ///////////////////////////////////
 ///////////////////////////////////
@@ -1602,19 +1607,50 @@ void weight_to_rgb(float input, float *fr, float *fg, float *fb)
        }
 }
 
-static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, unsigned char *col)
+static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, unsigned char *col, char *dg_flags, int selected, int unselected, int multipaint, int auto_normalize)
 {
        Mesh *me = ob->data;
-       float colf[4], input = 0.0f;
+       float colf[4], input = 0.0f;// Jason
        int i;
+       char make_black = FALSE;
+       char was_a_nonzero = FALSE;
 
        if (me->dvert) {
-               for (i=0; i<me->dvert[vert].totweight; i++)
-                       if (me->dvert[vert].dw[i].def_nr==ob->actdef-1)
-                               input+=me->dvert[vert].dw[i].weight;            
-       }
+               for (i=0; i<me->dvert[vert].totweight; i++) {
+                       // Jason was here
+                       // in multipaint, get the average if auto normalize is inactive
+                       // get the sum if it is active
+                       if(multipaint && selected > 1) {
+                               if(dg_flags[me->dvert[vert].dw[i].def_nr]) {
+                                       if(me->dvert[vert].dw[i].weight) {
+                                               input+=me->dvert[vert].dw[i].weight;
+                                               was_a_nonzero = TRUE;
+                                       }
+                               }
+                       } else if (me->dvert[vert].dw[i].def_nr==ob->actdef-1) {
+                               input+=me->dvert[vert].dw[i].weight;
+                       }
+               }
+               
+               // Jason was here
+               // make it black if the selected groups have no weight on a vertex
+               if(!make_black && multipaint && selected > 1) {
+                       if(!was_a_nonzero) {
+                               make_black = TRUE;
+                       } else if (!auto_normalize){
+                               // get the average
+                               input /= selected;
+                       }
 
-       CLAMP(input, 0.0f, 1.0f);
+               }
+       }
+       
+       if(make_black) {
+               input = -1;
+       }else {
+               CLAMP(input, 0.0f, 1.0f);
+       }
+       
        
        if(coba)
                do_colorband(coba, input, colf);
@@ -1633,26 +1669,69 @@ void vDM_ColorBand_store(ColorBand *coba)
 {
        stored_cb= coba;
 }
-
-static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm)
+/* TODO move duplicates to header */
+/* Jason was here duplicate function in paint_vertex.c*/
+static char* get_selected_defgroups(Object *ob, int defcnt) {
+       bPoseChannel *chan;
+       bPose *pose;
+       bDeformGroup *defgroup;
+       //Bone *bone;
+       char *dg_flags = MEM_callocN(defcnt*sizeof(char), "dg_selected_flags");
+       int i;
+       Object *armob = ED_object_pose_armature(ob);
+
+       if(armob) {
+               pose = armob->pose;
+               for (chan=pose->chanbase.first; chan; chan=chan->next) {
+                       for (i = 0, defgroup = ob->defbase.first; i < defcnt && defgroup; defgroup = defgroup->next, i++) {
+                               if(!strcmp(defgroup->name, chan->bone->name)) {
+                                       dg_flags[i] = (chan->bone->flag & BONE_SELECTED);
+                               }
+                       }
+               }
+       }
+       
+       return dg_flags;
+}
+/* TODO move duplicates to header */
+/* Jason was here duplicate function */
+static int count_true(char *list, int len)
+{
+       int i;
+       int cnt = 0;
+       for(i = 0; i < len; i++) {
+               if (list[i]) {
+                       cnt++;
+               }
+       }
+       return cnt;
+}
+static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int multipaint, int auto_normalize)
 {
        Mesh *me = ob->data;
        MFace *mf = me->mface;
        ColorBand *coba= stored_cb;     /* warning, not a local var */
        unsigned char *wtcol;
        int i;
-       
+       // Jason was here
+       int defcnt = BLI_countlist(&ob->defbase);
+       char *dg_flags = get_selected_defgroups(ob, defcnt);
+       int selected = count_true(dg_flags, defcnt);
+       int unselected = defcnt - selected;
+
        wtcol = MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
        
        memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
        for (i=0; i<me->totface; i++, mf++) {
-               calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4]); 
-               calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4]); 
-               calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4]); 
+               calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4], dg_flags, selected, unselected, multipaint, auto_normalize); 
+               calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4], dg_flags, selected, unselected, multipaint, auto_normalize); 
+               calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4], dg_flags, selected, unselected, multipaint, auto_normalize); 
                if (mf->v4)
-                       calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4]); 
+                       calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4], dg_flags, selected, unselected, multipaint, auto_normalize); 
        }
-       
+       // Jason
+       MEM_freeN(dg_flags);
+
        CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, dm->numFaceData);
 }
 
@@ -1859,7 +1938,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
                                }
 
                                if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT))
-                                       add_weight_mcol_dm(ob, dm);
+                                       add_weight_mcol_dm(ob, dm, scene->toolsettings->multipaint, scene->toolsettings->auto_normalize);// Jason
 
                                /* Constructive modifiers need to have an origindex
                                 * otherwise they wont have anywhere to copy the data from.
@@ -1971,7 +2050,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
                CDDM_calc_normals(finaldm);
 
                if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT))
-                       add_weight_mcol_dm(ob, finaldm);
+                       add_weight_mcol_dm(ob, finaldm, scene->toolsettings->multipaint, scene->toolsettings->auto_normalize);// Jason
        } else if(dm) {
                finaldm = dm;
        } else {
@@ -1983,7 +2062,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
                }
 
                if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT))
-                       add_weight_mcol_dm(ob, finaldm);
+                       add_weight_mcol_dm(ob, finaldm, scene->toolsettings->multipaint, scene->toolsettings->auto_normalize);// Jason
        }
 
        /* add an orco layer if needed */
@@ -2256,7 +2335,7 @@ static void clear_mesh_caches(Object *ob)
 static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
 {
        Object *obact = scene->basact?scene->basact->object:NULL;
-       int editing = paint_facesel_test(ob);
+       int editing = paint_facesel_test(ob) || paint_vertsel_test(ob);// Jason: paint_vertsel_test
        /* weight paint and face select need original indices because of selection buffer drawing */
        int needMapping = (ob==obact) && (editing || (ob->mode & (OB_MODE_WEIGHT_PAINT|OB_MODE_VERTEX_PAINT)));