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.14 by greg, Thu Feb 27 22:42:53 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 >        static const int        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 */
199 <        return(idf_getfield(param, surf_type[i].vert_fld));
221 >        return(res);
222   }
223  
224   /* Get/allocate surface polygon */
# Line 297 | Line 319 | rad_surface(IDF_OBJECT *param, FILE *ofp)
319   }
320  
321   /* Convert subsurface to Radiance with modifier based on unique name */
322 < static int
322 > static double
323   rad_subsurface(IDF_OBJECT *param, FILE *ofp)
324   {
325          const char      *sname = idf_getfield(param,NAME_FLD)->val;
326 <        SURFACE         *surf = get_surface(idf_getfield(param,SS_VERT_FLD));
326 >        SURFACE         *surf = get_surface(get_vlist(param, NULL));
327 >        double          area;
328          int             i;
329  
330          if (surf == NULL) {
331                  fprintf(stderr, "%s: bad subsurface '%s'\n", progname, sname);
332 <                return(0);
332 >                return(-1.);
333          }
334          fprintf(ofp, "\nvoid glow '%s'\n0\n0\n4 1 1 1 0\n", sname);
335          fprintf(ofp, "\n'%s' polygon 'ss_%s'\n0\n0\n%d\n",
# Line 316 | Line 339 | rad_subsurface(IDF_OBJECT *param, FILE *ofp)
339                  VSUM(vert, surf->vl[i], surf->norm, 2.*SURF_EPS);
340                  fprintf(ofp, "\t%.12f %.12f %.12f\n", vert[0], vert[1], vert[2]);
341          }
342 +        area = surf->area;
343          free(surf);
344 <        return(!ferror(ofp));
344 >        if (ferror(ofp))
345 >                return(-1.);
346 >        return(area);
347   }
348  
349   /* Start rcontrib process */
# Line 333 | Line 359 | start_rcontrib(SUBPROC *pd, ZONE *zp)
359          FILE            *ofp;
360          IDF_OBJECT      *pptr;
361          IDF_FIELD       *fptr;
362 <        int             i, n;
362 >        int             i, j, n;
363                                                  /* start oconv command */
364          sprintf(cbuf, "oconv - > '%s'", temp_octree);
365          if ((ofp = popen(cbuf, "w")) == NULL) {
# Line 363 | Line 389 | start_rcontrib(SUBPROC *pd, ZONE *zp)
389                  av[i++] = fptr->val;
390          }
391                                                  /* now subsurfaces */
392 +        if (zp->ntotal > zp->nsurf) {
393 +                if (zp->area_redu != NULL)
394 +                        memset(zp->area_redu, 0, sizeof(float)*zp->nsurf);
395 +                else if ((zp->area_redu = (float *)calloc(zp->nsurf,
396 +                                                sizeof(float))) == NULL)
397 +                        return(0);
398 +        }
399          for ( ; n < zp->ntotal; n++, pptr = pptr->dnext) {
400 +                double          ssarea;
401 +                const char      *bname;
402 +                IDF_OBJECT      *pptr1;
403                  fptr = idf_getfield(pptr,NAME_FLD);
404                  if (fptr == NULL || !fptr->val[0]) {
405                          fputs(progname, stderr);
406                          fputs(": missing name for subsurface object\n", stderr);
407                          return(0);
408                  }
409 <                if (!rad_subsurface(pptr, ofp)) /* add surface to octree */
409 >                                                /* add subsurface to octree */
410 >                if ((ssarea = rad_subsurface(pptr, ofp)) < 0)
411                          return(0);
412 +                                                /* mark area for subtraction */
413 +                bname = idf_getfield(pptr,SS_BASE_FLD)->val;
414 +                for (j = 0, pptr1 = zp->pfirst;
415 +                                j < zp->nsurf; j++, pptr1 = pptr1->dnext)
416 +                        if (!strcmp(idf_getfield(pptr1,NAME_FLD)->val, bname)) {
417 +                                zp->area_redu[j] += ssarea;
418 +                                break;
419 +                        }
420                  av[i++] = "-m";
421                  av[i++] = fptr->val;
422          }
# Line 492 | Line 537 | sample_triangle(const Vert2_list *vl2, int a, int b, i
537   }
538  
539   /* Sample the given surface */
540 < static int
540 > static double
541   sample_surface(IDF_OBJECT *param, int wd)
542   {
543          POLYSAMP        psamp;
544 +        double          area;
545          int             nv;
546          Vert2_list      *vlist2;
547                                          /* set up our polygon sampler */
# Line 503 | Line 549 | sample_surface(IDF_OBJECT *param, int wd)
549                  fprintf(stderr, "%s: bad polygon %s '%s'\n",
550                                  progname, param->pname,
551                                  idf_getfield(param,NAME_FLD)->val);
552 <                return(0);
552 >                return(-1.);
553          }
554          psamp.samp_left = nsamps;       /* assign samples & destination */
555          psamp.wd = wd;
556                                          /* hack for subsurface sampling */
557          psamp.poff += 2.*SURF_EPS * !strcmp(param->pname, SUBSURF_PNAME);
558 +
559 +        area = psamp.area_left;         /* remember starting surface area */
560                                          /* sample each subtriangle */
561          if (!polyTriangulate(vlist2, &sample_triangle))
562 <                return(0);
562 >                return(-1.);
563          polyFree(vlist2);               /* clean up and return */
564 <        return(1);
564 >        return(area);
565   }
566  
567   /* Compute User View Factors using open rcontrib process */
# Line 545 | Line 593 | compute_uvfs(SUBPROC *pd, ZONE *zp)
593                                                  /* UVFs from each surface */
594          for (n = 0, pptr = zp->pfirst; n < zp->ntotal; n++, pptr = pptr->dnext) {
595                  double  vfsum = 0;
596 +                double  adj_factor;
597                                                  /* send samples to rcontrib */
598 <                if (!sample_surface(pptr, pd->w))
598 >                if ((adj_factor = sample_surface(pptr, pd->w)) < 0)
599                          return(0);
600 +                if (zp->area_redu == NULL)
601 +                        adj_factor = 1.;
602 +                else                            /* comp. for subsurface area */
603 +                        adj_factor /= adj_factor - zp->area_redu[n];
604                                                  /* read results */
605                  if (readbuf(pd->r, (char *)uvfa, sizeof(float)*3*zp->ntotal) !=
606                                  sizeof(float)*3*zp->ntotal) {
# Line 558 | Line 611 | compute_uvfs(SUBPROC *pd, ZONE *zp)
611                                                  /* append UVF fields */
612                  for (m = 0, pptr1 = zp->pfirst;
613                                  m < zp->ntotal; m++, pptr1 = pptr1->dnext) {
614 <                        vfsum += uvfa[3*m + 1];
615 <                        if (pptr1 == pptr && uvfa[3*m + 1] > .001)
614 >                        const double    uvf = uvfa[3*m + 1] * adj_factor;
615 >                        vfsum += uvf;
616 >                        if (pptr1 == pptr && uvf > .001)
617                                  fprintf(stderr,
618                  "%s: warning - non-zero self-VF (%.1f%%) for surface '%s'\n",
619 <                                                progname, 100.*uvfa[3*m + 1],
619 >                                                progname, 100.*uvf,
620                                                  idf_getfield(pptr,NAME_FLD)->val);
621 <                        sprintf(uvfbuf, "%.4f", uvfa[3*m + 1]);
621 >                        sprintf(uvfbuf, "%.4f", uvf);
622                          if (!idf_addfield(pout,
623                                          idf_getfield(pptr,NAME_FLD)->val, NULL) ||
624                                  !idf_addfield(pout,

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines