Revision: 39123
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=39123
Author:   jwilkins
Date:     2011-08-07 09:13:37 +0000 (Sun, 07 Aug 2011)
Log Message:
-----------
Revision: 30823
Author: nicholasbishop
Date: 12:41:32 AM, Wednesday, July 28, 2010
Message:
== VPaint ==

* Implemented blur brush for non-multires models

----
Modified : 
/branches/soc-2010-nicolasbishop/source/blender/editors/sculpt_paint/paint_vertex.c

--
jwilkins: 

Nick had tried to use IMB_BLEND* values for brush.vertexpaint_tool, but I do 
not think it is completely compatible because IMB_BLEND* are integers not char 
and there is no IMB_BLEND* value for blur.  The more vertex tools are added 
that are not exactly the same as IMB_BLEND* modes the more hacky this will 
seem, so I just decoupled them made a lookup function for the vertexpaint_tools 
that happen to correspond to IMB_BLEND* modes.

Modified Paths:
--------------
    branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_vertex.c
    branches/soc-2011-onion/source/blender/makesdna/DNA_brush_types.h
    branches/soc-2011-onion/source/blender/makesrna/intern/rna_brush.c

Modified: 
branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_vertex.c
===================================================================
--- branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_vertex.c  
2011-08-07 08:58:03 UTC (rev 39122)
+++ branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_vertex.c  
2011-08-07 09:13:37 UTC (rev 39123)
@@ -654,7 +654,7 @@
                }
        }
        
-       if(tool==IMB_BLEND_MIX || tool==VERTEX_PAINT_BLUR)
+       if(tool==IMB_BLEND_MIX || tool==VERTEX_PAINT_TOOL_BLUR)
                dw->weight = paintval*alpha + dw->weight*(1.0f-alpha);
        else if(tool==IMB_BLEND_ADD)
                dw->weight += paintval*alpha;
@@ -677,7 +677,7 @@
                float testw=0.0f;
                
                alpha= brush_alpha(brush);
-               if(tool==IMB_BLEND_MIX || tool==VERTEX_PAINT_BLUR)
+               if(tool==IMB_BLEND_MIX || tool==VERTEX_PAINT_TOOL_BLUR)
                        testw = paintval*alpha + uw->weight*(1.0f-alpha);
                else if(tool==IMB_BLEND_ADD)
                        testw = uw->weight + paintval*alpha;
@@ -1301,7 +1301,7 @@
        /* make sure each vertex gets treated only once */
        /* and calculate filter weight */
        totw= 0;
-       if(brush->vertexpaint_tool==VERTEX_PAINT_BLUR) 
+       if(brush->vertexpaint_tool==VERTEX_PAINT_TOOL_BLUR) 
                paintweight= 0.0f;
        else
                paintweight= ts->vgroup_weight;
@@ -1315,7 +1315,7 @@
                        (me->dvert+mface->v3)->flag= 1;
                        if(mface->v4) (me->dvert+mface->v4)->flag= 1;
                                        
-                       if(brush->vertexpaint_tool==VERTEX_PAINT_BLUR) {
+                       if(brush->vertexpaint_tool==VERTEX_PAINT_TOOL_BLUR) {
                                MDeformWeight *dw, *(*dw_func)(MDeformVert *, 
const int);
                                                
                                if(wp->flag & VP_ONLYVGROUP)
@@ -1337,7 +1337,7 @@
                }
        }
                        
-       if(brush->vertexpaint_tool==VERTEX_PAINT_BLUR) 
+       if(brush->vertexpaint_tool==VERTEX_PAINT_TOOL_BLUR) 
                paintweight/= (float)totw;
                        
        for(index=0; index<totindex; index++) {
@@ -1576,11 +1576,31 @@
                        0);
 }
 
+static int vpaint_to_imb_blend(int vpaint_tool)
+{
+       static int table[8] = {
+               IMB_BLEND_MIX,       /*VERTEX_PAINT_TOOL_MIX*/
+               IMB_BLEND_ADD,       /*VERTEX_PAINT_TOOL_ADD*/
+               IMB_BLEND_SUB,       /*VERTEX_PAINT_TOOL_SUB*/
+               IMB_BLEND_MUL,       /*VERTEX_PAINT_TOOL_MUL*/
+               0, /* invalid value, VERTEX_PAINT_TOOL_BLUR */
+               IMB_BLEND_LIGHTEN,   /*VERTEX_PAINT_TOOL_LIGHTEN*/
+               IMB_BLEND_DARKEN,    /*VERTEX_PAINT_TOOL_DARKEN*/
+               IMB_BLEND_ADD_ALPHA, /*VERTEX_PAINT_TOOL_ADD_ALPHA*/
+       };
+
+       assert(vpaint_tool != VERTEX_PAINT_TOOL_BLUR);
+       assert(vpaint_tool >= 0);
+       assert(vpaint_tool < VERTEX_PAINT_TOOL_BLUR);
+
+       return table[vpaint_tool];
+}
+
 static void vpaint_blend(Brush *brush, float dst[4], float src1[4], float 
src2[4], float fac)
 {
-       int tool = brush->vertexpaint_tool;
+       if (brush->vertexpaint_tool != VERTEX_PAINT_TOOL_BLUR) {
+               int tool= vpaint_to_imb_blend(brush->vertexpaint_tool);
 
-       if (tool != VERTEX_PAINT_BLUR) {
                if (tool == IMB_BLEND_ADD_ALPHA && (brush->flag & BRUSH_DIR_IN))
                        tool = IMB_BLEND_ERASE_ALPHA;
 
@@ -1588,9 +1608,14 @@
        }
 }
 
-static float tex_strength(struct VPaint* vp, struct Brush *brush, struct 
PaintStroke *stroke,
-                         float co[3], float mask, float len,
-                         float radius3d)
+static float tex_strength(
+       struct Brush *brush,
+       struct BrushSpace *bspace,
+       struct PaintStroke *stroke,
+       float co[3],
+       float mask,
+       float len,
+       float radius3d)
 {
 #if 0 // SNIP
        struct Object *ob= CTX_data_active_object(C);
@@ -1621,20 +1646,24 @@
                        tex_mouse,
                        mats);
 #else
-       const BrushSpace *bspace= vp->paint.cache->bspace_symm_curr;
        return paint_strength(brush, bspace, co, NULL, mask, len);
 #endif
 }
 
 /* apply paint at specified coordinate
    returns 1 if paint was applied, 0 otherwise */
-static int vpaint_paint_coord(struct VPaint *vp, struct PaintStroke *stroke,
-                             float co[3], float col[4],
-                             float center[3], float radius,
-                             float radius_squared, float mask)
+static int vpaint_paint_coord(
+       struct Brush *brush,
+       struct BrushSpace *bspace,
+       struct PaintStroke *stroke,
+       float co[3],
+       float col[4],
+       float center[3],
+       float radius,
+       float radius_squared,
+       float mask)
 {
        VPaintData *vpd= paint_stroke_mode_data(stroke);
-       struct Brush *brush = paint_brush(&vp->paint);
        float fac, dist, dist_squared;
 
        dist_squared = len_squared_v3v3(center, co);
@@ -1643,7 +1672,7 @@
                dist = sqrtf(dist_squared);
 
                fac= vpd->fac *
-                       tex_strength(vp, brush, stroke, co, mask, dist, radius);
+                       tex_strength(brush, bspace, stroke, co, mask, dist, 
radius);
 
                vpaint_blend(brush, col, col, vpd->color, fac);
 
@@ -1653,42 +1682,62 @@
        return 0;
 }
 
-static void vpaint_nodes_grids(struct VPaint *vp, struct PaintStroke *stroke,
-                              DMGridData **grids, CustomData *vdata,
-                              GridKey *gridkey,
-                              int *grid_indices, int totgrid,
-                              int gridsize, int active, float center[3],
-                              float radius)
+static void vpaint_nodes_grids(
+       struct Brush *brush,
+       struct BrushSpace *bspace,
+       struct PaintStroke *stroke,
+       struct DMGridData **grids,
+       struct CustomData *vdata,
+       struct GridKey *gridkey,
+       int *grid_indices,
+       int totgrid,
+       int gridsize,
+       int active,
+       float center[3],
+       float radius)
 {
-       float radius_squared = radius*radius;
+       float radius_squared= radius*radius;
        int i, x, y;
 
        for(i = 0; i < totgrid; ++i) {
-               DMGridData *grid = grids[grid_indices[i]];
+               struct DMGridData *grid= grids[grid_indices[i]];
 
                for(y = 0; y < gridsize; ++y) {
                        for(x = 0; x < gridsize; ++x) {
-                               DMGridData *elem = GRIDELEM_AT(grid,
-                                                              y*gridsize+x,
-                                                              gridkey);
-                               float *co = GRIDELEM_CO(elem, gridkey);
-                               float *gridcol = GRIDELEM_COLOR(elem, 
gridkey)[active];
-                               float mask = paint_mask_from_gridelem(elem,
-                                                                     gridkey,
-                                                                     vdata);
+                               struct DMGridData *elem=
+                                       GRIDELEM_AT(
+                                               grid,
+                                               y*gridsize + x,
+                                               gridkey);
 
-                               vpaint_paint_coord(vp, stroke, co,
-                                                  gridcol,
-                                       center, radius,
-                                                  radius_squared,
-                                                  mask);
-                               }
+                               float *co= GRIDELEM_CO(elem, gridkey);
+
+                               float *gridcol= GRIDELEM_COLOR(elem, 
gridkey)[active];
+
+                               float mask=
+                                       paint_mask_from_gridelem(
+                                               elem,
+                                               gridkey,
+                                               vdata);
+
+                               vpaint_paint_coord(
+                                       brush,
+                                       bspace,
+                                       stroke,
+                                       co,
+                                       gridcol,
+                                       center,
+                                       radius,
+                                       radius_squared,
+                                       mask);
                        }
                }
        }
+}
 
 static void vpaint_nodes_faces(
-       struct VPaint *vp,
+       struct Brush *brush,
+       struct BrushSpace *bspace,
        struct PaintStroke *stroke,
        struct MFace *mface,
        struct MVert *mvert,
@@ -1733,7 +1782,8 @@
                                        pmask_first_layer);
 
                        vpaint_paint_coord(
-                               vp,
+                               brush,
+                               bspace,
                                stroke,
                                co,
                                fcol,
@@ -1750,6 +1800,95 @@
        }
 }
 
+static void vpaint_nodes_faces_smooth(
+       struct Brush *brush,
+       struct BrushSpace *bspace,
+       struct PaintStroke *stroke,
+       struct PBVH *pbvh,
+       struct PBVHNode *node,
+       struct MFace *mface,
+       struct CustomData *fdata,
+       struct ListBase *fmap,
+       float center[3],
+       float radius,
+       float radius_squared)
+{
+       struct PBVHVertexIter vd;
+       struct PaintStrokeTest test;
+       struct MCol *mcol;
+       
+       paint_stroke_test_init(&test, center, radius_squared);
+       mcol = CustomData_get_layer(fdata, CD_MCOL);
+
+       BLI_pbvh_vertex_iter_begin(pbvh, node, vd, PBVH_ITER_UNIQUE) {
+               if(paint_stroke_test(&test, vd.co)) {
+                       struct IndexNode *n;
+                       float strength, avg_col[4] = {0, 0, 0, 0};
+                       int vndx = vd.vert_indices[vd.i], totcol, i, j;
+
+                       /* first find average color from neighboring faces */
+                       totcol = 0;
+                       for(n = fmap[vndx].first; n; n = n->next) {
+                               int fndx = n->index;
+                               MFace *f = &mface[fndx];
+                               int S = f->v4 ? 4 : 3;
+
+                               for(i = 0; i < S; ++i) {
+                                       int cndx = fndx*4 + i;
+
+                                       avg_col[0] += mcol[cndx].b / 255.0;
+                                       avg_col[1] += mcol[cndx].g / 255.0;
+                                       avg_col[2] += mcol[cndx].r / 255.0;
+                                       avg_col[3] += mcol[cndx].a / 255.0;
+                                       
+                                       ++totcol;
+                               }
+                       }
+
+                       for(i = 0; i < 4; ++i)
+                               avg_col[i] /= totcol;
+
+                       /* for all face corners matching vndx,
+                          interp towards the averaged color */
+                       for(n = fmap[vndx].first; n; n = n->next) {
+                               int fndx = n->index;
+                               MFace *f = &mface[fndx];
+                               int S = f->v4 ? 4 : 3;
+
+                               for(i = 0; i < S; ++i) {
+                                       int cndx = fndx*4 + i;
+
+                                       if((&f->v1)[i] != vndx)
+                                               continue;
+
+                                       strength =
+                                               brush->alpha *
+                                               tex_strength(
+                                                       brush,
+                                                       bspace,
+                                                       stroke,
+                                                       vd.co,
+                                                       vd.mask_combined,
+                                                       test.dist,
+                                                       radius);
+
+                                       for(j = 0; j < 4; ++j) {
+                                               unsigned char *c;
+                                               float col;
+
+                                               c = ((unsigned 
char*)(&mcol[cndx])) + j;
+
+                                               col = *c / 255.0f;
+                                               col = interpf(avg_col[3 - j], 
col, strength);
+                                               *c = col * 255.0f;
+                                       }
+                               }
+                       }
+               }
+       }
+       BLI_pbvh_vertex_iter_end;
+}
+
 static int vpaint_find_gridkey_active_layer(CustomData *fdata, GridKey 
*gridkey)
 {
        int active, i;
@@ -1768,14 +1907,25 @@
        return -1;
 }
 
-static void vpaint_nodes(struct VPaint *vp, struct PaintStroke *stroke,
-                        PBVH *pbvh,
-                        PBVHNode **nodes, int totnode,
-                        float center[3], float radius)
+static void vpaint_nodes(
+       struct VPaint *vp,
+       struct BrushSpace *bspace,
+       struct PaintStroke *stroke,
+       struct Scene *scene,
+       struct Object *ob,
+       struct PBVHNode **nodes,
+       int totnode,
+       float center[3],
+       float radius)
 {
+       PBVH *pbvh = ob->paint->pbvh;
+       Brush *brush = paint_brush(&vp->paint);
        int n;
 
        for(n = 0; n < totnode; ++n) {
+               DerivedMesh *dm;
+               ListBase *fmap;
+
                MVert *mvert;
                MFace *mface;
                CustomData *vdata = NULL;
@@ -1788,32 +1938,79 @@
 
                BLI_pbvh_node_get_verts(pbvh, nodes[n], NULL, &mvert, &vdata);
 
-               BLI_pbvh_node_get_faces(pbvh, nodes[n], &mface, &fdata,
-                                       &face_indices, NULL, &totface);
+               BLI_pbvh_node_get_faces(
+                       pbvh,
+                       nodes[n],
+                       &mface,
+                       &fdata,
+                       &face_indices,
+                       NULL,
+                       &totface);
 
-               BLI_pbvh_node_get_grids(pbvh, nodes[n], &grid_indices,
-                                       &totgrid, NULL, &gridsize, &grids,
-                                       NULL, &gridkey);
+               BLI_pbvh_node_get_grids(
+                       pbvh,
+                       nodes[n],
+                       &grid_indices,
+                       &totgrid,
+                       NULL,
+                       &gridsize,
+                       &grids,
+                       NULL,
+                       &gridkey);
 
-               if(grids) {
-                       int active = vpaint_find_gridkey_active_layer(fdata,
-                                                                     gridkey);
+               if (grids) {
+                       int active= vpaint_find_gridkey_active_layer(fdata, 
gridkey);
 
                        if(active != -1) {
-                               vpaint_nodes_grids(vp, stroke, grids, vdata,
-                                                  gridkey,
-                                                  grid_indices, totgrid,
-                                                  gridsize, active, center,
-                                                  radius);
+                               vpaint_nodes_grids(
+                                       brush,
+                                       bspace,
+                                       stroke,
+                                       grids,
+                                       vdata,
+                                       gridkey,
+                                       grid_indices,
+                                       totgrid,
+                                       gridsize,
+                                       active,
+                                       center,
+                                       radius);
                        }
                }

@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to