ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/obj2mesh.c
Revision: 2.13
Committed: Wed Nov 12 03:54:31 2008 UTC (16 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R2P2, rad5R0, rad4R2, rad4R1, rad4R0, rad4R2P1
Changes since 2.12: +2 -1 lines
Log Message:
Fixes for Visual Studio compilation

File Contents

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