calculate weight paint colors once per vertex rather then on every face corner (was...
authorCampbell Barton <ideasman42@gmail.com>
Mon, 19 Dec 2011 22:55:04 +0000 (22:55 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 19 Dec 2011 22:55:04 +0000 (22:55 +0000)
Quick shows over 2x speedup in my tests, will give bigger speedup with more vertex groups.

If you happen to have vertices with no faces using them - vertex colors will be calculated unnecessarily, but this isnt a common use case for weight paint mode.

source/blender/blenkernel/BKE_texture.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/texture.c

index 52fa52a..7f321ab 100644 (file)
@@ -67,7 +67,7 @@ void free_plugin_tex(struct PluginTex *pit);
 
 void init_colorband(struct ColorBand *coba, int rangetype);
 struct ColorBand *add_colorband(int rangetype);
-int do_colorband(struct ColorBand *coba, float in, float out[4]);
+int do_colorband(const struct ColorBand *coba, float in, float out[4]);
 void colorband_table_RGBA(struct ColorBand *coba, float **array, int *size);
 int vergcband(const void *a1, const void *a2);
 struct CBData *colorband_element_add(struct ColorBand *coba, float position);
index 3bc2ee6..c078de8 100644 (file)
@@ -642,7 +642,7 @@ enum {
        CALC_WP_AUTO_NORMALIZE= (1<<1)
 };
 
-void weightpaint_color(unsigned char r_col[4], ColorBand *coba, const float input)
+static void weightpaint_color(unsigned char r_col[4], ColorBand *coba, const float input)
 {
        float colf[4];
 
@@ -669,10 +669,10 @@ static void calc_weightpaint_vert_color(
 
        if ((selected > 1) && (draw_flag & CALC_WP_MULTIPAINT)) {
                int was_a_nonzero= FALSE;
-               int i;
+               unsigned int i;
 
                MDeformWeight *dw= dv->dw;
-               for (i = dv->totweight; i > 0; i--, dw++) {
+               for (i = dv->totweight; i != 0; i--, dw++) {
                        /* in multipaint, get the average if auto normalize is inactive
                         * get the sum if it is active */
                        if (dw->def_nr < defbase_tot) {
@@ -717,46 +717,63 @@ void vDM_ColorBand_store(ColorBand *coba)
        stored_cb= coba;
 }
 
-static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag)
+/* return an array of vertex weight colors */
+static unsigned char *calc_weightpaint_vert_array(Object *ob, int const draw_flag, ColorBand *coba)
 {
        Mesh *me = ob->data;
-       ColorBand *coba= stored_cb;     /* warning, not a local var */
-
-       unsigned char *wtcol = MEM_mallocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
+       unsigned char *wtcol_v = MEM_callocN (sizeof(unsigned char) * me->totvert * 4, "weightmap_v");
 
        if (me->dvert) {
-               MDeformVert *dvert= me->dvert;
-               MFace *mf = me->mface;
+               unsigned char *wc = wtcol_v;
+               MDeformVert *dv= me->dvert;
+               unsigned int i;
 
+               /* varisbles for multipaint */
                const int defbase_tot = BLI_countlist(&ob->defbase);
                const int defbase_act = ob->actdef-1;
                char *dg_flags = MEM_mallocN(defbase_tot * sizeof(char), __func__);
                const int selected = get_selected_defgroups(ob, dg_flags, defbase_tot);
                /* const int unselected = defbase_tot - selected; */ /* UNUSED */
 
-               int i;
-
-               memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
-               for (i=0; i<me->totface; i++, mf++) {
-                       unsigned int fidx= mf->v4 ? 3:2;
-                       do {
-                               calc_weightpaint_vert_color(&wtcol[(i*4 + fidx)*4],
-                                                           &dvert[*(&mf->v1 + fidx)], coba,
-                                                           defbase_tot, defbase_act,
-                                                           dg_flags, selected, draw_flag);
-                       } while (fidx--);
+               for (i = me->totvert; i != 0; i--, wc += 4, dv++) {
+                       calc_weightpaint_vert_color(wc, dv, coba, defbase_tot, defbase_act, dg_flags, selected, draw_flag);
                }
 
                MEM_freeN(dg_flags);
        }
        else {
-               /* no weights, fill in zero */
                int col_i;
                weightpaint_color((unsigned char *)&col_i, coba, 0.0f);
-               fill_vn_i((int *)wtcol, me->totface*4, col_i);
+               fill_vn_i((int *)wtcol_v, me->totvert, col_i);
+       }
+
+       return wtcol_v;
+}
+
+#include "PIL_time.h"
+
+static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag)
+{
+       ColorBand *coba= stored_cb;     /* warning, not a local var */
+
+       Mesh *me = ob->data;
+       unsigned char *wtcol_v = calc_weightpaint_vert_array(ob, draw_flag, coba);
+       unsigned char *wtcol_f = MEM_mallocN (sizeof(unsigned char) * me->totface*4*4, "weightmap_f");
+
+       MFace *mf = me->mface;
+       int i;
+
+       for (i=0; i<me->totface; i++, mf++) {
+               unsigned int fidx= mf->v4 ? 3:2;
+               do {
+                       copy_v4_v4_char((char *)&wtcol_f[(4 * i + fidx) * 4],
+                                       (char *)&wtcol_v[4 * (*(&mf->v1 + fidx))]);
+               } while (fidx--);
        }
 
-       CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, dm->numFaceData);
+       MEM_freeN(wtcol_v);
+
+       CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol_f, dm->numFaceData);
 }
 
 /* new value for useDeform -1  (hack for the gameengine):
index 93404dc..7051376 100644 (file)
@@ -349,9 +349,9 @@ ColorBand *add_colorband(int rangetype)
 
 /* ------------------------------------------------------------------------- */
 
-int do_colorband(ColorBand *coba, float in, float out[4])
+int do_colorband(const ColorBand *coba, float in, float out[4])
 {
-       CBData *cbd1, *cbd2, *cbd0, *cbd3;
+       const CBData *cbd1, *cbd2, *cbd0, *cbd3;
        float fac, mfac, t[4];
        int a;