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.22 by greg, Fri Feb 28 05:18:49 2020 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines