Revision: 17502
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17502
Author:   campbellbarton
Date:     2008-11-19 08:57:25 +0100 (Wed, 19 Nov 2008)

Log Message:
-----------
* use utility function brush_painter_paint that runs the project_paint_op in a 
callback, (hopefully making tablets work properly)
* removed own interpolation function, use bilinear_interpolation_color instead.

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-19 
05:30:52 UTC (rev 17501)
+++ branches/projection-paint/source/blender/src/imagepaint.c   2008-11-19 
07:57:25 UTC (rev 17502)
@@ -262,13 +262,13 @@
 {
        float *f_pt;                    /* float buffer */
        unsigned int *uint_pt; /* 2 ways to access a char buffer */
-       char *ch_pt;
+       unsigned char *ch_pt;
 } PixelPointer;
 
 typedef union pixelStore
 {
-       char ch[4];
-       int uint;
+       unsigned char ch[4];
+       unsigned int uint;
 } PixelStore;
 
 typedef struct ProjPixel {
@@ -648,98 +648,8 @@
        return best_face_index; /* will be -1 or a valid face */
 }
 
-/* TODO move to "source/blender/imbuf/intern/imageprocess.c" - also try 
bilinear weight which is faster */
-
-/**************************************************************************
-*                            INTERPOLATIONS 
-*
-* Reference and docs:
-* http://wiki.blender.org/index.php/User:Damiles#Interpolations_Algorithms
-***************************************************************************/
-
-/* BICUBIC Interpolation functions */
-/*  More info: 
http://wiki.blender.org/index.php/User:Damiles#Bicubic_pixel_interpolation
-*/
-/* function assumes out to be zero'ed, only does RGBA */
-static float P(float k){
-       return (float)(1.0f/6.0f)*( pow( MAX2(k+2.0f,0) , 3.0f ) - 4.0f * pow( 
MAX2(k+1.0f,0) , 3.0f ) + 6.0f * pow( MAX2(k,0) , 3.0f ) - 4.0f * pow( 
MAX2(k-1.0f,0) , 3.0f));
-}
-
-static void bicubic_interpolation_px(ImBuf *in, float x, float y, float 
rgba_fp[4], char rgba[4])
-{
-       int i,j,n,m,x1,y1;
-       unsigned char *dataI;
-       float a,b,w,wx,wy[4], outR,outG,outB,outA,*dataF;
-       int do_rect=0, do_float=0;
-
-       if (in == NULL) return;
-       if (in->rect == NULL && in->rect_float == NULL) return;
-
-       if (in->rect_float)     do_float = 1;
-       else                            do_rect = 1;
-       
-       i= (int)floor(x);
-       j= (int)floor(y);
-       a= x - i;
-       b= y - j;
-
-       outR= 0.0f;
-       outG= 0.0f;
-       outB= 0.0f;
-       outA= 0.0f;
-       
-       /* avoid calling multiple times */
-       wy[0] = P(b-(-1));
-       wy[1] = P(b-  0);
-       wy[2] = P(b-  1);
-       wy[3] = P(b-  2);
-       
-       for(n= -1; n<= 2; n++){
-               x1= i+n;
-               if (x1>0 && x1 < in->x) {
-                       wx = P(n-a);
-                       for(m= -1; m<= 2; m++){
-                               y1= j+m;
-                               if (y1>0 && y1<in->y) {
-                                       /* normally we could do this */
-                                       /* w = P(n-a) * P(b-m); */
-                                       /* except that would call P() 16 times 
per pixel therefor pow() 64 times, better precalc these */
-                                       w = wx * wy[m+1];
-                                       
-                                       if (do_float) {
-                                               dataF= in->rect_float + in->x * 
y1 * 4 + 4*x1;
-                                               outR+= dataF[0] * w;
-                                               outG+= dataF[1] * w;
-                                               outB+= dataF[2] * w;
-                                               outA+= dataF[3] * w;
-                                       }
-                                       if (do_rect) {
-                                               dataI= (unsigned char*)in->rect 
+ in->x * y1 * 4 + 4*x1;
-                                               outR+= dataI[0] * w;
-                                               outG+= dataI[1] * w;
-                                               outB+= dataI[2] * w;
-                                               outA+= dataI[3] * w;
-                                       }
-                               }
-                       }
-               }
-       }
-       if (do_rect) {
-               rgba[0]= (int)outR;
-               rgba[1]= (int)outG;
-               rgba[2]= (int)outB;
-               rgba[3]= (int)outA;
-       }
-       if (do_float) {
-               rgba_fp[0]= outR;
-               rgba_fp[1]= outG;
-               rgba_fp[2]= outB;
-               rgba_fp[3]= outA;
-       }
-}
-
 /* Set the top-most face color that the screen space coord 'pt' touches (or 
return 0 if none touch) */
-static int project_paint_PickColor(ProjPaintState *ps, float pt[2], float 
*rgba_fp, char *rgba, int interp)
+static int project_paint_PickColor(ProjPaintState *ps, float pt[2], float 
*rgba_fp, unsigned char *rgba, int interp)
 {
        float w[3], uv[2];
        int side;
@@ -782,18 +692,18 @@
                
                if (ibuf->rect_float) {
                        if (rgba_fp) {
-                               bicubic_interpolation_px(ibuf, x, y, rgba_fp, 
NULL);
+                               bilinear_interpolation_color(ibuf, NULL, 
rgba_fp, x, y);
                        } else {
                                float rgba_tmp_fp[4];
-                               bicubic_interpolation_px(ibuf, x, y, 
rgba_tmp_fp, NULL);
+                               bilinear_interpolation_color(ibuf, NULL, 
rgba_tmp_fp, x, y);
                                IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba, rgba_tmp_fp);
                        }
                } else {
                        if (rgba) {
-                               bicubic_interpolation_px(ibuf, x, y, NULL, 
rgba);
+                               bilinear_interpolation_color(ibuf, rgba, NULL, 
x, y);
                        } else {
-                               char rgba_tmp[4];
-                               bicubic_interpolation_px(ibuf, x, y, NULL, 
rgba_tmp);
+                               unsigned char rgba_tmp[4];
+                               bilinear_interpolation_color(ibuf, rgba_tmp, 
NULL, x, y);
                                IMAPAINT_CHAR_RGBA_TO_FLOAT( rgba_fp,  
rgba_tmp);
                        }
                }
@@ -1329,7 +1239,7 @@
                        projPixel->pixel.f_pt = ((( float * ) ibuf->rect_float) 
+ (( x + y * ibuf->x ) * IMA_CHAR_PX_SIZE));
                        /* TODO float support for origColor */
                } else {
-                       projPixel->pixel.ch_pt = ((( char * ) ibuf->rect) + (( 
x + y * ibuf->x ) * IMA_CHAR_PX_SIZE));
+                       projPixel->pixel.ch_pt = ((( unsigned char * ) 
ibuf->rect) + (( x + y * ibuf->x ) * IMA_CHAR_PX_SIZE));
                        projPixel->origColor.uint = *projPixel->pixel.uint_pt;
                }
                
@@ -1379,7 +1289,8 @@
                                        x = x * ibuf_other->x - 0.5f;
                                        y = y * ibuf_other->y - 0.5f;
                                        
-                                       bicubic_interpolation_px(ibuf_other, x, 
y, NULL, ((ProjPixelClone *)projPixel)->clonepx.ch);
+                                       /* TODO - float buffer check */
+                                       
bilinear_interpolation_color(ibuf_other, ((ProjPixelClone 
*)projPixel)->clonepx.ch, NULL, x, y);
                                } else {
                                        ((ProjPixelClone 
*)projPixel)->clonepx.ch[3] = 0;
                                }
@@ -2197,14 +2108,8 @@
        
        ps->screenCoords = MEM_mallocN(sizeof(float) * ps->dm_totvert * 4, 
"ProjectPaint ScreenVerts");
        projScreenCo = ps->screenCoords;
-       
-       /* TODO - check cameras mode too */
-       
-       //if (G.vd->persp == V3D_ORTHO) {
-       //      ps->is_ortho = 1;
-       //}
-       
 
+       
        {       /* only use these for running 'get_view3d_viewplane' */
                rctf viewplane;
                float clipend;
@@ -2725,14 +2630,20 @@
        if (ibuf->rect_float) {
                float *rrgbf = ibuf->rect_float + (ibuf->x*y + x)*4;
 
-               if (set) IMAPAINT_FLOAT_RGB_COPY(rrgbf, rgb)
-               else IMAPAINT_FLOAT_RGB_COPY(rgb, rrgbf)
+               if (set) {
+                       IMAPAINT_FLOAT_RGB_COPY(rrgbf, rgb);
+               } else {
+                       IMAPAINT_FLOAT_RGB_COPY(rgb, rrgbf);
+               }
        }
        else {
                char *rrgb = (char*)ibuf->rect + (ibuf->x*y + x)*4;
 
-               if (set) IMAPAINT_FLOAT_RGB_TO_CHAR(rrgb, rgb)
-               else IMAPAINT_CHAR_RGB_TO_FLOAT(rgb, rrgb)
+               if (set) {
+                       IMAPAINT_FLOAT_RGB_TO_CHAR(rrgb, rgb)
+               } else {
+                       IMAPAINT_CHAR_RGB_TO_FLOAT(rgb, rrgb)
+               }
        }
 }
 
@@ -3062,8 +2973,9 @@
        }
 }
 
-static void partial_redraw_array_merge(ImagePaintPartialRedraw *pr, 
ImagePaintPartialRedraw *pr_other, int tot)
+static int partial_redraw_array_merge(ImagePaintPartialRedraw *pr, 
ImagePaintPartialRedraw *pr_other, int tot)
 {
+       int touch;
        while (tot--) {
                pr->x1 = MIN2(pr->x1, pr_other->x1);
                pr->y1 = MIN2(pr->y1, pr_other->y1);
@@ -3071,8 +2983,13 @@
                pr->x2 = MAX2(pr->x2, pr_other->x2);
                pr->y2 = MAX2(pr->y2, pr_other->y2);
                
+               if (pr->x2 != -2)
+                       touch = 1;
+               
                pr++; pr_other++;
        }
+       
+       return touch;
 }
 
 /* Loop over all images on this mesh and update any we have touched */
@@ -3168,16 +3085,32 @@
        return 0;
 }
 
-static void imapaint_paint_sub_stroke_project(
-                               ProjPaintState *ps,
-                               BrushPainter *painter,
-                               float prevmval[2],
-                               float mval[2],
-                               double time,
-                               float pressure,
-                               ProjPaintImage *projImages,
-                               int thread_index)
+
+/* Each thread gets one of these, also used as an argument to pass to 
project_paint_op */
+typedef struct ProjectHandle {
+       /* args */
+       ProjPaintState *ps;
+       float prevmval[2];
+       float mval[2];
+       
+       /* annoying but we need to have image bounds per thread, then merge 
into ps->projectPartialRedraws */
+       ProjPaintImage *projImages;     /* array of partial redraws */
+       
+       /* thread settings */
+       int thread_index;
+} ProjectHandle;
+
+/* run this for single and multithreaded painting */
+static void *do_projectpaint_thread(void *ph_v)
 {
+       /* First unpack args from the struct */
+       ProjPaintState *ps =                    ((ProjectHandle *)ph_v)->ps;
+       ProjPaintImage *projImages =    ((ProjectHandle *)ph_v)->projImages;
+       float *lastpos =                                ((ProjectHandle 
*)ph_v)->prevmval;
+       float *pos =                                    ((ProjectHandle 
*)ph_v)->mval;
+       int thread_index =                              ((ProjectHandle 
*)ph_v)->thread_index;
+       /* Done with args from ProjectHandle */
+
        LinkNode *node;
        ProjPixel *projPixel;
        
@@ -3186,7 +3119,7 @@
        ImagePaintPartialRedraw *last_partial_redraw_cell;
        
        float rgba[4], alpha, dist, dist_nosqrt;
-       char rgba_ub[4];
+       unsigned char rgba_ub[4];
        
        float brush_size_sqared;
        int bucket_index;
@@ -3197,7 +3130,7 @@
        
        /* for smear only */
        char rgba_smear[4];
-       float mval_ofs[2];
+       float pos_ofs[2];
        float co[2];
        LinkNode *smearPixels = NULL;
        LinkNode *smearPixels_float = NULL;
@@ -3205,8 +3138,8 @@
        
        
        if (ps->tool==PAINT_TOOL_SMEAR) {
-               mval_ofs[0] = mval[0] - prevmval[0];
-               mval_ofs[1] = mval[1] - prevmval[1];
+               pos_ofs[0] = pos[0] - lastpos[0];
+               pos_ofs[1] = pos[1] - lastpos[1];
                
                smearArena = BLI_memarena_new(1<<16);
        }
@@ -3216,16 +3149,10 @@
        
        /* printf("brush bounds %d %d %d %d\n", bucket_min[0], bucket_min[1], 
bucket_max[0], bucket_max[1]); */
        
-       /* If there is ever problems with getting the bounds for the brush, set 
the bounds to include all */
-       /*bucket_min[0] = 0; bucket_min[1] = 0; bucket_max[0] = ps->buckets_x; 
bucket_max[1] = ps->buckets_y;*/
-       
-       /* no clamping needed, dont use screen bounds, use vert bounds  */
-       
-       //for (bucket_y = bucket_min[1]; bucket_y < bucket_max[1]; bucket_y++) {
 #ifdef PROJ_DEBUG_PRINT_THREADS
        printf("THREAD %d %d %d\n", ps->thread_tot, thread_index,  
(ps->bucket_max[0] - ps->bucket_min[0]) * (ps->bucket_max[1] - 
ps->bucket_min[1]) );
 #endif
-       while (bucket_iter_next(ps, &bucket_index, bucket_bounds, mval)) {      
                        
+       while (bucket_iter_next(ps, &bucket_index, bucket_bounds, pos)) {       
                        
                
 #ifdef PROJ_DEBUG_PRINT_THREADS
                printf("\t%d %d\n", thread_index, bucket_index);
@@ -3245,8 +3172,8 @@
                        do {
                                projPixel = (ProjPixel *)node->link;
                                
-                               /*dist = Vec2Lenf(projPixel->projCo2D, mval);*/ 
/* correct but uses a sqrt */
-                               dist_nosqrt = 
Vec2Lenf_nosqrt(projPixel->projCo2D, mval);
+                               /*dist = Vec2Lenf(projPixel->projCo2D, pos);*/ 
/* correct but uses a sqrt */
+                               dist_nosqrt = 
Vec2Lenf_nosqrt(projPixel->projCo2D, pos);
                                
                                /*if (dist < s->brush->size) {*/ /* correct but 
uses a sqrt */
                                if (dist_nosqrt < brush_size_sqared) {
@@ -3289,7 +3216,7 @@
                                                }
                                                break;
                                        case PAINT_TOOL_SMEAR:
-                                               Vec2Subf(co, 
projPixel->projCo2D, mval_ofs);
+                                               Vec2Subf(co, 
projPixel->projCo2D, pos_ofs);
                                                if (project_paint_PickColor(ps, 
co, NULL, rgba_ub, 1)) { /* Note, no interpolation here, only needed for clone, 
nearest should be is OK??? - c */
                                                        
brush_sample_tex(ps->brush, projPixel->projCo2D, rgba);

@@ 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