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

Comparing ray/src/util/eplus_adduvf.c (file contents):
Revision 2.11 by greg, Sat Feb 15 01:31:36 2014 UTC vs.
Revision 2.17 by greg, Fri Apr 4 17:56:45 2014 UTC

# Line 62 | Line 62 | typedef struct s_zone {
62          int             ntotal;                 /* surfaces+subsurfaces */
63          IDF_OBJECT      *pfirst;                /* first matching object */
64          IDF_OBJECT      *plast;                 /* last before subsurfaces */
65 +        float           *area_redu;             /* subsurface area per surf. */
66   } ZONE;                 /* a list of collected zone surfaces */
67  
68   ZONE            *zone_list = NULL;      /* our list of zones */
# Line 98 | Line 99 | new_zone(const char *zname, IDF_OBJECT *param)
99          znew->next = zone_list;
100          znew->pfirst = znew->plast = param;
101          znew->ntotal = znew->nsurf = 1;
102 +        znew->area_redu = NULL;
103          return(zone_list = znew);
104   }
105  
# Line 174 | Line 176 | add_subsurf(IDF_OBJECT *param)
176   static IDF_FIELD *
177   get_vlist(IDF_OBJECT *param, const char *zname)
178   {
179 <        int             i = 0;
179 > #define itm_len         (sizeof(IDF_FIELD)+6)
180 >        static char             fld_buf[4*itm_len];
181 >        static char             *next_fbp = fld_buf;
182 >        int                     i;
183 >        IDF_FIELD               *res;
184                                                  /* check if subsurface */
185          if (!strcmp(param->pname, SUBSURF_PNAME)) {
186                  if (zname != NULL) {
# Line 183 | Line 189 | get_vlist(IDF_OBJECT *param, const char *zname)
189                          if (strcmp((*(ZONE *)lep->data).zname, zname))
190                                  return(NULL);
191                  }
192 <                return(idf_getfield(param, SS_VERT_FLD));
192 >                res = idf_getfield(param, SS_VERT_FLD);
193 >        } else {
194 >                i = 0;                          /* check for surface type */
195 >                while (strcmp(surf_type[i].pname, param->pname))
196 >                        if (surf_type[++i].pname == NULL)
197 >                                return(NULL);
198 >
199 >                if (zname != NULL) {            /* matches specified zone? */
200 >                        IDF_FIELD       *fptr = idf_getfield(param, surf_type[i].zone_fld);
201 >                        if (fptr == NULL || strcmp(fptr->val, zname))
202 >                                return(NULL);
203 >                }
204 >                res = idf_getfield(param, surf_type[i].vert_fld);
205          }
206 <                                                /* check for surface type */
207 <        while (strcmp(surf_type[i].pname, param->pname))
208 <                if (surf_type[++i].pname == NULL)
206 >        if (!res->val[0]) {                     /* hack for missing #vert */
207 >                IDF_FIELD       *fptr;
208 >                if (next_fbp >= fld_buf+sizeof(fld_buf))
209 >                        next_fbp = fld_buf;
210 >                i = 0;                          /* count vertices */
211 >                for (fptr = res->next; fptr != NULL; fptr = fptr->next)
212 >                        ++i;
213 >                if (i % 3)
214                          return(NULL);
215 <
216 <        if (zname != NULL) {                    /* matches specified zone? */
217 <                IDF_FIELD       *fptr = idf_getfield(param, surf_type[i].zone_fld);
218 <                if (fptr == NULL || strcmp(fptr->val, zname))
219 <                        return(NULL);
215 >                fptr = res->next;
216 >                res = (IDF_FIELD *)next_fbp; next_fbp += itm_len;
217 >                res->next = fptr;
218 >                res->rem = "";
219 >                sprintf(res->val, "%d", i/3);
220          }
221 <                                                /* return field for #verts */
222 <        return(idf_getfield(param, surf_type[i].vert_fld));
221 >        return(res);
222 > #undef itm_len
223   }
224  
225   /* Get/allocate surface polygon */
# Line 297 | Line 320 | rad_surface(IDF_OBJECT *param, FILE *ofp)
320   }
321  
322   /* Convert subsurface to Radiance with modifier based on unique name */
323 < static int
323 > static double
324   rad_subsurface(IDF_OBJECT *param, FILE *ofp)
325   {
326          const char      *sname = idf_getfield(param,NAME_FLD)->val;
327 <        SURFACE         *surf = get_surface(idf_getfield(param,SS_VERT_FLD));
327 >        SURFACE         *surf = get_surface(get_vlist(param, NULL));
328 >        double          area;
329          int             i;
330  
331          if (surf == NULL) {
332                  fprintf(stderr, "%s: bad subsurface '%s'\n", progname, sname);
333 <                return(0);
333 >                return(-1.);
334          }
335          fprintf(ofp, "\nvoid glow '%s'\n0\n0\n4 1 1 1 0\n", sname);
336          fprintf(ofp, "\n'%s' polygon 'ss_%s'\n0\n0\n%d\n",
# Line 316 | Line 340 | rad_subsurface(IDF_OBJECT *param, FILE *ofp)
340                  VSUM(vert, surf->vl[i], surf->norm, 2.*SURF_EPS);
341                  fprintf(ofp, "\t%.12f %.12f %.12f\n", vert[0], vert[1], vert[2]);
342          }
343 +        area = surf->area;
344          free(surf);
345 <        return(!ferror(ofp));
345 >        if (ferror(ofp))
346 >                return(-1.);
347 >        return(area);
348   }
349  
350   /* Start rcontrib process */
# Line 333 | Line 360 | start_rcontrib(SUBPROC *pd, ZONE *zp)
360          FILE            *ofp;
361          IDF_OBJECT      *pptr;
362          IDF_FIELD       *fptr;
363 <        int             i, n;
363 >        int             i, j, n;
364                                                  /* start oconv command */
365 <        sprintf(cbuf, "oconv - > '%s'", temp_octree);
365 >        sprintf(cbuf, "oconv - > \"%s\"", temp_octree);
366          if ((ofp = popen(cbuf, "w")) == NULL) {
367                  fputs(progname, stderr);
368                  fputs(": cannot open oconv process\n", stderr);
# Line 363 | Line 390 | start_rcontrib(SUBPROC *pd, ZONE *zp)
390                  av[i++] = fptr->val;
391          }
392                                                  /* now subsurfaces */
393 +        if (zp->ntotal > zp->nsurf) {
394 +                if (zp->area_redu != NULL)
395 +                        memset(zp->area_redu, 0, sizeof(float)*zp->ntotal);
396 +                else if ((zp->area_redu = (float *)calloc(zp->ntotal,
397 +                                                sizeof(float))) == NULL)
398 +                        return(0);
399 +        }
400          for ( ; n < zp->ntotal; n++, pptr = pptr->dnext) {
401 +                double          ssarea;
402 +                const char      *bname;
403 +                IDF_OBJECT      *pptr1;
404                  fptr = idf_getfield(pptr,NAME_FLD);
405                  if (fptr == NULL || !fptr->val[0]) {
406                          fputs(progname, stderr);
407                          fputs(": missing name for subsurface object\n", stderr);
408                          return(0);
409                  }
410 <                if (!rad_subsurface(pptr, ofp)) /* add surface to octree */
410 >                                                /* add subsurface to octree */
411 >                if ((ssarea = rad_subsurface(pptr, ofp)) < 0)
412                          return(0);
413 +                                                /* mark area for subtraction */
414 +                bname = idf_getfield(pptr,SS_BASE_FLD)->val;
415 +                for (j = 0, pptr1 = zp->pfirst;
416 +                                j < zp->nsurf; j++, pptr1 = pptr1->dnext)
417 +                        if (!strcmp(idf_getfield(pptr1,NAME_FLD)->val, bname)) {
418 +                                zp->area_redu[j] += ssarea;
419 +                                break;
420 +                        }
421                  av[i++] = "-m";
422                  av[i++] = fptr->val;
423          }
# Line 492 | Line 538 | sample_triangle(const Vert2_list *vl2, int a, int b, i
538   }
539  
540   /* Sample the given surface */
541 < static int
541 > static double
542   sample_surface(IDF_OBJECT *param, int wd)
543   {
544          POLYSAMP        psamp;
545 +        double          area;
546          int             nv;
547          Vert2_list      *vlist2;
548                                          /* set up our polygon sampler */
# Line 503 | Line 550 | sample_surface(IDF_OBJECT *param, int wd)
550                  fprintf(stderr, "%s: bad polygon %s '%s'\n",
551                                  progname, param->pname,
552                                  idf_getfield(param,NAME_FLD)->val);
553 <                return(0);
553 >                return(-1.);
554          }
555          psamp.samp_left = nsamps;       /* assign samples & destination */
556          psamp.wd = wd;
557                                          /* hack for subsurface sampling */
558          psamp.poff += 2.*SURF_EPS * !strcmp(param->pname, SUBSURF_PNAME);
559 +
560 +        area = psamp.area_left;         /* remember starting surface area */
561                                          /* sample each subtriangle */
562          if (!polyTriangulate(vlist2, &sample_triangle))
563 <                return(0);
563 >                return(-1.);
564          polyFree(vlist2);               /* clean up and return */
565 <        return(1);
565 >        return(area);
566   }
567  
568   /* Compute User View Factors using open rcontrib process */
# Line 545 | Line 594 | compute_uvfs(SUBPROC *pd, ZONE *zp)
594                                                  /* UVFs from each surface */
595          for (n = 0, pptr = zp->pfirst; n < zp->ntotal; n++, pptr = pptr->dnext) {
596                  double  vfsum = 0;
597 +                double  adj_factor;
598                                                  /* send samples to rcontrib */
599 <                if (!sample_surface(pptr, pd->w))
599 >                if ((adj_factor = sample_surface(pptr, pd->w)) < 0)
600                          return(0);
601 +                if (zp->area_redu == NULL)
602 +                        adj_factor = 1.;
603 +                else                            /* comp. for subsurface area */
604 +                        adj_factor /= adj_factor - zp->area_redu[n];
605                                                  /* read results */
606                  if (readbuf(pd->r, (char *)uvfa, sizeof(float)*3*zp->ntotal) !=
607                                  sizeof(float)*3*zp->ntotal) {
# Line 558 | Line 612 | compute_uvfs(SUBPROC *pd, ZONE *zp)
612                                                  /* append UVF fields */
613                  for (m = 0, pptr1 = zp->pfirst;
614                                  m < zp->ntotal; m++, pptr1 = pptr1->dnext) {
615 <                        vfsum += uvfa[3*m + 1];
616 <                        if (pptr1 == pptr && uvfa[3*m + 1] > .001)
615 >                        const double    uvf = uvfa[3*m + 1] * adj_factor;
616 >                        vfsum += uvf;
617 >                        if (pptr1 == pptr && uvf > .001)
618                                  fprintf(stderr,
619                  "%s: warning - non-zero self-VF (%.1f%%) for surface '%s'\n",
620 <                                                progname, 100.*uvfa[3*m + 1],
620 >                                                progname, 100.*uvf,
621                                                  idf_getfield(pptr,NAME_FLD)->val);
622 <                        sprintf(uvfbuf, "%.4f", uvfa[3*m + 1]);
622 >                        sprintf(uvfbuf, "%.4f", uvf);
623                          if (!idf_addfield(pout,
624                                          idf_getfield(pptr,NAME_FLD)->val, NULL) ||
625                                  !idf_addfield(pout,

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines