ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/obj2mesh.c
Revision: 2.5
Committed: Thu Jun 5 19:29:34 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.4: +2 -4 lines
Log Message:
Macros for setting binary file mode. Replacing MSDOS by _WIN32.

File Contents

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