diff options
author | Lars-Dominik Braun <lars@6xq.net> | 2015-04-08 20:56:23 +0200 |
---|---|---|
committer | Lars-Dominik Braun <lars@6xq.net> | 2015-05-02 21:36:45 +0200 |
commit | 697f57743e560fad2264b7a2039795432ca5b3a8 (patch) | |
tree | a6a5d2d04604b8171edfee751783d29aa2b9eefe | |
parent | d9c048f2028e3103212a1cfc6a29b2dc6c729387 (diff) | |
download | pucket-697f57743e560fad2264b7a2039795432ca5b3a8.tar.gz pucket-697f57743e560fad2264b7a2039795432ca5b3a8.tar.bz2 pucket-697f57743e560fad2264b7a2039795432ca5b3a8.zip |
Refactor flam3_iterate
-rw-r--r-- | flam3.c | 141 | ||||
-rw-r--r-- | flam3.h | 10 | ||||
-rw-r--r-- | rect.c | 34 | ||||
-rw-r--r-- | variations.c | 2 | ||||
-rw-r--r-- | variations.h | 2 |
5 files changed, 110 insertions, 79 deletions
@@ -148,60 +148,60 @@ int flam3_create_chaos_distrib(flam3_genome *cp, int xi, unsigned short *xform_d return(0); } +void iterator_init (iterator * const iter, const flam3_genome * const genome, + const unsigned short * const xform_distrib, randctx * const rc) { + iter->consec = 0; + iter->lastxf = 0; + iter->genome = genome; + iter->xform_distrib = xform_distrib; + iter->p = (double4) { + rand_d11(rc), + rand_d11(rc), + rand_d01(rc), + rand_d01(rc), + }; +} + /* xform_precalc must be called once for each xform before running this * function */ -int flam3_iterate(flam3_genome *cp, int n, int fuse, const double4 in, double4 *samples, const unsigned short *xform_distrib, randctx *rc) { - int i; - double4 p, q; - int consec = 0; - int badvals = 0; - int lastxf=0; - int fn; - - p = in; - - for (i = -fuse; i < n; i++) { - -// fn = xform_distrib[ lastxf*CHOOSE_XFORM_GRAIN + (((unsigned)irand(rc)) % CHOOSE_XFORM_GRAIN)]; - if (cp->chaos_enable) - fn = xform_distrib[ lastxf*CHOOSE_XFORM_GRAIN + (rand_u64(rc) & CHOOSE_XFORM_GRAIN_M1)]; - else - fn = xform_distrib[ rand_u64(rc) & CHOOSE_XFORM_GRAIN_M1 ]; - - if (apply_xform(cp, fn, p, &q, rc)>0) { - consec ++; - badvals ++; - if (consec<5) { - p = q; - --i; - continue; - } else - consec = 0; - } else - consec = 0; - - /* Store the last used transform */ - lastxf = fn+1; - - p = q; - - if (cp->final_xform_enable == 1) { - if (cp->xform[cp->final_xform_index].opacity==1 || - rand_d01(rc)<cp->xform[cp->final_xform_index].opacity) { - apply_xform(cp, cp->final_xform_index, p, &q, rc); - /* Keep the opacity from the original xform */ - q = (double4) { q[0], q[1], q[2], p[3] }; - } - } - - /* if fuse over, store it */ - if (i >= 0) { - samples[i] = q; - } - } - - return(badvals); +bool iterator_step (iterator * const iter, double4 * const ret, randctx * const rc) { + const flam3_genome * const genome = iter->genome; + unsigned int fn; + double4 q; + + if (genome->chaos_enable) + fn = iter->xform_distrib[ iter->lastxf*CHOOSE_XFORM_GRAIN + (rand_u64(rc) & CHOOSE_XFORM_GRAIN_M1)]; + else + fn = iter->xform_distrib[ rand_u64(rc) & CHOOSE_XFORM_GRAIN_M1 ]; + + if (apply_xform(genome, fn, iter->p, &q, rc)>0) { + ++iter->consec; + if (iter->consec < 5) { + iter->p = q; + return false; + } else + iter->consec = 0; + } else + iter->consec = 0; + + /* Store the last used transform */ + iter->lastxf = fn+1; + + iter->p = q; + + if (genome->final_xform_enable == 1) { + if (genome->xform[genome->final_xform_index].opacity==1 || + rand_d01(rc)<genome->xform[genome->final_xform_index].opacity) { + apply_xform(genome, genome->final_xform_index, iter->p, &q, rc); + /* Keep the opacity from the original xform */ + q = (double4) { q[0], q[1], q[2], iter->p[3] }; + } + } + + *ret = q; + + return true; } /* @@ -1832,7 +1832,7 @@ static int sort_by_y(const void *av, const void *bv) { * find a 2d bounding box that does not enclose eps of the fractal density * in each compass direction. */ -int flam3_estimate_bounding_box(flam3_genome *cp, double eps, int nsamples, +int flam3_estimate_bounding_box(flam3_genome *cp, double eps, int maxsamples, double *bmin, double *bmax, randctx *rc) { int i; int low_target, high_target; @@ -1841,11 +1841,10 @@ int flam3_estimate_bounding_box(flam3_genome *cp, double eps, int nsamples, int bv; unsigned short *xform_distrib; - if (nsamples <= 0) nsamples = 10000; + if (maxsamples <= 0) maxsamples = 10000; - int ret = posix_memalign ((void **) &points, sizeof (*points), sizeof(*points) * nsamples); + int ret = posix_memalign ((void **) &points, sizeof (*points), sizeof(*points) * maxsamples); assert (ret == 0 && points != NULL); - const double4 start = (double4) { rand_d11(rc), rand_d11(rc), 0.0, 0.0 }; if (prepare_precalc_flags(cp)) return(-1); @@ -1856,23 +1855,39 @@ int flam3_estimate_bounding_box(flam3_genome *cp, double eps, int nsamples, xform_precalc (&cp->xform[i]); } - bv=flam3_iterate(cp, nsamples, 20, start, points, xform_distrib, rc); + iterator iter; + iterator_init (&iter, cp, xform_distrib, rc); + + /* throw away fuse steps */ + for (unsigned int i = 0; i < 20; i++) { + double4 p; + iterator_step (&iter, &p, rc); + } + + /* actual iterations */ + unsigned int samples = 0; + for (unsigned int i = 0; i < maxsamples; i++) { + if (iterator_step (&iter, &points[samples], rc)) { + ++samples; + } + } + free(xform_distrib); - if ( bv/(double)nsamples > eps ) - eps = 3*bv/(double)nsamples; + if ( bv/(double)samples > eps ) + eps = 3*bv/(double)samples; if ( eps > 0.3 ) eps = 0.3; - low_target = (int)(nsamples * eps); - high_target = nsamples - low_target; + low_target = (int)(samples * eps); + high_target = samples - low_target; min[0] = min[1] = 1e10; max[0] = max[1] = -1e10; - for (i = 0; i < nsamples; i++) { + for (i = 0; i < samples; i++) { const double4 p = points[i]; if (p[0] < min[0]) min[0] = p[0]; if (p[1] < min[1]) min[1] = p[1]; @@ -1889,11 +1904,11 @@ int flam3_estimate_bounding_box(flam3_genome *cp, double eps, int nsamples, return(bv); } - qsort(points, nsamples, sizeof(double4), sort_by_x); + qsort(points, samples, sizeof(double4), sort_by_x); bmin[0] = points[low_target][0]; bmax[0] = points[high_target][0]; - qsort(points, nsamples, sizeof(double4), sort_by_y); + qsort(points, samples, sizeof(double4), sort_by_y); bmin[1] = points[low_target][1]; bmax[1] = points[high_target][1]; free(points); @@ -507,3 +507,13 @@ typedef struct { #define CROSS_INTERPOLATE 1 #define CROSS_ALTERNATE 2 +typedef struct { + unsigned int consec, lastxf; + double4 p; + const unsigned short *xform_distrib; + const flam3_genome *genome; +} iterator; + +void iterator_init (iterator * const iter, const flam3_genome * const genome, + const unsigned short * const xform_distrib, randctx * const rc); +bool iterator_step (iterator * const iter, double4 * const ret, randctx * const rc); @@ -89,27 +89,33 @@ static void iter_thread (flam3_genome * const input_genome, const double starttime = omp_get_wtime (); do { - /* Seed iterations */ - const double4 start = (double4) { - rand_d11(&rc), - rand_d11(&rc), - rand_d01(&rc), - rand_d01(&rc), - }; - - /* Execute iterations */ - const unsigned long badcount = flam3_iterate(&genome, - c->sub_batch_size, c->fuse, start, iter_storage, - c->xform_distrib, &rc); + iterator iter; + iterator_init (&iter, &genome, c->xform_distrib, &rc); + + /* throw away fuse steps */ + for (unsigned int i = 0; i < c->fuse; i++) { + double4 p; + iterator_step (&iter, &p, &rc); + } + + /* actual iterations */ + unsigned int samples = 0; + for (unsigned int i = 0; i < c->sub_batch_size; i++) { + if (iterator_step (&iter, &iter_storage[samples], &rc)) { + ++samples; + } + } + + const unsigned long badcount = c->sub_batch_size - samples; #pragma omp critical { /* Add the badcount to the counter */ bucket->badvals += badcount; - bucket->samples += c->sub_batch_size; + bucket->samples += samples; /* Put them in the bucket accumulator */ - for (unsigned int j = 0; j < c->sub_batch_size; j++) { + for (unsigned int j = 0; j < samples; j++) { const double4 p = iter_storage[j]; const double2 origpos = (double2) { p[0], p[1] }; diff --git a/variations.c b/variations.c index 82a74a7..dc6aacf 100644 --- a/variations.c +++ b/variations.c @@ -2032,7 +2032,7 @@ int prepare_precalc_flags(flam3_genome *cp) { return(0); } -int apply_xform(flam3_genome *cp, int fn, const double4 p, double4 *q_ret, randctx *rc) +int apply_xform(const flam3_genome * const cp, int fn, const double4 p, double4 *q_ret, randctx *rc) { flam3_iter_helper f; int var_n; diff --git a/variations.h b/variations.h index 519a9e8..5d9f2bd 100644 --- a/variations.h +++ b/variations.h @@ -22,6 +22,6 @@ void xform_precalc (flam3_xform * const xform); int prepare_precalc_flags(flam3_genome *); -int apply_xform(flam3_genome *cp, int fn, const double4 p, double4 *, randctx *rc); +int apply_xform(const flam3_genome * const cp, int fn, const double4 p, double4 *q_ret, randctx *rc); void initialize_xforms(flam3_genome *thiscp, int start_here); |