[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17543] branches/projection-paint/source/ blender/src/imagepaint.c: Only paint in the view clipped area when view clip is enabled ( space defined by Alt+B).
Campbell Barton
ideasman42 at gmail.com
Sun Nov 23 18:06:35 CET 2008
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. @@
More information about the Bf-blender-cvs
mailing list