ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/obj2mesh.c
Revision: 2.3
Committed: Fri Mar 14 21:27:46 2003 UTC (21 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.2: +13 -4 lines
Log Message:
Added -a option to obj2mesh to incorporate materials in mesh

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id$";
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 #ifdef MSDOS
77 setmode(fileno(stdout), O_BINARY);
78 #endif
79 newheader("RADIANCE", stdout); /* new binary file header */
80 printargs(i<argc ? i+1 : argc, argv, stdout);
81 fputformat(MESHFMT, stdout);
82 fputc('\n', stdout);
83
84 mincusize = ourmesh->mcube.cusize / resolu - FTINY;
85
86 for (i = 0; i < nobjects; i++) /* add triangles to octree */
87 if (objptr(i)->otype == OBJ_FACE)
88 addface(&ourmesh->mcube, i);
89
90 /* optimize octree */
91 ourmesh->mcube.cutree = combine(ourmesh->mcube.cutree);
92
93 if (ourmesh->mcube.cutree == EMPTY)
94 error(WARNING, "mesh is empty");
95
96 cvmesh(); /* convert mesh and leaf nodes */
97
98 writemesh(ourmesh, stdout); /* write mesh to output */
99
100 printmeshstats(ourmesh, stderr);
101
102 quit(0);
103 }
104
105
106 void
107 quit(code) /* exit program */
108 int code;
109 {
110 exit(code);
111 }
112
113
114 void
115 cputs() /* interactive error */
116 {
117 /* referenced, but not used */
118 }
119
120
121 void
122 wputs(s) /* warning message */
123 char *s;
124 {
125 if (!nowarn)
126 eputs(s);
127 }
128
129
130 void
131 eputs(s) /* put string to stderr */
132 register char *s;
133 {
134 static int inln = 0;
135
136 if (!inln++) {
137 fputs(progname, stderr);
138 fputs(": ", stderr);
139 }
140 fputs(s, stderr);
141 if (*s && s[strlen(s)-1] == '\n')
142 inln = 0;
143 }
144
145
146 addface(cu, obj) /* add a face to a cube */
147 register CUBE *cu;
148 OBJECT obj;
149 {
150
151 if (o_face(objptr(obj), cu) == O_MISS)
152 return;
153
154 if (istree(cu->cutree)) {
155 CUBE cukid; /* do children */
156 int i, j;
157 cukid.cusize = cu->cusize * 0.5;
158 for (i = 0; i < 8; i++) {
159 cukid.cutree = octkid(cu->cutree, i);
160 for (j = 0; j < 3; j++) {
161 cukid.cuorg[j] = cu->cuorg[j];
162 if ((1<<j) & i)
163 cukid.cuorg[j] += cukid.cusize;
164 }
165 addface(&cukid, obj);
166 octkid(cu->cutree, i) = cukid.cutree;
167 }
168 return;
169 }
170 if (isempty(cu->cutree)) {
171 OBJECT oset[2]; /* singular set */
172 oset[0] = 1; oset[1] = obj;
173 cu->cutree = fullnode(oset);
174 return;
175 }
176 /* add to full node */
177 add2full(cu, obj);
178 }
179
180
181 add2full(cu, obj) /* add object to full node */
182 register CUBE *cu;
183 OBJECT obj;
184 {
185 OCTREE ot;
186 OBJECT oset[MAXSET+1];
187 CUBE cukid;
188 register int i, j;
189
190 objset(oset, cu->cutree);
191 cukid.cusize = cu->cusize * 0.5;
192
193 if (oset[0] < objlim || cukid.cusize < mincusize) {
194 /* add to set */
195 if (oset[0] >= MAXSET) {
196 sprintf(errmsg, "set overflow in addobject (%s)",
197 objptr(obj)->oname);
198 error(INTERNAL, errmsg);
199 }
200 insertelem(oset, obj);
201 cu->cutree = fullnode(oset);
202 return;
203 }
204 /* subdivide cube */
205 if ((ot = octalloc()) == EMPTY)
206 error(SYSTEM, "out of octree space");
207 /* assign subcubes */
208 for (i = 0; i < 8; i++) {
209 cukid.cutree = EMPTY;
210 for (j = 0; j < 3; j++) {
211 cukid.cuorg[j] = cu->cuorg[j];
212 if ((1<<j) & i)
213 cukid.cuorg[j] += cukid.cusize;
214 }
215 for (j = 1; j <= oset[0]; j++)
216 addface(&cukid, oset[j]);
217 addface(&cukid, obj);
218 /* returned node */
219 octkid(ot, i) = cukid.cutree;
220 }
221 cu->cutree = ot;
222 }