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

Comparing ray/src/util/wrapBSDF.c (file contents):
Revision 2.1 by greg, Wed Feb 11 18:08:10 2015 UTC vs.
Revision 2.3 by greg, Fri Feb 13 20:49:59 2015 UTC

# Line 2 | Line 2
2   static const char RCSid[] = "$Id$";
3   #endif
4   /*
5 < * Wrap BSDF data in valid WINDOW XML wrapper
5 > * Wrap BSDF data in valid WINDOW XML file
6   *
7 < *      G. Ward         January 2015
7 > *      G. Ward         February 2015
8   */
9  
10   #include <ctype.h>
# Line 15 | Line 15 | static const char RCSid[] = "$Id$";
15   #include "bsdf_m.h"
16                                          /* XML template file names */
17   const char      def_template[] = "minimalBSDFt.xml";
18 < const char      win6_template[] = "window6BSDFt.xml";
18 > const char      win6_template[] = "WINDOW6BSDFt.xml";
19  
20   const char      stdin_name[] = "<stdin>";
21  
22                                          /* input files (can be stdin_name) */
23   const char      *xml_input = NULL;
24                                          /* unit for materials & geometry */
25 < const char      *attr_unit = "millimeter";
25 > const char      *attr_unit = "meter";
26   const char      legal_units[] = "meter|foot|inch|centimeter|millimeter";
27                                          /* system materials & geometry */
28   const char      *mgf_geometry = NULL;
# Line 36 | Line 36 | int            angle_basis = ABdefault;
36                                          /* field IDs and nicknames */
37   struct s_fieldID {
38          char            nickName[4];
39 <        int             has_unit;
39 >        short           has_unit;
40 >        short           win_need;
41          const char      *fullName;
42   } XMLfieldID[] = {
43 <        {"m", 0, "Manufacturer"},
44 <        {"n", 0, "Name"},
45 <        {"c", 0, "ThermalConductivity"},
46 <        {"ef", 0, "EmissivityFront"},
47 <        {"eb", 0, "EmissivityBack"},
48 <        {"tir", 0, "TIR"},
49 <        {"eo", 0, "EffectiveOpennessFraction"},
50 <        {"t", 1, "Thickness"},
51 <        {"h", 1, "Height"},
52 <        {"w", 1, "Width"},
53 <        {"\0", -1, NULL}        /* terminator */
43 >        {"m", 0, 1, "Manufacturer"},
44 >        {"n", 0, 1, "Name"},
45 >        {"c", 0, 0, "ThermalConductivity"},
46 >        {"ef", 0, 0, "EmissivityFront"},
47 >        {"eb", 0, 0, "EmissivityBack"},
48 >        {"tir", 0, 0, "TIR"},
49 >        {"eo", 0, 0, "EffectiveOpennessFraction"},
50 >        {"t", 1, 1, "Thickness"},
51 >        {"h", 1, 0, "Height"},
52 >        {"w", 1, 0, "Width"},
53 >        {"\0", 0, 0, NULL}      /* terminator */
54   };
55                                          /* field assignments */
56   #define MAXASSIGN       12
# Line 76 | Line 77 | const char     *spectr_file[MAXFILES]; /* custom spectral
77  
78   const char      top_level_name[] = "WindowElement";
79  
80 < static char     *basis_definition[] = {
80 > static char     basis_definition[][256] = {
81  
82          "\t\t<IncidentDataStructure>Columns</IncidentDataStructure>\n"
83          "\t\t<AngleBasis>\n"
# Line 130 | Line 131 | input2str(const char *inpspec)
131                  return "";
132          if (inpspec == stdin_name) {            /* read from stdin */
133                  fp = stdin;
134 <        } else if (*inpspec == '!') {           /* read from command */
134 >        } else if (inpspec[0] == '!') {         /* read from command */
135                  fp = popen(inpspec+1, "r");
136                  if (fp == NULL) {
137                          fprintf(stderr, "Cannot start process '%s'\n",
138 <                                        inpspec+1);
138 >                                        inpspec);
139                          return "";
140                  }
141          } else {                                /* else load file */
# Line 144 | Line 145 | input2str(const char *inpspec)
145                          return "";
146                  }
147                  len = lseek(fd, 0L, SEEK_END);
148 <                if (len < 0) {
149 <                        fprintf(stderr, "%s: seek error\n", inpspec);
148 >                if (len > 0) {
149 >                        lseek(fd, 0L, SEEK_SET);
150 >                        str = (char *)malloc(len+1);
151 >                        if (str == NULL) {
152 >                                close(fd);
153 >                                goto memerr;
154 >                        }
155 >                        if (read(fd, str, len) != len) {
156 >                                fprintf(stderr, "%s: read error\n", inpspec);
157 >                                free(str);
158 >                                close(fd);
159 >                                return "";
160 >                        }
161 >                        str[len] = '\0';
162                          close(fd);
163 <                        return "";
163 >                        return str;
164                  }
165 <                lseek(fd, 0L, SEEK_SET);
153 <                str = (char *)malloc(len+1);
154 <                if (str == NULL) {
155 <                        close(fd);
156 <                        goto memerr;
157 <                }
158 <                if (read(fd, str, len) != len) {
159 <                        fprintf(stderr, "%s: read error\n", inpspec);
160 <                        free(str);
161 <                        close(fd);
162 <                        return "";
163 <                }
164 <                str[len] = '\0';
165 <                close(fd);
166 <                return str;
165 >                fp = fdopen(fd, "r");           /* not a regular file */
166          }
167                                                  /* reading from stream */
168          str = (char *)malloc((len=8192)+1);
# Line 186 | Line 185 | input2str(const char *inpspec)
185                  if (str == NULL)
186                          goto memerr;
187          }
188 <        if (*inpspec != '!')
188 >        if (inpspec[0] != '!')
189                  fclose(fp);
190          else if (pclose(fp))
191 <                fprintf(stderr, "Error running command '%s'\n", inpspec+1);
191 >                fprintf(stderr, "Error running command '%s'\n", inpspec);
192          return str;
193   memerr:
194          fprintf(stderr, "%s: error allocating memory\n", inpspec);
195          if (fp != NULL)
196 <                (*inpspec == '!') ? pclose(fp) : fclose(fp);
196 >                (inpspec[0] == '!') ? pclose(fp) : fclose(fp);
197          return "";
198   }
199  
# Line 204 | Line 203 | mat_assignments(const char *caller, const char *fn, ez
203   {
204          int     i;
205  
207        if (!nfield_assign)
208                return 1;
206          wtl = ezxml_child(wtl, "Material");
207          if (wtl == NULL) {
208                  fprintf(stderr, "%s: missing <Material> tag\n", fn);
# Line 222 | Line 219 | mat_assignments(const char *caller, const char *fn, ez
219                                  ++fnext;
220                          if (!*fnext)
221                                  break;
222 <                        for (j = 0; (*fnext != '=') & !isspace(*fnext); ) {
222 >                        for (j = 0; *fnext != '=' && !isspace(*fnext); ) {
223                                  if (!*fnext | (*fnext == FASEP) |
224                                                  (j >= sizeof(sbuf)-1)) {
225                                          fprintf(stderr,
# Line 232 | Line 229 | mat_assignments(const char *caller, const char *fn, ez
229                                  }
230                                  sbuf[j++] = *fnext++;
231                          }
232 <                        sbuf[j] = '\0';         /* check nick-names */
232 >                        sbuf[j] = '\0';         /* check known field */
233                          for (j = 0; XMLfieldID[j].nickName[0]; j++)
234 <                                if (!strcasecmp(sbuf, XMLfieldID[j].nickName)) {
234 >                                if (!strcasecmp(sbuf, XMLfieldID[j].nickName) ||
235 >                                        !strcasecmp(sbuf, XMLfieldID[j].fullName)) {
236                                          strcpy(sbuf, XMLfieldID[j].fullName);
237                                          break;
238                                  }
239                                                  /* check if tag exists */
240                          fld = ezxml_child(wtl, sbuf);
241                          if (fld == NULL) {      /* otherwise, create one */
242 <                                fprintf(stderr, "%s: warning - adding tag <%s>\n",
243 <                                        fn, sbuf);
242 >                                if (!XMLfieldID[j].nickName[0])
243 >                                        fprintf(stderr,
244 >                                                "%s: warning - adding tag <%s>\n",
245 >                                                        fn, sbuf);
246                                  fld = ezxml_add_child_d(wtl, sbuf, strlen(wtl->txt));
247                          }
248                          if (XMLfieldID[j].has_unit)
249                                  ezxml_set_attr(fld, "unit", attr_unit);
250 +                        XMLfieldID[j].win_need = 0;
251                          while (isspace(*fnext))
252                                  ++fnext;
253                          if (*fnext++ != '=') {
# Line 255 | Line 256 | mat_assignments(const char *caller, const char *fn, ez
256                                                  caller, field_assignment[i]);
257                                  return 0;
258                          }
259 <                        for (j = 0; *fnext & (*fnext != FASEP); ) {
259 >                        for (j = 0; *fnext && *fnext != FASEP; ) {
260                                  if (j >= sizeof(sbuf)-1) {
261                                          fprintf(stderr,
262                                          "%s: field too long in '%s'\n",
# Line 269 | Line 270 | mat_assignments(const char *caller, const char *fn, ez
270                          fnext += (*fnext == FASEP);
271                  }
272          }
273 +                                        /* check required WINDOW settings */
274 +        if (xml_input == win6_template)
275 +            for (i = 0; XMLfieldID[i].nickName[0]; i++)
276 +                if (XMLfieldID[i].win_need &&
277 +                        !ezxml_txt(ezxml_child(wtl,XMLfieldID[i].fullName))[0]) {
278 +                        fprintf(stderr,
279 +                        "%s: missing required '%s' assignment for WINDOW <%s>\n",
280 +                                        caller, XMLfieldID[i].nickName,
281 +                                        XMLfieldID[i].fullName);
282 +                        return 0;
283 +                }
284          return 1;               /* no errors */
285   }
286  
# Line 433 | Line 445 | writeBSDFblock(const char *caller, struct s_dfile *df)
445          fflush(stdout);
446          if (df->fname == stdin_name) {
447                  copy_and_close(fileno(stdin));
448 <        } else if (*df->fname != '!') {
448 >        } else if (df->fname[0] != '!') {
449                  if (!copy_and_close(open(df->fname, O_RDONLY))) {
450                          fprintf(stderr, "%s: error reading from '%s'\n",
451                                          caller, df->fname);
452                          return 0;
453                  }
454          } else if (system(df->fname+1)) {
455 <                fprintf(stderr, "%s: error running '%s'\n", caller, df->fname+1);
455 >                fprintf(stderr, "%s: error running '%s'\n", caller, df->fname);
456                  return 0;
457          }
458          puts("\t\t\t</ScatteringData>");
# Line 453 | Line 465 | writeBSDFblock(const char *caller, struct s_dfile *df)
465   static int
466   writeBSDF(const char *caller, ezxml_t fl)
467   {
468 <        char    *xml = ezxml_toxml(fl);
468 >        char    *xml = ezxml_toxml(fl);         /* store XML in string */
469          int     ei, i;
470                                                  /* locate trailer */
471          for (ei = strlen(xml)-strlen("</Layer></Optical></WindowElement>");
# Line 477 | Line 489 | writeBSDF(const char *caller, ezxml_t fl)
489                          return 0;
490                  }
491          fputs(xml+ei, stdout);                  /* write trailer */
492 <        free(xml);
492 >        free(xml);                              /* free string */
493          return (fflush(stdout) == 0);
494   }
495  
# Line 485 | Line 497 | writeBSDF(const char *caller, ezxml_t fl)
497   static int
498   wrapBSDF(const char *caller)
499   {
500 <        const char      *xml_path = getpath((char *)xml_input, getrlibpath(), R_OK);
500 >        const char      *xml_path = xml_input;
501          ezxml_t         fl, wtl;
502                                          /* load previous XML/template */
503 <        if (xml_path == NULL) {
504 <                fprintf(stderr, "%s: cannot find XML file named '%s'\n",
505 <                                caller, xml_input==NULL ? "NULL" : xml_input);
506 <                return 0;
503 >        if (xml_input == stdin_name) {
504 >                fl = ezxml_parse_fp(stdin);
505 >        } else if (xml_input[0] == '!') {
506 >                FILE    *pfp = popen(xml_input+1, "r");
507 >                if (pfp == NULL) {
508 >                        fprintf(stderr, "%s: cannot start process '%s'\n",
509 >                                        caller, xml_input);
510 >                        return 0;
511 >                }
512 >                fl = ezxml_parse_fp(pfp);
513 >                if (pclose(pfp)) {
514 >                        fprintf(stderr, "%s: error running '%s'\n",
515 >                                        caller, xml_input);
516 >                        return 0;
517 >                }
518 >        } else {
519 >                xml_path = getpath((char *)xml_input, getrlibpath(), R_OK);
520 >                if (xml_path == NULL) {
521 >                        fprintf(stderr, "%s: cannot find XML file named '%s'\n",
522 >                                        caller, xml_input==NULL ? "NULL" : xml_input);
523 >                        return 0;
524 >                }
525 >                fl = ezxml_parse_file(xml_path);
526          }
496        fl = ezxml_parse_file(xml_path);
527          if (fl == NULL) {
528 <                fprintf(stderr, "%s: cannot open XML path '%s'\n",
499 <                                caller, xml_path);
528 >                fprintf(stderr, "%s: cannot load XML '%s'\n", caller, xml_path);
529                  return 0;
530          }
531          if (ezxml_error(fl)[0]) {
532 <                fprintf(stderr, "%s: error in XML %s: %s\n", caller, xml_path,
532 >                fprintf(stderr, "%s: error in XML '%s': %s\n", caller, xml_path,
533                                  ezxml_error(fl));
534                  goto failure;
535          }
# Line 522 | Line 551 | wrapBSDF(const char *caller)
551                  goto failure;
552          }
553                                          /* make material assignments */
554 <        if (!mat_assignments(caller, xml_path, wtl)) {
554 >        if (!mat_assignments(caller, xml_path, wtl))
555                  goto failure;
527        }
556          if (mgf_geometry != NULL) {     /* add geometry if specified */
557                  ezxml_t geom = ezxml_child(wtl, "Geometry");
558                  if (geom == NULL)
559 <                        geom = ezxml_add_child(wtl, "Geometry", 0);
559 >                        geom = ezxml_add_child(wtl, "Geometry", strlen(wtl->txt));
560                  ezxml_set_attr(geom, "format", "MGF");
561                  geom = ezxml_child(geom, "MGFblock");
562                  if (geom == NULL) {
563                          geom = ezxml_child(wtl, "Geometry");
564 <                        geom = ezxml_add_child(geom, "MGFblock", strlen(geom->txt));
564 >                        geom = ezxml_add_child(geom, "MGFblock", 0);
565                  }
566                  ezxml_set_attr(geom, "unit", attr_unit);
567                  ezxml_set_txt(geom, input2str(mgf_geometry));
# Line 544 | Line 572 | wrapBSDF(const char *caller)
572          if (angle_basis != ABdefault) {
573                  ezxml_t ab, dd = ezxml_child(wtl, "DataDefinition");
574                  if (dd == NULL) {
575 <                        dd = ezxml_add_child(wtl, "DataDefinition", 0);
576 <                } else {
577 <                        if (ezxml_child(dd, "DataDefinition") != NULL)
550 <                                fprintf(stderr,
575 >                        dd = ezxml_add_child(wtl, "DataDefinition", strlen(wtl->txt));
576 >                } else if (dd->child != NULL) {
577 >                        fprintf(stderr,
578                  "%s: warning - replacing existing <DataDefinition> in '%s'\n",
579                                                  caller, xml_path);
580 <                        while (dd->child != NULL)
580 >                        do
581                                  ezxml_remove(dd->child);
582 +                        while (dd->child != NULL);
583                  }
584                  ezxml_insert(ezxml_parse_str(basis_definition[angle_basis],
585                                          strlen(basis_definition[angle_basis])),
# Line 580 | Line 608 | UsageExit(const char *pname)
608   {
609          fputs("Usage: ", stderr);
610          fputs(pname, stderr);
611 <        fputs(" [options] [input.xml]\n", stderr);
611 >        fputs(" [-W][-a {kf|kh|kq|t3|t4}][-u unit][-g geom][-f 'x=string;y=string']", stderr);
612 >        fputs(" [-s spectr][-tb inp][-tf inp][-rb inp][-rf inp]", stderr);
613 >        fputs(" [input.xml]\n", stderr);
614          exit(1);
615   }
616  
# Line 617 | Line 647 | main(int argc, char *argv[])
647                                                  argv[0]);
648                                  return 1;
649                          }
650 <                        if (strstr(argv[i], legal_units) == NULL) {
651 <                                fprintf(stderr, "%s: unit must be one of (%s)\n",
650 >                        if (strstr(legal_units, argv[i]) == NULL) {
651 >                                fprintf(stderr, "%s: -u unit must be one of (%s)\n",
652                                                  argv[0], legal_units);
653                                  return 1;
654                          }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines