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.18 by schorsch, Sun Mar 6 01:13:18 2016 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines