Index: source/blender/blenkernel/BKE_node.h =================================================================== RCS file: /cvsroot/bf-blender/blender/source/blender/blenkernel/BKE_node.h,v retrieving revision 1.27 diff -u -p -r1.27 BKE_node.h --- source/blender/blenkernel/BKE_node.h 22 Dec 2006 08:10:28 -0000 1.27 +++ source/blender/blenkernel/BKE_node.h 25 Dec 2006 20:31:14 -0000 @@ -247,6 +247,7 @@ void set_node_shader_lamp_loop(void (* #define CMP_NODE_MAP_UV 242 #define CMP_NODE_ID_MASK 243 #define CMP_NODE_DEFOCUS 244 +#define CMP_NODE_AUTOFOCUSMASK 245 /* filter types */ Index: source/blender/blenkernel/intern/node_composite.c =================================================================== RCS file: /cvsroot/bf-blender/blender/source/blender/blenkernel/intern/node_composite.c,v retrieving revision 1.85 diff -u -p -r1.85 node_composite.c --- source/blender/blenkernel/intern/node_composite.c 21 Dec 2006 18:23:30 -0000 1.85 +++ source/blender/blenkernel/intern/node_composite.c 25 Dec 2006 20:31:15 -0000 @@ -3140,6 +3140,9 @@ static bNodeType cmp_node_blur= { static bNodeSocketType cmp_node_defocus_in[]= { { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_VALUE, 1, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "fStop", 8.0f, 8.0f, 8.0f, 1.0f, 0.5f, 128.0f}, + { SOCK_VALUE, 1, "Focal length", 50.0f, 50.0f, 50.0f, 1.0f, 0.0f, 250.0f}, + { SOCK_VALUE, 1, "Focus distance", 10.0f, 10.0f, 10.0f, 1.0f, 0.0f, 10000.0f}, { -1, 0, "" } }; static bNodeSocketType cmp_node_defocus_out[]= { @@ -3158,15 +3161,15 @@ typedef struct BokehCoeffs { // returns array of BokehCoeffs // returns length of array in 'len_bkh', // radius squared of inscribed disk in 'inradsq', needed in getWeight() test, -// BKH[8] is the data returned for the bokeh shape & bkh_b[4] is it's 2d bound -static void makeBokeh(char bktype, char ro, int* len_bkh, float* inradsq, BokehCoeffs BKH[8], float bkh_b[4]) +// BKH[9] is the data returned for the bokeh shape & bkh_b[4] is it's 2d bound +static void makeBokeh(char bktype, char ro, int* len_bkh, float* inradsq, BokehCoeffs BKH[9], float bkh_b[4]) { float x0, x1, y0, y1, dx, dy, iDxy, w = ro*M_PI/180.f; float wi = (360.f/bktype)*M_PI/180.f; int i, ov, nv; - // bktype must be at least 3 & <= 8 - bktype = (bktype<3) ? 3 : ((bktype>8) ? 8 : bktype); + // bktype must be at least 3 & <= 9 + bktype = (bktype<3) ? 3 : ((bktype>9) ? 9 : bktype); *len_bkh = bktype; *inradsq = -1.f; @@ -3341,11 +3344,11 @@ static void IIR_gauss(CompBuf* buf, floa #undef YVV } -static void defocus_blur(CompBuf* new, CompBuf* img, CompBuf* zbuf, float inpval, NodeDefocus* nqd) +static void defocus_blur(CompBuf* new, CompBuf* img, CompBuf* zbuf, float inpval, NodeDefocus* nqd, float sock_fstop, float sock_flen, float sock_dist) { CompBuf *wts; // weights buffer CompBuf *crad; // CoC radius buffer - BokehCoeffs BKH[8]; // bokeh shape data, here never > 8 pts. + BokehCoeffs BKH[9]; // bokeh shape data, here never > 9 pts. float bkh_b[4] = {0}; // shape 2D bound unsigned int p, px, p4, zp, cp, cp4; float *ctcol, u, v, iZ, ct_crad, bcrad, lwt, wt=0, cR2=0; @@ -3364,14 +3367,33 @@ static void defocus_blur(CompBuf* new, C cam_invfdist = 1.f/cam_fdist; } + printf("1 L %f D %f\n", cam_lens, cam_fdist); + + if(sock_flen > 0.0f) { + cam_lens = sock_flen; + } + if(sock_dist > 0.0f) { + cam_fdist = sock_dist; + cam_invfdist = 1.f/cam_fdist; + } + + printf("2 L %f D %f\n", cam_lens, cam_fdist); + // guess work here.. best match with raytraced result minsz = MIN2(img->x, img->y); dof_sp = (float)minsz / (16.f / cam_lens); // <- == aspect * MIN2(img->x, img->y) / tan(0.5f * fov); // aperture aspect = (img->x > img->y) ? (img->y / (float)img->x) : (img->x / (float)img->y); - aperture = 0.5f*(cam_lens / (aspect*32.f)) / nqd->fstop; + if(sock_fstop > 0.0f) { + aperture = 0.5f*(cam_lens / (aspect*32.f)) / sock_fstop; + printf("SF %f\n", sock_fstop); + } else { + aperture = 0.5f*(cam_lens / (aspect*32.f)) / nqd->fstop; + printf("NF %f\n", nqd->fstop); + } + fflush(stdout); // if not disk, make bokeh coefficients and other needed data if (nqd->bktype!=0) { makeBokeh(nqd->bktype, nqd->rotation, &len_bkh, &inradsq, BKH, bkh_b); @@ -3870,7 +3892,7 @@ static void node_composit_exec_defocus(v } new = alloc_compbuf(old->x, old->y, old->type, 1); - defocus_blur(new, old, zbuf_use, in[1]->vec[0]*nqd->scale, node->storage); + defocus_blur(new, old, zbuf_use, in[1]->vec[0]*nqd->scale, node->storage, in[2]->vec[0], in[3]->vec[0], in[4]->vec[0]); if (nqd->gamco) { gamma_correct_compbuf(new, 1); @@ -3892,6 +3914,89 @@ static bNodeType cmp_node_defocus = { /* execfunc */ node_composit_exec_defocus }; +/* **************** Autofocus mask ******************** */ +/* Feed it the Z and a greyscale mask with white meaning use and + black meaning ignore to get a weighted autofocus estimation */ +static bNodeSocketType cmp_node_autofocusmask_in[]= { + { SOCK_VALUE, 1, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 10000.0f}, + { SOCK_VALUE, 1, "Mask", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "Offset", 0.0f, 0.0f, 0.0f, 1.0f, -5000.0f, 5000.0f}, + { SOCK_VALUE, 1, "Fallback", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 10000.0f}, + { -1, 0, "" } +}; +static bNodeSocketType cmp_node_autofocusmask_out[]= { + { SOCK_VALUE, 0, "Distance", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 10000.0f}, + { -1, 0, "" } +}; + +static void node_composit_exec_autofocusmask(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + float dist = in[3]->vec[0]; + + if(out[0]->hasoutput == 0) + return; + + if(in[0]->data) { + int i; + double weight = 0.0; + double zaccum = 0.0; + CompBuf *zbuf = in[0]->data; + CompBuf *maskbuf = in[1]->data; + + if (in[1]->data) { + int converted; + printf("Boo\n"); + if(maskbuf->type != CB_VAL) { + maskbuf = typecheck_compbuf(in[1]->data, CB_VAL); + converted = 1; + } + for (i = 0; i < (zbuf->x * zbuf->y); i++) { + if (((zbuf->rect[i]) <= 10000.0f) && ((maskbuf->rect[i]) > 0.0f)) { + weight += (double) maskbuf->rect[i]; + zaccum += (double) (maskbuf->rect[i] * zbuf->rect[i]); + //printf("I %i M %f Z %f we %f za %f\n", i, maskbuf->rect[i], zbuf->rect[i], weight, zaccum); + } + if ((i % 400) == 200) { + //printf("i %i M %f Z %f we %f za %f\n", i/400, maskbuf->rect[i], zbuf->rect[i], weight, zaccum); + } + } + if(converted) { + free_compbuf(maskbuf); + } + } else { + printf("Foo\n"); + if (in[1]->vec[0] > 0.0f) { + for (i = 0; i < (zbuf->x * zbuf->y); i++) { + if (zbuf->rect[i] <= 10000.0f) { + weight += (double) in[1]->vec[0]; + zaccum += (double) (in[1]->vec[0] * zbuf->rect[i]); + } + } + } + } + + if (weight > 0.0f) { + dist = (float) (zaccum / weight); + dist += in[2]->vec[0]; + } + printf("D %f Z %f W %f <--\n", dist, zaccum, weight); + fflush(stdout); + } + + out[0]->vec[0] = dist; +} + +static bNodeType cmp_node_autofocusmask= { + /* type code */ CMP_NODE_AUTOFOCUSMASK, + /* name */ "AutoFocus", + /* width+range */ 140, 100, 320, + /* class+opts */ NODE_CLASS_CONVERTOR, NODE_OPTIONS, + /* input sock */ cmp_node_autofocusmask_in, + /* output sock */ cmp_node_autofocusmask_out, + /* storage */ "", + /* execfunc */ node_composit_exec_autofocusmask +}; + /* **************** VECTOR BLUR ******************** */ static bNodeSocketType cmp_node_vecblur_in[]= { { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, @@ -5412,6 +5517,7 @@ bNodeType *node_all_composit[]= { &cmp_node_mapuv, &cmp_node_idmask, &cmp_node_defocus, + &cmp_node_autofocusmask, NULL };