From 2b7098820dc4e385ddc56c78d0e87a55483526ce Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 6 Dec 2008 13:42:55 +0000 Subject: [PATCH] * Patch from Michael Fox to set the normal angle (was fixed at 80 before) * Fixed another face clipping bug (some artifacts still when using screen aligned faces) * Removed Soften and Warp buttons on the panit panel since they are not used for projection painting * added do_versions to initialize bleed and normal values --- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenloader/intern/readfile.c | 11 ++++ source/blender/makesdna/DNA_scene_types.h | 9 ++- source/blender/src/buttons_editing.c | 25 +++---- source/blender/src/imagepaint.c | 72 ++++++++++++--------- 5 files changed, 69 insertions(+), 50 deletions(-) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index f392d57521c..a6334e665d1 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -41,7 +41,7 @@ struct ListBase; struct MemFile; #define BLENDER_VERSION 248 -#define BLENDER_SUBVERSION 1 +#define BLENDER_SUBVERSION 2 #define BLENDER_MINVERSION 245 #define BLENDER_MINSUBVERSION 15 diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 423d050c862..91170563c11 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8007,6 +8007,17 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 2)) { + Scene *sce; + + /* Note, these will need to be added for painting */ + for (sce= main->scene.first; sce; sce= sce->id.next) { + sce->toolsettings->imapaint.seam_bleed = 2; + sce->toolsettings->imapaint.normal_angle = 80; + } + } + + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 9851a851e58..23f4b6a728c 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -347,8 +347,8 @@ typedef struct ImagePaintSettings { short flag, tool; /* for projection painting only - todo - use flags */ - float seam_bleed; - int clone_layer, pad; + char seam_bleed,normal_angle; + short clone_layer; } ImagePaintSettings; typedef struct ParticleBrushData { @@ -805,9 +805,8 @@ typedef struct Scene { /* projection painting only */ #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 +#define IMAGEPAINT_PROJECT_CLONE_LAYER 32 +#define IMAGEPAINT_PROJECT_FLAT 64 /* toolsettings->uvcalc_flag */ #define UVCALC_FILLHOLES 1 diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 8d989538749..5000c798325 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -6341,10 +6341,10 @@ static void editing_panel_mesh_paint(void) //uiDefButS(block, ROW, B_BRUSHCHANGE, "Soften", 108 ,yco,106,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_SOFTEN, 0, 0, "Soften brush"); //uiDefButS(block, ROW, B_BRUSHCHANGE, "Smear", 214,yco,106,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_SMEAR, 0, 0, "Smear brush"); - uiDefButS(block, ROW, B_SIMABRUSHCHANGE, "Draw", 0 ,yco,80,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_DRAW, 0, 0, "Draw brush"); - uiDefButS(block, ROW, B_SIMABRUSHCHANGE, "Soften", 80 ,yco,80,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_SOFTEN, 0, 0, "Soften brush"); - uiDefButS(block, ROW, B_SIMABRUSHCHANGE, "Smear", 160,yco,80,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_SMEAR, 0, 0, "Smear brush"); - uiDefButS(block, ROW, B_SIMABRUSHCHANGE, "Clone", 240,yco,80,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_CLONE, 0, 0, "Clone brush, use RMB to drag source image"); + uiDefButS(block, ROW, B_SIMABRUSHCHANGE, "Draw", 0 ,yco,108,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_DRAW, 0, 0, "Draw brush"); + //uiDefButS(block, ROW, B_SIMABRUSHCHANGE, "Soften", 80 ,yco,80,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_SOFTEN, 0, 0, "Soften brush"); + uiDefButS(block, ROW, B_SIMABRUSHCHANGE, "Smear", 108 ,yco,106,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_SMEAR, 0, 0, "Smear brush"); + uiDefButS(block, ROW, B_SIMABRUSHCHANGE, "Clone", 214,yco,106,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_CLONE, 0, 0, "Clone brush, use RMB to drag source image"); uiBlockEndAlign(block); yco -= 30; @@ -6361,23 +6361,24 @@ static void editing_panel_mesh_paint(void) uiDefButS(block, MENU, B_NOP, "Mix %x0|Add %x1|Subtract %x2|Multiply %x3|Lighten %x4|Darken %x5|Erase Alpha %x6|Add Alpha %x7", xco+10,yco,butw,19, &brush->blend, 0, 0, 0, 0, "Blending method for applying brushes"); - uiDefButBitS(block, TOG|BIT, BRUSH_TORUS, B_BRUSHCHANGE, "Wrap", xco+10,yco-25,butw,19, &brush->flag, 0, 0, 0, 0, "Enables torus wrapping"); + // uiDefButBitS(block, TOG|BIT, BRUSH_TORUS, B_BRUSHCHANGE, "Wrap", xco+10,yco-25,butw,19, &brush->flag, 0, 0, 0, 0, "Enables torus wrapping"); uiBlockBeginAlign(block); - uiDefButBitS(block, TOG|BIT, BRUSH_AIRBRUSH, B_BRUSHCHANGE, "Airbrush", xco+10,yco-50,butw,19, &brush->flag, 0, 0, 0, 0, "Keep applying paint effect while holding mouse (spray)"); - uiDefButF(block, NUM, B_NOP, "Rate ", xco+10,yco-70,butw,19, &brush->rate, 0.01, 1.0, 0, 0, "Number of paints per second for Airbrush"); + uiDefButBitS(block, TOG|BIT, BRUSH_AIRBRUSH, B_BRUSHCHANGE, "Airbrush", xco+10,yco-25,butw,19, &brush->flag, 0, 0, 0, 0, "Keep applying paint effect while holding mouse (spray)"); + uiDefButF(block, NUM, B_NOP, "Rate ", xco+10,yco-45,butw,19, &brush->rate, 0.01, 1.0, 0, 0, "Number of paints per second for Airbrush"); uiBlockEndAlign(block); yco -= 25; /* 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, "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, "Paint most on faces pointing towards teh view"); + uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_XRAY, B_NOP, "Occlude", xco+10,yco-45,butw/2,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, "Cull", xco+10+butw/2,yco-45,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)"); + uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_FLAT, B_NOP, "Normal", xco+10,yco-65,butw/2,19, &settings->imapaint.flag, 0, 0, 0, 0, "Paint most on faces pointing towards the view"); + uiDefButC(block, NUM, B_NOP, "", xco+10 +(butw/2),yco-65,butw/2,19, &settings->imapaint.normal_angle, 10.0, 90.0, 0, 0, "Paint most on faces pointing towards the view acording to this angle)"); + + uiDefButC(block, NUM, B_NOP, "Bleed: ", xco+10,yco-85,butw,19, &settings->imapaint.seam_bleed, 0.0, 8.0, 0, 0, "Extend paint beyond the faces UVs to reduce seams (in pixels, slower)"); uiBlockEndAlign(block); uiBlockBeginAlign(block); diff --git a/source/blender/src/imagepaint.c b/source/blender/src/imagepaint.c index 301cb95c294..1edca8892c0 100644 --- a/source/blender/src/imagepaint.c +++ b/source/blender/src/imagepaint.c @@ -159,6 +159,7 @@ typedef struct ImagePaintPartialRedraw { //#define PROJ_DEBUG_PAINT 1 //#define PROJ_DEBUG_NOSEAMBLEED 1 +//#define PROJ_DEBUG_PRINT_CLIP 1 #define PROJ_DEBUG_WINCLIP 1 /* projectFaceSeamFlags options */ @@ -186,7 +187,6 @@ typedef struct ImagePaintPartialRedraw { /* vert flags */ #define PROJ_VERT_CULL 1 -/* M_PI_2 is 90d, we want 80 though */ #define PI_80_DEG ((M_PI_2 / 9) * 8) /* This is mainly a convenience struct used so we can keep an array of images we use @@ -245,6 +245,8 @@ typedef struct ProjPaintState { 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 do_mask_normal; /* mask out pixels based on their normals */ + float normal_angle; /* what angle to mask at*/ + short is_ortho; short is_airbrush; /* only to avoid using (ps.brush->flag & BRUSH_AIRBRUSH) */ short is_texbrush; /* only to avoid running */ @@ -1293,7 +1295,7 @@ float project_paint_uvpixel_mask( const int side, const float w[3]) { - float mask; + float mask, mask_angle; /* calculate mask */ if (ps->do_mask_normal) { @@ -1340,22 +1342,28 @@ float project_paint_uvpixel_mask( angle = NormalizedVecAngle2(viewDirPersp, no); } - if (angle >= PI_80_DEG) { + /*if (angle >= (M_PI_2 / 90) * ps->normal_angle) { return 0.0f; } - else { + else {*/ #if 0 mask = 1.0f - (angle / PI_80_DEG); /* map angle to 1.0-facing us, 0.0 right angles to the view direction */ #endif /* trickier method that clips the normal so its more useful */ - mask = (angle / PI_80_DEG); /* map angle to 1.0-facing us, 0.0 right angles to the view direction */ + /* M_PI_2 is 90d, we want 80 though */ + mask_angle = ((M_PI_2 / 90) * ps->normal_angle); + + /*printf("normal_angle : %f \n" ,ps->normal_angle); + printf("mask_angle : %f \n" ,mask_angle);*/ + + mask = (angle / mask_angle); /* map angle to 1.0-facing us, 0.0 right angles to the view direction */ mask = (1.0f - (mask * mask * mask)) * 1.4f; if (mask > 1.0f) { mask = 1.0f; } + /*}*/ } - } else { mask = 1.0f; } @@ -1548,7 +1556,7 @@ static int line_clip_rect2f( } /* top/bottom */ - if (line_isect_y(l1, l2, rect->ymin, &isect) && (isect > rect->xmin) && (isect < rect->xmax)) { + if (line_isect_y(l1, l2, rect->ymin, &isect) && (isect >= rect->xmin) && (isect <= rect->xmax)) { if (l1[1] < l2[1]) { /* line 1 is outside */ l1_clip[0] = isect; l1_clip[1] = rect->ymin; @@ -1560,7 +1568,7 @@ static int line_clip_rect2f( ok2 = 2; } } - if (line_isect_y(l1, l2, rect->ymax, &isect) && (isect > rect->xmin) && (isect < rect->xmax)) { + if (line_isect_y(l1, l2, rect->ymax, &isect) && (isect >= rect->xmin) && (isect <= rect->xmax)) { if (l1[1] > l2[1]) { /* line 1 is outside */ l1_clip[0] = isect; l1_clip[1] = rect->ymax; @@ -1574,7 +1582,7 @@ static int line_clip_rect2f( } /* left/right */ - if (line_isect_x(l1, l2, rect->xmin, &isect) && (isect > rect->ymin) && (isect < rect->ymax)) { + if (line_isect_x(l1, l2, rect->xmin, &isect) && (isect >= rect->ymin) && (isect <= rect->ymax)) { if (l1[0] < l2[0]) { /* line 1 is outside */ l1_clip[0] = rect->xmin; l1_clip[1] = isect; @@ -1586,7 +1594,7 @@ static int line_clip_rect2f( ok2 = 2; } } - if (line_isect_x(l1, l2, rect->xmax, &isect) && (isect > rect->ymin) && (isect < rect->ymax)) { + if (line_isect_x(l1, l2, rect->xmax, &isect) && (isect >= rect->ymin) && (isect <= rect->ymax)) { if (l1[0] > l2[0]) { /* line 1 is outside */ l1_clip[0] = rect->xmax; l1_clip[1] = isect; @@ -1963,7 +1971,8 @@ static void project_bucket_clip_face( float cent[2] = {0.0f, 0.0f}; /*float up[2] = {0.0f, 1.0f};*/ float tmp_f; - int i, unsorted; + int i; + short unsorted, doubles; (*tot) = 0; @@ -2059,24 +2068,29 @@ static void project_bucket_clip_face( } /* remove doubles */ - /* first/last check */ if (fabs(isectVCosSS[0][0]-isectVCosSS[(*tot)-1][0]) < ISECT_TOLERANCE && fabs(isectVCosSS[0][1]-isectVCosSS[(*tot)-1][1]) < ISECT_TOLERANCE) { (*tot)--; } - unsorted = TRUE; - while (unsorted==TRUE) { - unsorted = FALSE; + /* its possible there is only a few left after remove doubles */ + if ((*tot) < 3) { + // printf("removed too many doubles A\n"); + *tot = 0; + return; + } + + doubles = TRUE; + while (doubles==TRUE) { + doubles = FALSE; for(i=1; i<(*tot); i++) { if (fabs(isectVCosSS[i-1][0]-isectVCosSS[i][0]) < ISECT_TOLERANCE && fabs(isectVCosSS[i-1][1]-isectVCosSS[i][1]) < ISECT_TOLERANCE) { - int j; for(j=i+1; j<(*tot); j++) { isectVCosSS[j-1][0] = isectVCosSS[j][0]; isectVCosSS[j-1][1] = isectVCosSS[j][1]; } - unsorted = TRUE; /* keep looking for more doubles */ + doubles = TRUE; /* keep looking for more doubles */ (*tot)--; } } @@ -2084,6 +2098,7 @@ static void project_bucket_clip_face( /* its possible there is only a few left after remove doubles */ if ((*tot) < 3) { + // printf("removed too many doubles B\n"); *tot = 0; return; } @@ -2102,9 +2117,8 @@ static void project_bucket_clip_face( } } } -} -#if 0 +#ifdef PROJ_DEBUG_PRINT_CLIP /* include this at the bottom of the above function to debug the output */ { @@ -2123,7 +2137,9 @@ static void project_bucket_clip_face( } printf("]),\\\n"); } +#endif } + /* # This script creates faces in a blender scene from printed data above. @@ -2169,8 +2185,7 @@ def main(): if __name__ == '__main__': main() */ - -#endif + #undef ISECT_1 #undef ISECT_2 @@ -2990,14 +3005,14 @@ static void project_paint_begin(ProjPaintState *ps, short mval[2]) no[2] = (float)(v->no[2] / 32767.0f); if (ps->is_ortho) { - if (NormalizedVecAngle2(ps->viewDir, no) >= PI_80_DEG) { /* 1 vert of this face is towards us */ + if (NormalizedVecAngle2(ps->viewDir, no) >= (M_PI_2 / 90) * ps->normal_angle) { /* 1 vert of this face is towards us */ ps->vertFlags[a] |= PROJ_VERT_CULL; } } else { VecSubf(viewDirPersp, ps->viewPos, v->co); Normalize(viewDirPersp); - if (NormalizedVecAngle2(viewDirPersp, no) >= PI_80_DEG) { /* 1 vert of this face is towards us */ + if (NormalizedVecAngle2(viewDirPersp, no) >= (M_PI_2 / 90) * ps->normal_angle) { /* 1 vert of this face is towards us */ ps->vertFlags[a] |= PROJ_VERT_CULL; } } @@ -4426,16 +4441,9 @@ void imagepaint_paint(short mousebutton, short texpaint) } #ifndef PROJ_DEBUG_NOSEAMBLEED - if (settings->imapaint.flag & IMAGEPAINT_PROJECT_IGNORE_SEAMS) { - ps.seam_bleed_px = 0.0f; - } - else { - ps.seam_bleed_px = settings->imapaint.seam_bleed; /* pixel num to bleed */ - if (ps.seam_bleed_px < 2.0f) - ps.seam_bleed_px = 2.0f; - } - + ps.seam_bleed_px = settings->imapaint.seam_bleed; /* pixel num to bleed */ #endif + ps.normal_angle = settings->imapaint.normal_angle; project_paint_begin(&ps, mval); if (stroke_gp) {