[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17526] branches/projection-paint/source/ blender: * added option "Normal", same as the vpaint option, gives more natural looking brush strokes.
Campbell Barton
ideasman42 at gmail.com
Fri Nov 21 04:09:51 CET 2008
Revision: 17526
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17526
Author: campbellbarton
Date: 2008-11-21 04:09:48 +0100 (Fri, 21 Nov 2008)
Log Message:
-----------
* added option "Normal", same as the vpaint option, gives more natural looking brush strokes.
* faces that were ignored were also not taken into acount when checking UV seams - causng bleed not to work properly in some cases.
* commented early pixel filling loop exit that fails in some cases.
Modified Paths:
--------------
branches/projection-paint/source/blender/makesdna/DNA_scene_types.h
branches/projection-paint/source/blender/src/buttons_editing.c
branches/projection-paint/source/blender/src/imagepaint.c
Modified: branches/projection-paint/source/blender/makesdna/DNA_scene_types.h
===================================================================
--- branches/projection-paint/source/blender/makesdna/DNA_scene_types.h 2008-11-21 02:23:46 UTC (rev 17525)
+++ branches/projection-paint/source/blender/makesdna/DNA_scene_types.h 2008-11-21 03:09:48 UTC (rev 17526)
@@ -803,10 +803,11 @@
#define IMAGEPAINT_DRAW_TOOL_DRAWING 4
/* projection painting only */
-#define IMAGEPAINT_PROJECT_XRAY 8
-#define IMAGEPAINT_PROJECT_BACKFACE 16
+#define IMAGEPAINT_PROJECT_XRAY 8
+#define IMAGEPAINT_PROJECT_BACKFACE 16
#define IMAGEPAINT_PROJECT_IGNORE_SEAMS 32
#define IMAGEPAINT_PROJECT_CLONE_LAYER 64
+#define IMAGEPAINT_PROJECT_FLAT 128
/* toolsettings->uvcalc_flag */
#define UVCALC_FILLHOLES 1
Modified: branches/projection-paint/source/blender/src/buttons_editing.c
===================================================================
--- branches/projection-paint/source/blender/src/buttons_editing.c 2008-11-21 02:23:46 UTC (rev 17525)
+++ branches/projection-paint/source/blender/src/buttons_editing.c 2008-11-21 03:09:48 UTC (rev 17526)
@@ -6373,7 +6373,9 @@
/* Projection Painting */
uiBlockBeginAlign(block);
uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_XRAY, B_NOP, "Occlude", xco+10,yco-70,butw,19, &settings->imapaint.flag, 0, 0, 0, 0, "Only paint onto the faces directly under the brush (slower)");
- uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_BACKFACE, B_NOP, "Backface Cull", xco+10,yco-90,butw,19, &settings->imapaint.flag, 0, 0, 0, 0, "Ignore faces pointing away from the view (faster)");
+ uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_BACKFACE, B_NOP, "Cull", xco+10,yco-90,butw/2,19, &settings->imapaint.flag, 0, 0, 0, 0, "Ignore faces pointing away from the view (faster)");
+ uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_FLAT, B_NOP, "Normal", xco+10+butw/2,yco-90,butw/2,19, &settings->imapaint.flag, 0, 0, 0, 0, "Ignore faces pointing away from the view (faster)");
+
uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_IGNORE_SEAMS, B_NOP, "Bleed", xco+10,yco-110,butw/2,19, &settings->imapaint.flag, 0, 0, 0, 0, "Extend paint beyond the faces UVs to reduce seams (in pixels, slower)");
uiDefButF(block, NUM, B_NOP, "", xco+10 + (butw/2),yco-110,butw/2,19, &settings->imapaint.seam_bleed, 2.0, 8.0, 0, 0, "Extend paint beyond the faces UVs to reduce seams (in pixels, slower)");
uiBlockEndAlign(block);
Modified: branches/projection-paint/source/blender/src/imagepaint.c
===================================================================
--- branches/projection-paint/source/blender/src/imagepaint.c 2008-11-21 02:23:46 UTC (rev 17525)
+++ branches/projection-paint/source/blender/src/imagepaint.c 2008-11-21 03:09:48 UTC (rev 17526)
@@ -178,6 +178,9 @@
#define PROJ_BUCKET_INIT 1<<0
// #define PROJ_BUCKET_CLONE_INIT 1<<1
+/* vert flags */
+#define PROJ_VERT_CULL 1
+
/* only for readability */
#define PROJ_BUCKET_LEFT 0
#define PROJ_BUCKET_RIGHT 1
@@ -221,6 +224,7 @@
char *faceSeamFlags; /* store info about faces, if they are initialized etc*/
float (*faceSeamUVs)[4][2]; /* expanded UVs for faces to use as seams */
LinkNode **vertFaces; /* Only needed for when seam_bleed_px is enabled, use to find UV seams */
+ char *vertFlags; /* store options per vert, now only store if the vert is pointing away from the view */
#endif
int buckets_x; /* The size of the bucket grid, the grid span's screen_min/screen_max so you can paint outsize the screen or with 2 brushes at once */
int buckets_y;
@@ -235,6 +239,7 @@
short do_occlude; /* Use raytraced occlusion? - ortherwise will paint right through to the back*/
short do_backfacecull; /* ignore faces with normals pointing away, skips a lot of raycasts if your normals are correctly flipped */
short is_ortho;
+ short do_mask_normal; /* mask out pixels based on their normals */
#ifndef PROJ_DEBUG_NOSEAMBLEED
float seam_bleed_px;
#endif
@@ -245,6 +250,7 @@
float projectMat[4][4]; /* Projection matrix, use for getting screen coords */
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 screen_min[2]; /* 2D bounds for mesh verts on the screen's plane (screenspace) */
float screen_max[2];
@@ -278,8 +284,10 @@
PixelStore origColor;
PixelPointer pixel;
- short image_index; /* if anyone wants to paint onto more then 32000 images they can bite me */
- short bb_cell_index;
+ 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;
typedef struct ProjPixelClone {
@@ -583,6 +591,19 @@
}
}
+static VecWeightf(float p[3], float v1[3], float v2[3], float v3[3], float w[3])
+{
+ p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2];
+ p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2];
+ p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2];
+}
+
+static Vec2Weightf(float p[3], float v1[3], float v2[3], float v3[3], float w[3])
+{
+ p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2];
+ p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2];
+}
+
static float tri_depth_2d(float v1[3], float v2[3], float v3[3], float pt[2], float w[3])
{
BarycentricWeightsSimple2f(v1,v2,v3,pt,w);
@@ -666,12 +687,10 @@
tf = ps->dm_mtface + face_index;
- if (side==0) {
- uv[0] = tf->uv[0][0]*w[0] + tf->uv[1][0]*w[1] + tf->uv[2][0]*w[2];
- uv[1] = tf->uv[0][1]*w[0] + tf->uv[1][1]*w[1] + tf->uv[2][1]*w[2];
+ if (side == 0) {
+ Vec2Weightf(uv, tf->uv[0], tf->uv[1], tf->uv[2], w);
} else { /* QUAD */
- uv[0] = tf->uv[0][0]*w[0] + tf->uv[2][0]*w[1] + tf->uv[3][0]*w[2];
- uv[1] = tf->uv[0][1]*w[0] + tf->uv[2][1]*w[1] + tf->uv[3][1]*w[2];
+ Vec2Weightf(uv, tf->uv[0], tf->uv[2], tf->uv[3], w);
}
ibuf = BKE_image_get_ibuf((Image *)tf->tpage, NULL); /* TODO - this may be slow */
@@ -774,9 +793,8 @@
/* 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) */
-static int project_bucket_point_occluded(ProjPaintState *ps, int bucket_index, int orig_face, float pixelScreenCo[4])
+static int project_bucket_point_occluded(ProjPaintState *ps, LinkNode *bucketFace, int orig_face, float pixelScreenCo[4])
{
- LinkNode *node = ps->bucketFaces[bucket_index];
MFace *mf;
int face_index;
int isect_ret;
@@ -784,8 +802,8 @@
/* 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 (node) {
- face_index = (int)node->link;
+ while (bucketFace) {
+ face_index = (int)bucketFace->link;
if (orig_face != face_index) {
@@ -812,7 +830,7 @@
return 1;
}
}
- node = node->next;
+ bucketFace = bucketFace->next;
}
return 0;
@@ -1151,20 +1169,19 @@
float w[3])
{
BarycentricWeightsSimple2f(uv1co,uv2co,uv3co,uv,w);
- pixelScreenCo[0] = v1co[0]*w[0] + v2co[0]*w[1] + v3co[0]*w[2];
- pixelScreenCo[1] = v1co[1]*w[0] + v2co[1]*w[1] + v3co[1]*w[2];
- pixelScreenCo[2] = v1co[2]*w[0] + v2co[2]*w[1] + v3co[2]*w[2];
+ VecWeightf(pixelScreenCo, v1co, v2co, v3co, w);
}
/* same as screen_px_from_ortho except we need to take into account
* the perspective W coord for each vert */
static void screen_px_from_persp(
ProjPaintState *ps, float uv[2],
- float v1co[3], float v2co[3], float v3co[3], /* Worldspace coords */
+ float v1co[3], float v2co[3], float v3co[3], /* screenspace coords */
float uv1co[2], float uv2co[2], float uv3co[2],
float pixelScreenCo[4],
float w[3])
{
+
float wtot_inv, wtot;
BarycentricWeightsSimple2f(uv1co,uv2co,uv3co,uv,w);
@@ -1185,149 +1202,230 @@
}
/* done re-weighting */
+ VecWeightf(pixelScreenCo, v1co, v2co, v3co, w);
+}
+
+#if 0
+static void screen_px_from_persp(
+ ProjPaintState *ps, float uv[2],
+ float v1co[3], float v2co[3], float v3co[3], /* Worldspace coords */
+ float uv1co[2], float uv2co[2], float uv3co[2],
+ float pixelScreenCo[4],
+ float w[3])
+{
+ BarycentricWeightsSimple2f(uv1co,uv2co,uv3co,uv,w);
pixelScreenCo[0] = v1co[0]*w[0] + v2co[0]*w[1] + v3co[0]*w[2];
pixelScreenCo[1] = v1co[1]*w[0] + v2co[1]*w[1] + v3co[1]*w[2];
- pixelScreenCo[2] = v1co[2]*w[0] + v2co[2]*w[1] + v3co[2]*w[2];
+ pixelScreenCo[2] = v1co[2]*w[0] + v2co[2]*w[1] + v3co[2]*w[2];
+ pixelScreenCo[3] = 1.0;
+
+ Mat4MulVec4fl(ps->projectMat, pixelScreenCo);
+
+ // 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[2] = pixelScreenCo[2]/pixelScreenCo[3]; /* Use the depth for bucket point occlusion */
}
+#endif
/* Only run this function once for new ProjPixelClone's */
#define IMA_CHAR_PX_SIZE 4
-/* run this function when we know a bucket's, face's pixel can be initialized,
- * adding to the LinkList 'ps->bucketRect' */
-static void project_paint_uvpixel_init(ProjPaintState *ps, int thread_index, ImBuf *ibuf, short x, short y, int bucket_index, int face_index, int image_index, float pixelScreenCo[4], int side, float w[3])
-{
- ProjPixel *projPixel;
- short size;
-
- // printf("adding px (%d %d), (%f %f)\n", x,y,uv[0],uv[1]);
-
-
- /* Use screen_min to make (0,0) the bottom left of the bounds
- * Then this can be used to index the bucket array */
-
- /* Is this UV visible from the view? - raytrace */
- /* project_paint_PickFace is less complex, use for testing */
- //if (project_paint_PickFace(ps, pixelScreenCo, w, &side) == face_index) {
- if (ps->do_occlude==0 || !project_bucket_point_occluded(ps, bucket_index, face_index, pixelScreenCo)) {
+
+/* run this outside project_paint_uvpixel_init since pixels with mask 0 dont need init */
+float project_paint_uvpixel_mask(
+ ProjPaintState *ps,
+ int face_index,
+ int side,
+ float w[3]
+) {
+ float mask;
+ /* calculate mask */
+ if (ps->do_mask_normal) {
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list