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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: obj2mesh.c,v 2.6 2003/06/08 12:03:10 schorsch Exp $";
3 #endif
4 /*
5 * Main program to compile a Wavefront .OBJ file into a Radiance mesh
6 */
7
8 #include "copyright.h"
9 #include "platform.h"
10 #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 int nmatf = 0;
36 char *matinp[32];
37 int i, j;
38
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 case 'a': /* material file */
51 matinp[nmatf++] = argv[++i];
52 break;
53 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
62 if (i < argc-2)
63 error(USER, "too many file arguments");
64 /* initialize mesh */
65 cvinit(i==argc-2 ? argv[i+1] : "<stdout>");
66 /* 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 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 SET_FILE_BINARY(stdout);
81 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 if (objptr(i)->otype == OBJ_FACE)
90 addface(&ourmesh->mcube, i);
91
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 /* printmeshstats(ourmesh, stderr); */
103
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 CUBE cukid; /* do children */
158 int i, j;
159 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 OBJECT oset[2]; /* singular set */
174 oset[0] = 1; oset[1] = obj;
175 cu->cutree = fullnode(oset);
176 return;
177 }
178 /* add to full node */
179 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 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 sprintf(errmsg, "set overflow in addobject (%s)",
199 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 }