ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/obj2mesh.c
Revision: 2.7
Committed: Mon Jul 14 05:00:45 2003 UTC (20 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.6: +4 -1 lines
Log Message:
Added better command-line argument checking

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.7 static const char RCSid[] = "$Id: obj2mesh.c,v 2.6 2003/06/08 12:03:10 schorsch Exp $";
3 greg 2.1 #endif
4     /*
5     * Main program to compile a Wavefront .OBJ file into a Radiance mesh
6     */
7    
8     #include "copyright.h"
9 schorsch 2.6 #include "platform.h"
10 greg 2.1 #include "standard.h"
11     #include "cvmesh.h"
12     #include "otypes.h"
13    
14     extern int o_face();
15    
16     int o_default() { return(O_MISS); }
17    
18     FUN ofun[NUMOTYPE] = INIT_OTYPE; /* needed for link resolution */
19    
20     char *progname; /* argv[0] */
21    
22     int nowarn = 0; /* supress warnings? */
23    
24     int objlim = 15; /* # of objects before split */
25    
26     int resolu = 16384; /* octree resolution limit */
27    
28     double mincusize; /* minimum cube size from resolu */
29    
30    
31     main(argc, argv) /* compile a .OBJ file into a mesh */
32     int argc;
33     char *argv[];
34     {
35 greg 2.3 int nmatf = 0;
36     char *matinp[32];
37     int i, j;
38 greg 2.1
39     progname = argv[0];
40     ofun[OBJ_FACE].funp = o_face;
41    
42     for (i = 1; i < argc && argv[i][0] == '-'; i++)
43     switch (argv[i][1]) {
44     case 'n': /* set limit */
45     objlim = atoi(argv[++i]);
46     break;
47     case 'r': /* resolution limit */
48     resolu = atoi(argv[++i]);
49     break;
50 greg 2.3 case 'a': /* material file */
51     matinp[nmatf++] = argv[++i];
52     break;
53 greg 2.1 case 'w': /* supress warnings */
54     nowarn = 1;
55     break;
56     default:
57     sprintf(errmsg, "unknown option: '%s'", argv[i]);
58     error(USER, errmsg);
59     break;
60     }
61 greg 2.7
62     if (i < argc-2)
63     error(USER, "too many file arguments");
64 greg 2.1 /* initialize mesh */
65     cvinit(i==argc-2 ? argv[i+1] : "<stdout>");
66 greg 2.3 /* load material input */
67     for (j = 0; j < nmatf; j++)
68     readobj(matinp[j]);
69     /* read .OBJ file into triangles */
70     if (i == argc)
71 greg 2.1 wfreadobj(NULL);
72     else
73     wfreadobj(argv[i]);
74    
75     cvmeshbounds(); /* set octree boundaries */
76    
77     if (i == argc-2) /* open output file */
78     if (freopen(argv[i+1], "w", stdout) == NULL)
79     error(SYSTEM, "cannot open output file");
80 schorsch 2.5 SET_FILE_BINARY(stdout);
81 greg 2.1 newheader("RADIANCE", stdout); /* new binary file header */
82     printargs(i<argc ? i+1 : argc, argv, stdout);
83     fputformat(MESHFMT, stdout);
84     fputc('\n', stdout);
85    
86     mincusize = ourmesh->mcube.cusize / resolu - FTINY;
87    
88     for (i = 0; i < nobjects; i++) /* add triangles to octree */
89 greg 2.3 if (objptr(i)->otype == OBJ_FACE)
90     addface(&ourmesh->mcube, i);
91 greg 2.1
92     /* optimize octree */
93     ourmesh->mcube.cutree = combine(ourmesh->mcube.cutree);
94    
95     if (ourmesh->mcube.cutree == EMPTY)
96     error(WARNING, "mesh is empty");
97    
98     cvmesh(); /* convert mesh and leaf nodes */
99    
100     writemesh(ourmesh, stdout); /* write mesh to output */
101    
102 greg 2.4 /* printmeshstats(ourmesh, stderr); */
103 greg 2.1
104     quit(0);
105     }
106    
107    
108     void
109     quit(code) /* exit program */
110     int code;
111     {
112     exit(code);
113     }
114    
115    
116     void
117     cputs() /* interactive error */
118     {
119     /* referenced, but not used */
120     }
121    
122    
123     void
124     wputs(s) /* warning message */
125     char *s;
126     {
127     if (!nowarn)
128     eputs(s);
129     }
130    
131    
132     void
133     eputs(s) /* put string to stderr */
134     register char *s;
135     {
136     static int inln = 0;
137    
138     if (!inln++) {
139     fputs(progname, stderr);
140     fputs(": ", stderr);
141     }
142     fputs(s, stderr);
143     if (*s && s[strlen(s)-1] == '\n')
144     inln = 0;
145     }
146    
147    
148     addface(cu, obj) /* add a face to a cube */
149     register CUBE *cu;
150     OBJECT obj;
151     {
152    
153     if (o_face(objptr(obj), cu) == O_MISS)
154     return;
155    
156     if (istree(cu->cutree)) {
157 greg 2.2 CUBE cukid; /* do children */
158     int i, j;
159 greg 2.1 cukid.cusize = cu->cusize * 0.5;
160     for (i = 0; i < 8; i++) {
161     cukid.cutree = octkid(cu->cutree, i);
162     for (j = 0; j < 3; j++) {
163     cukid.cuorg[j] = cu->cuorg[j];
164     if ((1<<j) & i)
165     cukid.cuorg[j] += cukid.cusize;
166     }
167     addface(&cukid, obj);
168     octkid(cu->cutree, i) = cukid.cutree;
169     }
170     return;
171     }
172     if (isempty(cu->cutree)) {
173 greg 2.2 OBJECT oset[2]; /* singular set */
174 greg 2.1 oset[0] = 1; oset[1] = obj;
175     cu->cutree = fullnode(oset);
176     return;
177     }
178     /* add to full node */
179 greg 2.2 add2full(cu, obj);
180     }
181    
182    
183     add2full(cu, obj) /* add object to full node */
184     register CUBE *cu;
185     OBJECT obj;
186     {
187     OCTREE ot;
188     OBJECT oset[MAXSET+1];
189     CUBE cukid;
190     register int i, j;
191    
192 greg 2.1 objset(oset, cu->cutree);
193     cukid.cusize = cu->cusize * 0.5;
194    
195     if (oset[0] < objlim || cukid.cusize < mincusize) {
196     /* add to set */
197     if (oset[0] >= MAXSET) {
198 greg 2.2 sprintf(errmsg, "set overflow in addobject (%s)",
199 greg 2.1 objptr(obj)->oname);
200     error(INTERNAL, errmsg);
201     }
202     insertelem(oset, obj);
203     cu->cutree = fullnode(oset);
204     return;
205     }
206     /* subdivide cube */
207     if ((ot = octalloc()) == EMPTY)
208     error(SYSTEM, "out of octree space");
209     /* assign subcubes */
210     for (i = 0; i < 8; i++) {
211     cukid.cutree = EMPTY;
212     for (j = 0; j < 3; j++) {
213     cukid.cuorg[j] = cu->cuorg[j];
214     if ((1<<j) & i)
215     cukid.cuorg[j] += cukid.cusize;
216     }
217     for (j = 1; j <= oset[0]; j++)
218     addface(&cukid, oset[j]);
219     addface(&cukid, obj);
220     /* returned node */
221     octkid(ot, i) = cukid.cutree;
222     }
223     cu->cutree = ot;
224     }