Revision: 17543
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17543
Author:   campbellbarton
Date:     2008-11-23 18:06:35 +0100 (Sun, 23 Nov 2008)

Log Message:
-----------
Only paint in the view clipped area when view clip is enabled (space defined by 
Alt+B).

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-23 
15:27:53 UTC (rev 17542)
+++ branches/projection-paint/source/blender/src/imagepaint.c   2008-11-23 
17:06:35 UTC (rev 17543)
@@ -88,6 +88,7 @@
 #include "BSE_node.h"
 #include "BSE_trans_types.h"
 #include "BSE_view.h"
+#include "BSE_drawview.h" /* view3d_test_clipping */
 
 #include "BDR_imagepaint.h"
 #include "BDR_vpaint.h"
@@ -251,6 +252,7 @@
        float viewMat[4][4];
        float viewDir[3];                       /* View vector, use for 
do_backfacecull and for ray casting with an ortho viewport  */
        float viewPos[3];                       /* View location in object 
relative 3D space, so can compare to verts  */
+       float clipsta, clipend;
        
        float screen_min[2];                    /* 2D bounds for mesh verts on 
the screen's plane (screenspace) */
        float screen_max[2]; 
@@ -278,14 +280,14 @@
 } PixelStore;
 
 typedef struct ProjPixel {
-       float projCo2D[2]; /* the floating point screen projection of this 
pixel */
+       float projCoSS[2]; /* the floating point screen projection of this 
pixel */
+       float mask;                     /* for various reasons we may want to 
mask out painting onto this pixel */
+       
        short x_px, y_px;
        
        PixelStore origColor;
        PixelPointer pixel;
        
-       float mask;                     /* for various reasons we may want to 
mask out painting onto this pixel */
-       
        short image_index; /* if anyone wants to paint onto more then 32768 
images they can bite me */
        unsigned char bb_cell_index;
 } ProjPixel;
@@ -482,25 +484,25 @@
 }
 
 /* fast projection bucket array lookup, use the safe version for bound 
checking  */
-static int project_bucket_offset(ProjPaintState *ps, float projCo2D[2])
+static int project_bucket_offset(ProjPaintState *ps, float projCoSS[2])
 {
        /* If we were not dealing with screenspace 2D coords we could simple 
do...
         * ps->bucketRect[x + (y*ps->buckets_y)] */
        
        /* please explain?
-        * projCo2D[0] - ps->screen_min[0]      : zero origin
+        * projCoSS[0] - ps->screen_min[0]      : zero origin
         * ... / ps->screen_width                               : range from 
0.0 to 1.0
         * ... * ps->buckets_x          : use as a bucket index
         *
         * Second multiplication does similar but for vertical offset
         */
-       return  (       (int)(( (projCo2D[0] - ps->screen_min[0]) / 
ps->screen_width)  * ps->buckets_x)) + 
-               (       (       (int)(( (projCo2D[1] - ps->screen_min[1])  / 
ps->screen_height) * ps->buckets_y)) * ps->buckets_x );
+       return  (       (int)(( (projCoSS[0] - ps->screen_min[0]) / 
ps->screen_width)  * ps->buckets_x)) + 
+               (       (       (int)(( (projCoSS[1] - ps->screen_min[1])  / 
ps->screen_height) * ps->buckets_y)) * ps->buckets_x );
 }
 
-static int project_bucket_offset_safe(ProjPaintState *ps, float projCo2D[2])
+static int project_bucket_offset_safe(ProjPaintState *ps, float projCoSS[2])
 {
-       int bucket_index = project_bucket_offset(ps, projCo2D);
+       int bucket_index = project_bucket_offset(ps, projCoSS);
        
        if (bucket_index < 0 || bucket_index >= ps->buckets_x*ps->buckets_y) {  
                return -1;
@@ -530,20 +532,20 @@
 #define SIDE_OF_LINE(pa,pb,pp) 
((pa[0]-pp[0])*(pb[1]-pp[1]))-((pb[0]-pp[0])*(pa[1]-pp[1]))
 static void BarycentricWeights2f(float v1[2], float v2[2], float v3[2], float 
pt[2], float w[3]) {
        float wtot_inv, wtot = AreaF2Dfl(v1, v2, v3);
-       if (wtot > 0.0) {
+       if (wtot > 0.0f) {
                wtot_inv = 1.0f / wtot;
                w[0] = AreaF2Dfl(v2, v3, pt);
                w[1] = AreaF2Dfl(v3, v1, pt);
                w[2] = AreaF2Dfl(v1, v2, pt);
                
                /* negate weights when 'pt' is on the outer side of the the 
triangles edge */
-               if ((SIDE_OF_LINE(v2,v3, pt)>0.0) != (SIDE_OF_LINE(v2,v3, 
v1)>0.0))     w[0]*= -wtot_inv;
+               if ((SIDE_OF_LINE(v2,v3, pt)>0.0f) != (SIDE_OF_LINE(v2,v3, 
v1)>0.0f))   w[0]*= -wtot_inv;
                else                                                            
                                                                w[0]*=  
wtot_inv;
 
-               if ((SIDE_OF_LINE(v3,v1, pt)>0.0) != (SIDE_OF_LINE(v3,v1, 
v2)>0.0))     w[1]*= -wtot_inv;
+               if ((SIDE_OF_LINE(v3,v1, pt)>0.0f) != (SIDE_OF_LINE(v3,v1, 
v2)>0.0f))   w[1]*= -wtot_inv;
                else                                                            
                                                                w[1]*=  
wtot_inv;
 
-               if ((SIDE_OF_LINE(v1,v2, pt)>0.0) != (SIDE_OF_LINE(v1,v2, 
v3)>0.0))     w[2]*= -wtot_inv;
+               if ((SIDE_OF_LINE(v1,v2, pt)>0.0f) != (SIDE_OF_LINE(v1,v2, 
v3)>0.0f))   w[2]*= -wtot_inv;
                else                                                            
                                                                w[2]*=  
wtot_inv;
        } else {
                w[0] = w[1] = w[2] = 1.0f/3.0f; /* dummy values for zero area 
face */
@@ -764,7 +766,7 @@
  * -1  : no occlusion but 2D intersection is true (avoid testing the other 
half of a quad)
  *  1  : occluded */
 
-static int project_paint_PointOcclude(float pt[3], float v1[3], float v2[3], 
float v3[3])
+static int project_paint_occlude_ptv(float pt[3], float v1[3], float v2[3], 
float v3[3])
 {
        /* if all are behind us, return false */
        if(v1[2] > pt[2] && v2[2] > pt[2] && v3[2] > pt[2])
@@ -774,10 +776,10 @@
        if ( !IsectPT2Df(pt, v1, v2, v3) )
                return 0; /* we know there is  */
        
+
        /* From here on we know there IS an intersection */
-       
        /* if ALL of the verts are infront of us then we know it intersects ? */
-       if(     v1[2] < pt[2] && v2[2] < pt[2] && v3[2] < pt[2]) {
+       if(v1[2] < pt[2] && v2[2] < pt[2] && v3[2] < pt[2]) {
                return 1;
        } else {
                float w[3];
@@ -790,6 +792,34 @@
 }
 
 
+static int project_paint_occlude_ptv_clip(ProjPaintState *ps, MFace *mf, float 
pt[3], float v1[3], float v2[3], float v3[3], int side)
+{
+       float w[3], wco[3];
+       
+       /* if all are behind us, return false */
+       if(v1[2] > pt[2] && v2[2] > pt[2] && v3[2] > pt[2])
+               return 0;
+               
+       /* do a 2D point in try intersection */
+       if ( !IsectPT2Df(pt, v1, v2, v3) )
+               return 0; /* we know there is  */
+       
+       /* we intersect? - find the exact depth at the point of intersection */
+       if (tri_depth_2d(v1,v2,v3,pt,w) > pt[2])
+               return -1;
+       
+       if (side)       VecWeightf(wco, ps->dm_mvert[ (*(&mf->v1)) ].co, 
ps->dm_mvert[ (*(&mf->v1 + 2)) ].co, ps->dm_mvert[ (*(&mf->v1 + 3)) ].co, w);
+       else            VecWeightf(wco, ps->dm_mvert[ (*(&mf->v1)) ].co, 
ps->dm_mvert[ (*(&mf->v1 + 1)) ].co, ps->dm_mvert[ (*(&mf->v1 + 2)) ].co, w);
+       
+       Mat4MulVecfl(ps->ob->obmat, wco);
+       if(!view3d_test_clipping(G.vd, wco)) {
+               return 1;
+       }
+       
+       return -1;
+}
+
+
 /* Check if a screenspace location is occluded by any other faces
  * check, pixelScreenCo must be in screenspace, its Z-Depth only needs to be 
used for comparison
  * and dosn't need to be correct in relation to X and Y coords (this is the 
case in perspective view) */
@@ -802,37 +832,47 @@
        /* we could return 0 for 1 face buckets, as long as this function 
assumes
         * that the point its testing is only every originated from an existing 
face */
        
-       while (bucketFace) {
-               face_index = (int)bucketFace->link;
-               
-               if (orig_face != face_index) {
+       if(G.vd->flag & V3D_CLIPPING) {
+               while (bucketFace) {
+                       face_index = (int)bucketFace->link;
                        
-                       mf = ps->dm_mface + face_index;
-                       
-                       isect_ret = project_paint_PointOcclude(
-                                       pixelScreenCo,
-                                       ps->screenCoords[mf->v1],
-                                       ps->screenCoords[mf->v2],
-                                       ps->screenCoords[mf->v3]);
-                       
-                       /* Note, if isect_ret==-1 then we dont want to test the 
other side of the quad */
-                       if (isect_ret==0 && mf->v4) {
-                               isect_ret = project_paint_PointOcclude(
-                                               pixelScreenCo,
-                                               ps->screenCoords[mf->v1],
-                                               ps->screenCoords[mf->v3],
-                                               ps->screenCoords[mf->v4]);
+                       if (orig_face != face_index) {
+                               mf = ps->dm_mface + face_index;
+                                       isect_ret = 
project_paint_occlude_ptv_clip(ps, mf, pixelScreenCo, ps->screenCoords[mf->v1], 
ps->screenCoords[mf->v2], ps->screenCoords[mf->v3], 0);
+                                       
+                                       /* Note, if isect_ret==-1 then we dont 
want to test the other side of the quad */
+                                       if (isect_ret==0 && mf->v4) {
+                                               isect_ret = 
project_paint_occlude_ptv_clip(ps, mf, pixelScreenCo, ps->screenCoords[mf->v1], 
ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], 1);
+                                       }
+                               if (isect_ret==1) {
+                                       /* TODO - we may want to cache the 
first hit,
+                                        * it is not possible to swap the face 
order in the list anymore */
+                                       return 1; 
+                               }
                        }
+                       bucketFace = bucketFace->next;
+               }
+       } else {
+               while (bucketFace) {
+                       face_index = (int)bucketFace->link;
                        
-                       if (isect_ret==1) {
-                               /* TODO - we may want to cache the first hit,
-                                * it is not possible to swap the face order in 
the list anymore */
-                               return 1; 
+                       if (orig_face != face_index) {
+                               mf = ps->dm_mface + face_index;
+                                       isect_ret = 
project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], 
ps->screenCoords[mf->v2], ps->screenCoords[mf->v3]);
+                                       
+                                       /* Note, if isect_ret==-1 then we dont 
want to test the other side of the quad */
+                                       if (isect_ret==0 && mf->v4) {
+                                               isect_ret = 
project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], 
ps->screenCoords[mf->v3], ps->screenCoords[mf->v4]);
+                                       }
+                               if (isect_ret==1) {
+                                       /* TODO - we may want to cache the 
first hit,
+                                        * it is not possible to swap the face 
order in the list anymore */
+                                       return 1; 
+                               }
                        }
+                       bucketFace = bucketFace->next;
                }
-               bucketFace = bucketFace->next;
        }
-       
        return 0;
 }
 
@@ -1250,8 +1290,8 @@
        
        // if( pixelScreenCo[3] > 0.001 ) { ??? TODO
        /* screen space, not clamped */
-       pixelScreenCo[0] = 
(float)(curarea->winx/2.0)+(curarea->winx/2.0)*pixelScreenCo[0]/pixelScreenCo[3];
    
-       pixelScreenCo[1] = 
(float)(curarea->winy/2.0)+(curarea->winy/2.0)*pixelScreenCo[1]/pixelScreenCo[3];
+       pixelScreenCo[0] = 
(float)(curarea->winx/2.0f)+(curarea->winx/2.0f)*pixelScreenCo[0]/pixelScreenCo[3];
  
+       pixelScreenCo[1] = 
(float)(curarea->winy/2.0f)+(curarea->winy/2.0f)*pixelScreenCo[1]/pixelScreenCo[3];
        pixelScreenCo[2] = pixelScreenCo[2]/pixelScreenCo[3]; /* Use the depth 
for bucket point occlusion */
 }
 #endif
@@ -1372,7 +1412,7 @@
        }
        
        /* screenspace unclamped, we could keep its z and w values but dont 
need them at the moment */
-       VECCOPY2D(projPixel->projCo2D, pixelScreenCo);
+       VECCOPY2D(projPixel->projCoSS, pixelScreenCo);
        
        projPixel->x_px = x;
        projPixel->y_px = y;
@@ -1430,7 +1470,7 @@
                        
                        /* 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->clone_offset);
+                       Vec2Subf(co, projPixel->projCoSS, ps->clone_offset);
                        
                        /* 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(...) */
@@ -2094,7 +2134,7 @@
        
        float *vCo[4]; /* vertex screenspace coords */
        
-       float w[3];
+       float w[3], wco[3];
        

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