ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/obj2mesh.c
Revision: 2.2
Committed: Wed Mar 12 04:59:04 2003 UTC (21 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +17 -7 lines
Log Message:
Numerous bug fixes in new mesh code

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