ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/bsdfmesh.c
(Generate patch)

Comparing ray/src/cv/bsdfmesh.c (file contents):
Revision 2.4 by greg, Thu Nov 8 23:11:41 2012 UTC vs.
Revision 2.9 by greg, Fri Jun 28 23:18:51 2013 UTC

# Line 119 | Line 119 | run_subprocess(void)
119                  if (pid < 0) {
120                          fprintf(stderr, "%s: cannot fork subprocess\n",
121                                          progname);
122 +                        await_children(nchild);
123                          exit(1);
124                  }
125                  ++nchild;                       /* subprocess started */
# Line 172 | Line 173 | price_routes(PRICEMAT *pm, const RBFNODE *from_rbf, co
173              FVECT               vfrom;
174              ovec_from_pos(vfrom, from_rbf->rbfa[i].gx, from_rbf->rbfa[i].gy);
175              for (j = to_rbf->nrbf; j--; ) {
176 <                pricerow(pm,i)[j] = acos(DOT(vfrom, vto[j])) +
176 >                double          dprod = DOT(vfrom, vto[j]);
177 >                pricerow(pm,i)[j] = ((dprod >= 1.) ? .0 : acos(dprod)) +
178                                  fabs(R2ANG(to_rbf->rbfa[j].crad) - from_ang);
179                  psortrow(pm,i)[j] = j;
180              }
# Line 197 | Line 199 | min_cost(double amt2move, const double *avail, const P
199          int             j;
200  
201          if (amt2move <= FTINY)                  /* pre-emptive check */
202 <                return(0.);
202 >                return(.0);
203                                                  /* move cheapest first */
204          for (j = 0; j < pm->ncols && amt2move > FTINY; j++) {
205                  int     d = psortrow(pm,s)[j];
# Line 215 | Line 217 | migration_step(MIGRATION *mig, double *src_rem, double
217   {
218          const double    maxamt = 1./(double)pm->ncols;
219          const double    minamt = maxamt*5e-6;
220 <        static double   *src_cost = NULL;
219 <        static int      n_alloc = 0;
220 >        double          *src_cost;
221          struct {
222                  int     s, d;   /* source and destination */
223                  double  price;  /* price estimate per amount moved */
224                  double  amt;    /* amount we can move */
225          } cur, best;
226          int             i;
227 <
228 <        if (pm->nrows > n_alloc) {              /* allocate cost array */
229 <                if (n_alloc)
230 <                        free(src_cost);
231 <                src_cost = (double *)malloc(sizeof(double)*pm->nrows);
232 <                if (src_cost == NULL) {
232 <                        fprintf(stderr, "%s: Out of memory in migration_step()\n",
233 <                                        progname);
234 <                        exit(1);
235 <                }
236 <                n_alloc = pm->nrows;
227 >                                                /* allocate cost array */
228 >        src_cost = (double *)malloc(sizeof(double)*pm->nrows);
229 >        if (src_cost == NULL) {
230 >                fprintf(stderr, "%s: Out of memory in migration_step()\n",
231 >                                progname);
232 >                exit(1);
233          }
234          for (i = pm->nrows; i--; )              /* starting costs for diff. */
235                  src_cost[i] = min_cost(src_rem[i], dst_rem, pm, i);
# Line 242 | Line 238 | migration_step(MIGRATION *mig, double *src_rem, double
238          best.s = best.d = -1; best.price = FHUGE; best.amt = 0;
239          for (cur.s = pm->nrows; cur.s--; ) {
240              double      cost_others = 0;
241 +
242              if (src_rem[cur.s] <= minamt)
243                      continue;
244                                                  /* examine cheapest dest. */
245              for (i = 0; i < pm->ncols; i++)
246 <                if (dst_rem[cur.d = psortrow(pm,cur.s)[i]] > minamt)
246 >                if (dst_rem[ cur.d = psortrow(pm,cur.s)[i] ] > minamt)
247                          break;
248              if (i >= pm->ncols)
249 <                    return(.0);
249 >                break;
250              if ((cur.price = pricerow(pm,cur.s)[cur.d]) >= best.price)
251 <                    continue;                   /* no point checking further */
251 >                continue;                       /* no point checking further */
252              cur.amt = (src_rem[cur.s] < dst_rem[cur.d]) ?
253                                  src_rem[cur.s] : dst_rem[cur.d];
254              if (cur.amt > maxamt) cur.amt = maxamt;
# Line 265 | Line 262 | migration_step(MIGRATION *mig, double *src_rem, double
262              if (cur.price < best.price)         /* are we better than best? */
263                      best = cur;
264          }
265 <        if ((best.s < 0) | (best.d < 0))
265 >        free(src_cost);                         /* finish up */
266 >
267 >        if ((best.s < 0) | (best.d < 0))        /* nothing left to move? */
268                  return(.0);
269 <                                                /* make the actual move */
269 >                                                /* else make the actual move */
270          mtx_coef(mig,best.s,best.d) += best.amt;
271          src_rem[best.s] -= best.amt;
272          dst_rem[best.d] -= best.amt;
273          return(best.amt);
274   }
275  
277 #ifdef DEBUG
278 static char *
279 thetaphi(const FVECT v)
280 {
281        static char     buf[128];
282        double          theta, phi;
283
284        theta = 180./M_PI*acos(v[2]);
285        phi = 180./M_PI*atan2(v[1],v[0]);
286        sprintf(buf, "(%.0f,%.0f)", theta, phi);
287
288        return(buf);
289 }
290 #endif
291
276   /* Compute and insert migration along directed edge (may fork child) */
277   static MIGRATION *
278   create_migration(RBFNODE *from_rbf, RBFNODE *to_rbf)
# Line 298 | Line 282 | create_migration(RBFNODE *from_rbf, RBFNODE *to_rbf)
282          MIGRATION       *newmig;
283          double          *src_rem, *dst_rem;
284          double          total_rem = 1., move_amt;
285 <        int             i;
285 >        int             i, j;
286                                                  /* check if exists already */
287          for (newmig = from_rbf->ejl; newmig != NULL;
288                          newmig = nextedge(from_rbf,newmig))
289                  if (newmig->rbfv[1] == to_rbf)
290                          return(NULL);
291                                                  /* else allocate */
292 + #ifdef DEBUG
293 +        fprintf(stderr, "Building path from (theta,phi) (%.0f,%.0f) ",
294 +                        get_theta180(from_rbf->invec),
295 +                        get_phi360(from_rbf->invec));
296 +        fprintf(stderr, "to (%.0f,%.0f) with %d x %d matrix\n",
297 +                        get_theta180(to_rbf->invec),
298 +                        get_phi360(to_rbf->invec),
299 +                        from_rbf->nrbf, to_rbf->nrbf);
300 + #endif
301          newmig = new_migration(from_rbf, to_rbf);
302          if (run_subprocess())
303                  return(newmig);                 /* child continues */
# Line 316 | Line 309 | create_migration(RBFNODE *from_rbf, RBFNODE *to_rbf)
309                                  progname);
310                  exit(1);
311          }
319 #ifdef DEBUG
320        fprintf(stderr, "Building path from (theta,phi) %s ",
321                        thetaphi(from_rbf->invec));
322        fprintf(stderr, "to %s with %d x %d matrix\n",
323                        thetaphi(to_rbf->invec),
324                        from_rbf->nrbf, to_rbf->nrbf);
325 #endif
312                                                  /* starting quantities */
313          memset(newmig->mtx, 0, sizeof(float)*from_rbf->nrbf*to_rbf->nrbf);
314          for (i = from_rbf->nrbf; i--; )
315                  src_rem[i] = rbf_volume(&from_rbf->rbfa[i]) / from_rbf->vtotal;
316 <        for (i = to_rbf->nrbf; i--; )
317 <                dst_rem[i] = rbf_volume(&to_rbf->rbfa[i]) / to_rbf->vtotal;
316 >        for (j = to_rbf->nrbf; j--; )
317 >                dst_rem[j] = rbf_volume(&to_rbf->rbfa[j]) / to_rbf->vtotal;
318 >
319          do {                                    /* move a bit at a time */
320                  move_amt = migration_step(newmig, src_rem, dst_rem, &pmtx);
321                  total_rem -= move_amt;
335 #ifdef DEBUG
336                if (!nchild)
337                        fprintf(stderr, "\r%.9f remaining...", total_rem);
338 #endif
322          } while ((total_rem > end_thresh) & (move_amt > 0));
323 < #ifdef DEBUG
341 <        if (!nchild) fputs("done.\n", stderr);
342 <        else fprintf(stderr, "finished with %.9f remaining\n", total_rem);
343 < #endif
323 >
324          for (i = from_rbf->nrbf; i--; ) {       /* normalize final matrix */
325 <            float       nf = rbf_volume(&from_rbf->rbfa[i]);
346 <            int         j;
325 >            double      nf = rbf_volume(&from_rbf->rbfa[i]);
326              if (nf <= FTINY) continue;
327              nf = from_rbf->vtotal / nf;
328              for (j = to_rbf->nrbf; j--; )
329 <                mtx_coef(newmig,i,j) *= nf;
329 >                mtx_coef(newmig,i,j) *= nf;     /* row now sums to 1.0 */
330          }
331          end_subprocess();                       /* exit here if subprocess */
332          free_routes(&pmtx);                     /* free working arrays */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines