/* Last edited on 2025-02-05 14:54:56 by stolfi */ auto void report_pixel ( i2_t *iPix, r3_t *pCtr, double zFoc, double zDep, double shrp, double hAvg, double hDev, r3_t *sNrm, int32_t NC, float sVal[] ); /* A procedure suitable for the {report_pixel} argument of {multifok_raytrace_paint_frame_rectangle}. The procedure prints the ray data on {stderr}. */ auto void report_ray ( i2_t *iPix, i2_t *iSmp, double step, double wSmp, r3_t *pRay, r3_t *dRay, double wRay, r3_t *pHit, double hHit, double vBlr, r3_t *sNrm, int32_t NC, float sVal[] ); /* A procedure suitable for the {report_ray} argument of {multifok_raytrace_paint_frame_rectangle}. */ void report_ray ( i2_t *iPix, i2_t *iSmp, double step, double wSmp, r3_t *pRay, r3_t *dRay, double wRay, r3_t *pHit, double hHit, double vBlr, r3_t *sNrm, int32_t NC, float sVal[] ) { double pixSize = 1.0; multifok_raytrace_show_ray_data ( stderr, 6, iPix, pixSize, iSmp, step, wSmp, pRay, dRay, wRay, pHit, hHit, vBlr, sNrm, NC, sVal ); } void report_pixel ( i2_t *iPix, r3_t *pCtr, double zFoc, double zDep, double shrp, double hAvg, double hDev, r3_t *sNrm, int32_t NC, float sVal[] ) { double pixSize = 1.0; multifok_raytrace_show_pixel_data ( stderr, 4, iPix, pixSize, pCtr, zFoc, zDep, shrp, hAvg, hDev, sNrm, NC, sVal ); } void mren_make_and_write_frame ( int32_t NX, int32_t NY, float_image_test_generator_t *fpat, uint32_t HS, uint32_t KR_min, double zFoc, double zDep, multifok_raytrace_debug_pred_t *debug_pixel, multifok_raytrace_report_ray_proc_t report_ray, multifok_raytrace_report_pixel_proc_t report_pixel, char *frameFolder, bool_t verbose ) { fprintf(stderr, "generating blurred image zFoc = %12.6f pixels\n", zFoc); multifok_sampling_t *samp = multifok_sampling_choose(HS, KR_min, verbose); uint32_t NS = samp->NS; /* Number of pixel sub-sampling points. */ uint32_t KR = samp->KR; /* Number of pixel sub-sampling points. */ /* Paranoia: */ assert(NS >= 1); assert(KR >= 1); auto void trace_ray(r3_t *pR, r3_t *dR, bool_t debug_loc, r3_t *pHit_P, r3_t *sNrm_P, int32_t NC_loc, float sVal[]); /* A ray-tracing func suitable for {multifok_raytrace_paint_frame_rectangle}. The procedure assumes that the scene is the input image {fpat}, covering the rectangle {[0 _ NX] × [0 _ NY]} on the plane {Z=0}. */ auto void map_point(r2_t *p2_img, r3_t *p3_scene); /* An image-to-scene coordinate conversion function, suitable for the {map} argument of {multifok_raytrace_paint_frame_rectangle}. The point {p2_img} is assumed to be in the 2D image coordinate system, inside the output image domain or just outside it. It assumes that the image domain is the rectalgle {[0 _ NX] × [0 _ NY]} located at {Z = Zfoc}. */ int32_t NC = 1; r3_t dRef = (r3_t){{ 0, 0, -1 }}; multifok_raytrace_paint_frame_rectangle ( NC, NX, NY, trace_ray, map_point, &dRef, zFoc, zDep, samp, verbose, debug_pixel, report_ray, report_pixel ); multifok_sampling_free(samp); multifok_frame_free(fr); return; void trace_ray(r3_t *pR, r3_t *dR, bool_t debug_loc, r3_t *pHit_P, r3_t *sNrm_P, int32_t NC_loc, float sVal[]) { assert(NC_loc == NC); assert(dR->c[2] < 0); double zscale = -pR->c[2]/dR->c[2]; r2_t q = (r2_t){{ pR->c[0] + dR->c[0]*zscale, pR->c[1] + dR->c[1]*zscale }}; r3_t sNrm = (r3_t){{0,0,0}}; if ((q.c[0] < 0) || (q.c[0] > NX) || (q.c[1] < 0) || (q.c[1] > NY)) { for (uint32_t ic = 0; ic < NC; ic++) { sVal[ic] = 0.0; } } else { fpat(&q, NC, NX, NY, sVal); for (int32_t j = 0; j < 3; j++) { sNrm.c[j] = (j < NC ? sVal[j] : 1.0e-6); } (void)r3_dir(&sNrm, &sNrm); } r3_t pHit = (r3_t){{ q.c[0], q.c[1], 0.0 }}; (*pHit_P) = pHit; (*sNrm_P) = sNrm; } void map_point(r2_t *p2_img, r3_t *p3_scene) { (*p3_scene) = (r3_t){{ p2_img->c[0], p2_img->c[1], zFoc }}; } } void eval_spherical_pattern(r2_t *p, int32_t NC, int32_t NX, int32_t NY, float fs[]) { assert(img_pat != NULL); double dfs[NC]; float_image_interpolate_pixel(pat, p->c[0], p->c[1], 1, ix_reduce_mode_PXMIRR, dfs); for (int32_t k = 0; k < NC; k++) { fs[k] = (float)dfs[k]; } } frgb_t get_sGlo(r3_t *q) { return get_param(q, GLO, &sGlo_fg, &sGLo_bg); } frgb_t get_sLam(r3_t *q) { return get_param(q, LAM, &sLam_fg, &sLam_bg); } frgb_t get_param(r3_t *q, char code, frgb_t *fg, frgb_t *bg) { if (code == '0') { return (frgb_t){{ 0,0,0 }}; } else if (code == '1') { return (frgb_t){{ 1,1,1 }}; } else if (code == 'C') { return *fg; } else if (code == 'C') { double r = fpat(); return frgb_mix(1-r, fg, r, bg); } } }