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.4 by greg, Mon Feb 10 17:50:02 2014 UTC vs.
Revision 2.10 by greg, Thu Feb 13 17:33:37 2014 UTC

# Line 16 | Line 16 | static const char RCSid[] = "$Id$";
16   #include "rtprocess.h"
17  
18   #ifndef NSAMPLES
19 < #define NSAMPLES        100000                  /* number of samples to use */
19 > #define NSAMPLES        80000                   /* default number of samples */
20   #endif
21  
22   char            *progname;                      /* global argv[0] */
23  
24 < char            temp_octree[128];                       /* temporary octree */
24 > int             nsamps = NSAMPLES;              /* number of samples to use */
25  
26 + char            temp_octree[128];               /* temporary octree */
27 +
28   const char      UVF_PNAME[] =
29 <                        "ZoneProperty:UserViewFactor:bySurfaceName";
29 >                        "ZoneProperty:UserViewFactors:bySurfaceName";
30  
31   const char      ADD_HEADER[] =
32 <                        "!+++ User View Factors computed by Radiance +++!\n";
32 >                        "\n!+++ User View Factors computed by Radiance +++!\n\n";
33  
34   #define NAME_FLD        1                       /* name field always first? */
35  
36   typedef struct {
37 <        const char      *pname;                 /* parameter type name */
37 >        const char      *pname;                 /* object type name */
38          short           zone_fld;               /* zone field index */
39          short           vert_fld;               /* vertex field index */
40   } SURF_PTYPE;           /* surface type we're interested in */
41  
42   const SURF_PTYPE        surf_type[] = {
43                  {"BuildingSurface:Detailed", 4, 10},
44 +                {"Floor:Detailed", 3, 9},
45 +                {"RoofCeiling:Detailed", 3, 9},
46 +                {"Wall:Detailed", 3, 9},
47                  {NULL}
48 <        };
48 >        };                              /* IDF surface types */
49  
50   typedef struct s_zone {
51          const char      *zname;                 /* zone name */
52          struct s_zone   *next;                  /* next zone in list */
53          int             nsurf;                  /* surface count */
54 <        IDF_PARAMETER   *pfirst;                /* first matching parameter */
55 <        IDF_PARAMETER   *plast;                 /* last matching parameter */
54 >        IDF_OBJECT      *pfirst;                /* first matching object */
55 >        IDF_OBJECT      *plast;                 /* last matching object */
56   } ZONE;                 /* a list of collected zone surfaces */
57  
58   ZONE            *zone_list = NULL;      /* our list of zones */
59  
60   IDF_LOADED      *our_idf = NULL;        /* loaded/modified IDF */
61  
62 + typedef struct {
63 +        FVECT           sdir[3];        /* UVW unit sampling vectors */
64 +        double          poff;           /* W-offset for plane of polygon */
65 +        double          area_left;      /* area left to sample */
66 +        int             samp_left;      /* remaining samples */
67 +        int             wd;             /* output file descriptor */
68 + } POLYSAMP;             /* structure for polygon sampling */
69 +
70   /* Create a new zone and push to top of our list */
71   static ZONE *
72 < new_zone(const char *zname, IDF_PARAMETER *param)
72 > new_zone(const char *zname, IDF_OBJECT *param)
73   {
74          ZONE    *znew = (ZONE *)malloc(sizeof(ZONE));
75  
# Line 71 | Line 84 | new_zone(const char *zname, IDF_PARAMETER *param)
84  
85   /* Add the detailed surface (polygon) to the named zone */
86   static ZONE *
87 < add2zone(IDF_PARAMETER *param, const char *zname)
87 > add2zone(IDF_OBJECT *param, const char *zname)
88   {
89          ZONE    *zptr;
90  
# Line 81 | Line 94 | add2zone(IDF_PARAMETER *param, const char *zname)
94          if (zptr == NULL)
95                  return(new_zone(zname, param));
96                                                  /* keep surfaces together */
97 <        if (!idf_movparam(our_idf, param, zptr->plast))
97 >        if (!idf_movobject(our_idf, param, zptr->plast))
98                  return(NULL);
99          zptr->plast = param;
100          zptr->nsurf++;
101          return(zptr);
102   }
103  
104 < /* Return field for vertices in the given parameter */
104 > /* Return field for vertices in the given object */
105   static IDF_FIELD *
106 < get_vlist(IDF_PARAMETER *param, const char *zname)
106 > get_vlist(IDF_OBJECT *param, const char *zname)
107   {
108          int             i = 0;
109          IDF_FIELD       *fptr;
# Line 110 | Line 123 | get_vlist(IDF_PARAMETER *param, const char *zname)
123  
124   /* Convert surface to Radiance with modifier based on unique name */
125   static int
126 < rad_surface(IDF_PARAMETER *param, FILE *ofp)
126 > rad_surface(IDF_OBJECT *param, FILE *ofp)
127   {
128          const char      *sname = idf_getfield(param,NAME_FLD)->val;
129          IDF_FIELD       *fptr = get_vlist(param, NULL);
# Line 143 | Line 156 | rad_surface(IDF_PARAMETER *param, FILE *ofp)
156   static int
157   start_rcontrib(SUBPROC *pd, ZONE *zp)
158   {
159 < #define BASE_AC         3
159 > #define BASE_AC         5
160          static char     *base_av[BASE_AC] = {
161 <                                "rcontrib", "-ff", "-h"
161 >                                "rcontrib", "-fff", "-h", "-x", "1"
162                          };
163          char            cbuf[300];
164          char            **av;
165          FILE            *ofp;
166 <        IDF_PARAMETER   *pptr;
166 >        IDF_OBJECT      *pptr;
167          int             i, n;
168                                                  /* start oconv command */
169          sprintf(cbuf, "oconv - > '%s'", temp_octree);
# Line 165 | Line 178 | start_rcontrib(SUBPROC *pd, ZONE *zp)
178                  return(0);
179          for (i = 0; i < BASE_AC; i++)
180                  av[i] = base_av[i];
181 <        sprintf(cbuf, "%d", NSAMPLES);
181 >        sprintf(cbuf, "%d", nsamps);
182          av[i++] = "-c";
183          av[i++] = cbuf;                         /* add modifier arguments */
184          for (n = zp->nsurf, pptr = zp->pfirst; n--; pptr = pptr->dnext) {
185                  IDF_FIELD       *fptr = idf_getfield(pptr,NAME_FLD);
186                  if (fptr == NULL || !fptr->val[0]) {
187                          fputs(progname, stderr);
188 <                        fputs(": missing name for surface parameter\n", stderr);
188 >                        fputs(": missing name for surface object\n", stderr);
189                          return(0);
190                  }
191                  if (!rad_surface(pptr, ofp))    /* add surface to octree */
# Line 187 | Line 200 | start_rcontrib(SUBPROC *pd, ZONE *zp)
200          }
201          av[i++] = temp_octree;                  /* add final octree argument */
202          av[i] = NULL;
203 <        if (!open_process(pd, av)) {            /* start process */
203 >        if (open_process(pd, av) <= 0) {        /* start process */
204                  fputs(progname, stderr);
205                  fputs(": cannot start rcontrib process\n", stderr);
206                  return(0);
# Line 197 | Line 210 | start_rcontrib(SUBPROC *pd, ZONE *zp)
210   #undef BASE_AC
211   }
212  
200 typedef struct {
201        FVECT           sdir[3];        /* XYZ unit sampling vectors */
202        double          poff;           /* Z-offset for plane of polygon */
203        double          area_left;      /* area left to sample */
204        int             samp_left;      /* remaining samples */
205        int             wd;             /* output file descriptor */
206 } POLYSAMP;             /* structure for polygon sampling */
207
213   /* Initialize polygon sampling */
214   static Vert2_list *
215   init_poly(POLYSAMP *ps, IDF_FIELD *f0, int nv)
# Line 221 | Line 226 | init_poly(POLYSAMP *ps, IDF_FIELD *f0, int nv)
226          vl3 = (FVECT *)malloc(sizeof(FVECT)*nv);
227          if (vl3 == NULL)
228                  return(NULL);
229 <        for (i = 0; i < nv; i++)
229 >        for (i = nv; i--; )             /* reverse vertex ordering */
230                  for (j = 0; j < 3; j++) {
231                          if (fptr == NULL) {
232                                  fputs(progname, stderr);
233 <                                fputs(": bad vertex in init_poly()\n", stderr);
233 >                                fputs(": missing vertex in init_poly()\n", stderr);
234                                  return(NULL);
235                          }
236                          vl3[i][j] = atof(fptr->val);
237 +                        fptr = fptr->next;
238                  }
239                                          /* compute area and normal */
240          ps->sdir[2][0] = ps->sdir[2][1] = ps->sdir[2][2] = 0;
# Line 252 | Line 258 | init_poly(POLYSAMP *ps, IDF_FIELD *f0, int nv)
258          normalize(ps->sdir[0]);
259          fcross(ps->sdir[1], ps->sdir[2], ps->sdir[0]);
260                                          /* compute plane offset */
261 <        ps->poff = DOT(vl3[0], ps->sdir[2]) + FTINY;
261 >        ps->poff = DOT(vl3[0], ps->sdir[2]);
262                                          /* assign 2-D vertices */
263          for (i = 0; i < nv; i++) {
264                  vl2->v[i].mX = DOT(vl3[i], ps->sdir[0]);
# Line 276 | Line 282 | sample_triangle(const Vert2_list *vl2, int a, int b, i
282          for (i = 3; i--; ) {
283                  orig[i] = vl2->v[a].mX*ps->sdir[0][i] +
284                                  vl2->v[a].mY*ps->sdir[1][i] +
285 <                                ps->poff*ps->sdir[2][i];
285 >                                (ps->poff+.001)*ps->sdir[2][i];
286                  ab[i] = (vl2->v[b].mX - vl2->v[a].mX)*ps->sdir[0][i] +
287                                  (vl2->v[b].mY - vl2->v[a].mY)*ps->sdir[1][i];
288                  ac[i] = (vl2->v[c].mX - vl2->v[a].mX)*ps->sdir[0][i] +
# Line 307 | Line 313 | sample_triangle(const Vert2_list *vl2, int a, int b, i
313                  return(0);
314          for (i = ns; i--; ) {           /* stratified Monte Carlo sampling */
315                  double  sv[4];
316 +                FVECT   dv;
317                  multisamp(sv, 4, (i+frandom())/(double)ns);
318                  sv[0] *= sv[1] = sqrt(sv[1]);
319                  sv[1] = 1. - sv[1];
320                  for (j = 3; j--; )
321 <                        samp[ns*6 + j] = orig[j] + sv[0]*ab[j] + sv[1]*ac[j];
322 <                sv[3] = sqrt(sv[3]);
323 <                sv[4] *= 2.*PI;
324 <                samp[ns*6 + 3] = tcos(sv[4]) * sv[3];
325 <                samp[ns*6 + 4] = tsin(sv[4]) * sv[3];
326 <                samp[ns*6 + 5] = sqrt(1. - sv[3]*sv[3]);
321 >                        samp[i*6 + j] = orig[j] + sv[0]*ab[j] + sv[1]*ac[j];
322 >                sv[2] = sqrt(sv[2]);
323 >                sv[3] *= 2.*PI;
324 >                dv[0] = tcos(sv[3]) * sv[2];
325 >                dv[1] = tsin(sv[3]) * sv[2];
326 >                dv[2] = sqrt(1. - sv[2]*sv[2]);
327 >                for (j = 3; j--; )
328 >                        samp[i*6 + 3 + j] = dv[0]*ps->sdir[0][j] +
329 >                                                dv[1]*ps->sdir[1][j] +
330 >                                                dv[2]*ps->sdir[2][j] ;
331          }
332                                          /* send to our process */
333          writebuf(ps->wd, (char *)samp, sizeof(float)*6*ns);
# Line 326 | Line 337 | sample_triangle(const Vert2_list *vl2, int a, int b, i
337  
338   /* Sample the given surface */
339   static int
340 < sample_surface(IDF_PARAMETER *param, int wd)
340 > sample_surface(IDF_OBJECT *param, int wd)
341   {
342          IDF_FIELD       *fptr = get_vlist(param, NULL);
343          POLYSAMP        psamp;
344          int             nv;
345          Vert2_list      *vlist2;
346                                          /* set up our polygon sampler */
347 <        if (fptr == NULL || (nv = atoi(fptr->val)) < 3) {
348 <                fprintf(stderr, "%s: error in %s '%s'\n",
347 >        if (fptr == NULL || (nv = atoi(fptr->val)) < 3 ||
348 >                        (vlist2 = init_poly(&psamp, fptr->next, nv)) == NULL) {
349 >                fprintf(stderr, "%s: bad polygon %s '%s'\n",
350                                  progname, param->pname,
351                                  idf_getfield(param,NAME_FLD)->val);
352                  return(0);
353          }
354 <        vlist2 = init_poly(&psamp, fptr->next, nv);
343 <        if (vlist2 == NULL)
344 <                return(0);
345 <        psamp.samp_left = NSAMPLES;     /* assign samples & destination */
354 >        psamp.samp_left = nsamps;       /* assign samples & destination */
355          psamp.wd = wd;
356                                          /* sample each subtriangle */
357          if (!polyTriangulate(vlist2, &sample_triangle))
# Line 355 | Line 364 | sample_surface(IDF_PARAMETER *param, int wd)
364   static int
365   compute_uvfs(SUBPROC *pd, ZONE *zp)
366   {
367 <        IDF_PARAMETER   *pptr, *pout, *pptr1;
367 >        IDF_OBJECT      *pptr, *pout, *pptr1;
368          float           *uvfa;
369          char            uvfbuf[24];
370          int             n, m;
371 <                                                /* create output parameter */
372 <        pout = idf_newparam(our_idf, UVF_PNAME,
371 >                                                /* create output object */
372 >        pout = idf_newobject(our_idf, UVF_PNAME,
373                          "    ! computed by Radiance\n        ", zp->plast);
374          if (pout == NULL) {
375                  fputs(progname, stderr);
376 <                fputs(": cannot create new IDF parameter\n", stderr);
376 >                fputs(": cannot create new IDF object\n", stderr);
377                  return(0);
378          }
379          if (!idf_addfield(pout, zp->zname,
# Line 397 | Line 406 | compute_uvfs(SUBPROC *pd, ZONE *zp)
406                          if (pptr1 == pptr) {
407                                  if (uvfa[3*m + 1] > .001)
408                                          fprintf(stderr,
409 <                "%s: warning - non-zero self-VF (%.3e) for surface '%s'\n",
410 <                                                progname, uvfa[3*m + 1],
409 >                "%s: warning - non-zero self-VF (%.1f%%) for surface '%s'\n",
410 >                                                progname, 100.*uvfa[3*m + 1],
411                                                  idf_getfield(pptr,NAME_FLD)->val);
412                                  continue;       /* don't record self-factor */
413                          }
414 <                        sprintf(uvfbuf, "%.6f", uvfa[3*m + 1]);
414 >                        sprintf(uvfbuf, "%.4f", uvfa[3*m + 1]);
415                          if (!idf_addfield(pout,
416                                          idf_getfield(pptr,NAME_FLD)->val, NULL) ||
417                                  !idf_addfield(pout,
# Line 431 | Line 440 | compute_zones(void)
440   {
441          ZONE    *zptr;
442                                                  /* temporary octree name */
443 <        if (temp_filename(temp_octree, sizeof(temp_octree), TEMPLATE) == NULL) {
435 <                fputs(progname, stderr);
436 <                fputs(": cannot create temporary octree\n", stderr);
437 <                return(0);
438 <        }
443 >        mktemp(strcpy(temp_octree, TEMPLATE));
444                                                  /* compute each zone */
445          for (zptr = zone_list; zptr != NULL; zptr = zptr->next) {
446                  SUBPROC rcproc;
# Line 461 | Line 466 | main(int argc, char *argv[])
466   {
467          int             incl_comments = 1;
468          char            *origIDF, *revIDF;
469 <        IDF_PARAMETER   *pptr;
469 >        IDF_OBJECT      *pptr;
470          int             i;
471  
472 <        progname = argv[0];
473 <        if (argc > 2 && !strcmp(argv[1], "-c")) {
474 <                incl_comments = -1;             /* output header only */
475 <                ++argv; --argc;
476 <        }
477 <        if ((argc < 2) | (argc > 3)) {
478 <                fputs("Usage: ", stderr);
479 <                fputs(progname, stderr);
480 <                fputs(" [-c] Model.idf [Revised.idf]\n", stderr);
481 <                return(1);
482 <        }
483 <        origIDF = argv[1];
484 <        revIDF = (argc == 2) ? argv[1] : argv[2];
472 >        progname = *argv++; argc--;             /* get options if any */
473 >        while (argc > 1 && argv[0][0] == '-')
474 >                switch (argv[0][1]) {
475 >                case 'c':                       /* elide comments */
476 >                        incl_comments = -1;             /* header only */
477 >                        argv++; argc--;
478 >                        continue;
479 >                case 's':                       /* samples */
480 >                        nsamps = 1000*atoi(*++argv);
481 >                        argv++; argc -= 2;
482 >                        continue;
483 >                default:
484 >                        fputs(progname, stderr);
485 >                        fputs(": unknown option '", stderr);
486 >                        fputs(argv[0], stderr);
487 >                        fputs("'\n", stderr);
488 >                        goto userr;
489 >                }
490 >        if ((argc < 1) | (argc > 2))
491 >                goto userr;
492 >        origIDF = argv[0];
493 >        revIDF = (argc == 1) ? argv[0] : argv[1];
494                                                  /* load Input Data File */
495          our_idf = idf_load(origIDF);
496          if (our_idf == NULL) {
# Line 487 | Line 501 | main(int argc, char *argv[])
501                  return(1);
502          }
503                                                  /* remove existing UVFs */
504 <        if ((pptr = idf_getparam(our_idf, UVF_PNAME)) != NULL) {
505 <                IDF_PARAMETER   *pnext;
504 >        if ((pptr = idf_getobject(our_idf, UVF_PNAME)) != NULL) {
505 >                IDF_OBJECT      *pnext;
506                  fputs(progname, stderr);
507                  fputs(": removing previous User View Factors\n", stderr);
508                  do {
509                          pnext = pptr->pnext;
510 <                        idf_delparam(our_idf, pptr);
510 >                        idf_delobject(our_idf, pptr);
511                  } while (pnext != NULL);
512          }
513                                                  /* add to header */
# Line 503 | Line 517 | main(int argc, char *argv[])
517                  idf_add2hdr(our_idf, ADD_HEADER);
518                                                  /* gather zone surfaces */
519          for (i = 0; surf_type[i].pname != NULL; i++)
520 <                for (pptr = idf_getparam(our_idf, surf_type[i].pname);
520 >                for (pptr = idf_getobject(our_idf, surf_type[i].pname);
521                                  pptr != NULL; pptr = pptr->pnext) {
522                          IDF_FIELD       *fptr = idf_getfield(pptr,
523                                                          surf_type[i].zone_fld);
# Line 527 | Line 541 | main(int argc, char *argv[])
541                  return(1);
542          }
543          return(0);                              /* finito! */
544 + userr:
545 +        fputs("Usage: ", stderr);
546 +        fputs(progname, stderr);
547 +        fputs(" [-c][-s Ksamps] Model.idf [Revised.idf]\n", stderr);
548 +        return(1);
549   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines