ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/obj2mesh.c
Revision: 2.12
Committed: Thu Jul 12 14:58:53 2007 UTC (16 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R9
Changes since 2.11: +2 -2 lines
Log Message:
Decreased default -n setting in obj2mesh from 15 to 9

File Contents

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