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

# User Rev Content
1 greg 2.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 greg 2.2 CUBE cukid; /* do children */
147     int i, j;
148 greg 2.1 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 greg 2.2 OBJECT oset[2]; /* singular set */
163 greg 2.1 oset[0] = 1; oset[1] = obj;
164     cu->cutree = fullnode(oset);
165     return;
166     }
167     /* add to full node */
168 greg 2.2 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 greg 2.1 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 greg 2.2 sprintf(errmsg, "set overflow in addobject (%s)",
188 greg 2.1 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     }