Revision: 17344
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17344
Author:   campbellbarton
Date:     2008-11-06 03:08:41 +0100 (Thu, 06 Nov 2008)

Log Message:
-----------
added support for smear brush type

Modified Paths:
--------------
    branches/projection-paint/source/blender/src/imagepaint.c

Modified: branches/projection-paint/source/blender/src/imagepaint.c
===================================================================
--- branches/projection-paint/source/blender/src/imagepaint.c   2008-11-06 
01:30:24 UTC (rev 17343)
+++ branches/projection-paint/source/blender/src/imagepaint.c   2008-11-06 
02:08:41 UTC (rev 17344)
@@ -220,7 +220,7 @@
 
 typedef struct ProjectPixelClone {
        struct ProjectPixel __pp;
-       char backbuf[4];        /* TODO - float buffer? */
+       /*char backbuf[4];      *//* TODO - float buffer? */
        char clonebuf[4];
        //void *source;         /* pointer to source pixels */
 } ProjectPixelClone;
@@ -490,7 +490,7 @@
 }
 
 /* bucket_index is optional, since in some cases we know it */
-static int screenco_pickcol(ProjectPaintState *ps, int bucket_index, float 
pt[2], char rgba[4], int interp)
+static int screenco_pickcol(ProjectPaintState *ps, float pt[2], char rgba[4], 
int interp)
 {
        float w[3], uv[2];
        int side;
@@ -1065,23 +1065,23 @@
                        projPixel->pixel = (( char * ) ibuf->rect) + (( x + y * 
ibuf->x ) * pixel_size);
                        VECCOPY2D(projPixel->projCo2D, pixelScreenCo);
                        
-                       /* copy pixel color to backbuf */
-                       memcpy( &(((ProjectPixelClone *)projPixel)->backbuf), 
projPixel->pixel, pixel_size);
+                       /* copy pixel color to backbuf - not used yet */
+                       /* memcpy( &(((ProjectPixelClone 
*)projPixel)->backbuf), projPixel->pixel, pixel_size); */
                        //((ProjectPixelClone *)projPixel)->source = NULL; /* 
must be set later */
                        
                        
                        /* Initialize clone pixels - note that this is a bit of 
a waste since some of these are being indirectly initialized :/ */
                        /* TODO - possibly only run this for directly ativated 
buckets when cloning */
                        Vec2Subf(co, projPixel->projCo2D, ps->cloneOfs);
-                               
+                       
                        /* no need to initialize the bucket, we're only 
checking buckets faces and for this
                         * the faces are alredy initialized in 
project_paint_delayed_face_init(...) */
-                       if (!screenco_pickcol(ps, bucket_index, co, 
((ProjectPixelClone *)projPixel)->clonebuf, 1)) {
+                       if (!screenco_pickcol(ps, co, ((ProjectPixelClone 
*)projPixel)->clonebuf, 1)) {
                                ((ProjectPixelClone *)projPixel)->clonebuf[3] = 
0; /* zero alpha - ignore */
                        }
-
                } else {
-                       projPixel = (ProjectPixel 
*)BLI_memarena_alloc(ps->projectArena, sizeof(ProjectPixel));
+                       /* smear needs the buffer from a clone pixel */
+                       projPixel = (ProjectPixel 
*)BLI_memarena_alloc(ps->projectArena, (ps->tool==PAINT_TOOL_SMEAR) ? 
sizeof(ProjectPixelClone) : sizeof(ProjectPixel));
                        projPixel->pixel = (( char * ) ibuf->rect) + (( x + y * 
ibuf->x ) * pixel_size);
                        VECCOPY2D(projPixel->projCo2D, pixelScreenCo);
                }
@@ -2293,7 +2293,7 @@
        return 0;
 }
 
-static int imapaint_paint_sub_stroke_project(ProjectPaintState *ps, 
BrushPainter *painter, short mval[2], double time, int update, float pressure)
+static int imapaint_paint_sub_stroke_project(ProjectPaintState *ps, 
BrushPainter *painter, short prevmval[2], short mval[2], double time, int 
update, float pressure)
 {
        /* TODO - texpaint option : is there any use in projection painting 
from the image window??? - could be interesting */
        /* TODO - floating point images */
@@ -2313,11 +2313,14 @@
        int bucket_index;
        int a;
        short blend= ps->blend;
-       
        char *cp;
-       
        int bucket_x, bucket_y;
        
+       /* for smear only */
+       float mval_ofs[2]; 
+       float co[2];
+       LinkNode *smearPixels = NULL;
+       MemArena *smearArena = NULL; /* mem arena for this brush projection 
only */
        
        mval_f[0] = mval[0]; mval_f[1] = mval[1]; 
        
@@ -2335,6 +2338,14 @@
                return 0;
        }
        
+       if (ps->tool==PAINT_TOOL_SMEAR) {
+               mval_ofs[0] = (float)(mval[0] - prevmval[0]);
+               mval_ofs[1] = (float)(mval[1] - prevmval[1]);
+               
+               smearArena = BLI_memarena_new(1<<16);
+       }
+       
+       
        /* avoid a square root with every dist comparison */
        brush_size_sqared = ps->brush->size * ps->brush->size; 
        
@@ -2377,24 +2388,51 @@
                                                        
                                                        dist = 
(float)sqrt(dist_nosqrt);
                                                        
-                                                       if 
(ps->tool==PAINT_TOOL_CLONE && ((char 
*)((ProjectPixelClone*)projPixel)->clonebuf)[3]) { //&& 
((ProjectPixelClone*)projPixel)->source )  {
-                                                               alpha = 
brush_sample_falloff(ps->brush, dist);
-                                                               
-                                                               if (alpha <= 
0.0) {
-                                                                       /* do 
nothing */
-                                                               } else {
-                                                                       cp = 
(char *)((ProjectPixelClone*)projPixel)->clonebuf;
-                                                                       if 
(alpha >= 1.0) {
-                                                                               
projPixel->pixel[0] = FTOCHAR( cp[0] );
-                                                                               
projPixel->pixel[1] = FTOCHAR( cp[1] );
-                                                                               
projPixel->pixel[2] = FTOCHAR( cp[2] );
+                                                       switch(ps->tool) {
+                                                       case PAINT_TOOL_CLONE:
+                                                               if (((char 
*)((ProjectPixelClone*)projPixel)->clonebuf)[3]) {
+                                                                       alpha = 
brush_sample_falloff(ps->brush, dist);
+                                                                       if 
(alpha <= 0.0) {
+                                                                               
/* do nothing */
                                                                        } else {
-                                                                               
projPixel->pixel[0] = FTOCHAR( (((cp[0]/255.0) * alpha) + 
(((projPixel->pixel[0])/255.0)*(1.0-alpha))) );
-                                                                               
projPixel->pixel[1] = FTOCHAR( (((cp[1]/255.0) * alpha) + 
(((projPixel->pixel[1])/255.0)*(1.0-alpha))) );
-                                                                               
projPixel->pixel[2] = FTOCHAR( (((cp[2]/255.0) * alpha) + 
(((projPixel->pixel[2])/255.0)*(1.0-alpha))) );
+                                                                               
cp = (char *)((ProjectPixelClone*)projPixel)->clonebuf;
+                                                                               
if (alpha >= 1.0) {
+                                                                               
        projPixel->pixel[0] = FTOCHAR( cp[0] );
+                                                                               
        projPixel->pixel[1] = FTOCHAR( cp[1] );
+                                                                               
        projPixel->pixel[2] = FTOCHAR( cp[2] );
+                                                                               
} else {
+                                                                               
        projPixel->pixel[0] = FTOCHAR( (((cp[0]/255.0) * alpha) + 
(((projPixel->pixel[0])/255.0)*(1.0-alpha))) );
+                                                                               
        projPixel->pixel[1] = FTOCHAR( (((cp[1]/255.0) * alpha) + 
(((projPixel->pixel[1])/255.0)*(1.0-alpha))) );
+                                                                               
        projPixel->pixel[2] = FTOCHAR( (((cp[2]/255.0) * alpha) + 
(((projPixel->pixel[2])/255.0)*(1.0-alpha))) );
+                                                                               
}
                                                                        }
+                                                                       
                                                                }
-                                                       } else {
+                                                               break;
+                                                       case PAINT_TOOL_SMEAR:
+                                                               Vec2Subf(co, 
projPixel->projCo2D, mval_ofs);
+                                                               if 
(screenco_pickcol(ps, co, rgba_ub, 1)) {
+                                                                       
brush_sample_tex(ps->brush, projPixel->projCo2D, rgba);
+                                                                       alpha = 
rgba[3]*brush_sample_falloff(ps->brush, dist);
+                                                                       /* 
drat! - this could almost be very simple if we ignore
+                                                                        * the 
fact that applying the color directly gives feedback,
+                                                                        * 
instead, collect the colors and apply after :/ */
+                                                                       
+#if 0                                                          /* looks OK but 
not correct */
+                                                                       
*((unsigned int *)projPixel->pixel) = IMB_blend_color( *((unsigned int 
*)projPixel->pixel), *((unsigned int *)rgba_ub), (int)(alpha*255), blend);
+#endif
+                                                                       
+                                                                       /* add 
to memarena instead */
+                                                                       
*((unsigned int *) &((ProjectPixelClone *)projPixel)->clonebuf) = 
IMB_blend_color( *((unsigned int *)projPixel->pixel), *((unsigned int 
*)rgba_ub), (int)(alpha*255), blend);
+                                                                       
BLI_linklist_prepend_arena(
+                                                                               
&smearPixels,
+                                                                               
(void *)projPixel,
+                                                                               
smearArena
+                                                                       );
+                                                                       
+                                                               }
+                                                               break;
+                                                       default:
                                                                
brush_sample_tex(ps->brush, projPixel->projCo2D, rgba);
                                                                alpha = 
rgba[3]*brush_sample_falloff(ps->brush, dist);
                                                                if (alpha > 
0.0) {
@@ -2405,13 +2443,15 @@
                                                                        
                                                                        
*((unsigned int *)projPixel->pixel) = IMB_blend_color( *((unsigned int 
*)projPixel->pixel), *((unsigned int *)rgba_ub), (int)(alpha*255), blend);
                                                                }
+                                                               break;
+                                                               
                                                        }
                                                        
+                                                       
                                                        if (last_index != 
projPixel->image_index) {
                                                                last_index = 
projPixel->image_index;
                                                                
ps->projectImages[last_index]->id.flag |= LIB_DOIT;
                                                        }
-                                                       
                                                }
                                                
                                                node = node->next;
@@ -2421,6 +2461,18 @@
                }
        }
 
+       
+       if (ps->tool==PAINT_TOOL_SMEAR) {
+               if ((node = smearPixels)) {
+                       do {
+                               projPixel = node->link;
+                               *((unsigned int *)projPixel->pixel) = 
*((unsigned int *)(((ProjectPixelClone *)projPixel)->clonebuf));
+                               node = node->next;
+                       } while (node);
+               }
+               
+               BLI_memarena_free(smearArena);
+       }
        /* Loop over all images on this mesh and update any we have touched */
        for (a=0; a < ps->projectImageTotal; a++) {
                Image *ima = ps->projectImages[a];
@@ -2431,7 +2483,6 @@
                        ima->id.flag &= ~LIB_DOIT; /* clear for reuse */
                }
        }
-       
        return redraw;
 }
 
@@ -2522,7 +2573,7 @@
        
        /* TODO - support more brush operations, airbrush etc */
        {
-               redraw |= imapaint_paint_sub_stroke_project(ps, painter, mval, 
time, 1, pressure);
+               redraw |= imapaint_paint_sub_stroke_project(ps, painter, 
prevmval, mval, time, 1, pressure);
        }
        
        if (redraw) {
@@ -2626,6 +2677,13 @@
                time= PIL_check_seconds_timer();
 
                if (project) { /* Projection Painting */
+                       /* TODO - brush outline, dosnt work yet */
+                       /*
+                       persp(PERSP_WIN);
+                       fdrawXORcirc(mval[0], mval[1], ps.brush->size);
+                       draw_sel_circle(mval, prevmval, ps.brush->size, 
ps.brush->size, 0);
+                       persp(PERSP_VIEW);
+                       */
                        if((mval[0] != prevmval[0]) || (mval[1] != 
prevmval[1])) {
                                imapaint_paint_stroke_project(&ps, painter, 
prevmval, mval, time, pressure);
                                prevmval[0]= mval[0];


_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to