ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/obj2mesh.c
Revision: 2.11
Committed: Fri Apr 23 00:56:27 2004 UTC (20 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R7P2, rad3R7P1, rad3R6, rad3R6P1, rad3R8
Changes since 2.10: +16 -1 lines
Log Message:
Added -l option to search RAYPATH library locations for material file

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.10 static const char RCSid[] = "$Id: obj2mesh.c,v 2.9 2004/04/22 17:33:48 greg Exp $";
3 greg 2.1 #endif
4     /*
5     * Main program to compile a Wavefront .OBJ file into a Radiance mesh
6     */
7    
8     #include "copyright.h"
9 schorsch 2.6 #include "platform.h"
10 greg 2.1 #include "standard.h"
11 schorsch 2.8 #include "resolu.h"
12 greg 2.1 #include "cvmesh.h"
13     #include "otypes.h"
14    
15 schorsch 2.8 extern int o_face(); /* XXX should go to a header file */
16 greg 2.1
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 = 15; /* # of objects before split */
26    
27     int resolu = 16384; /* octree resolution limit */
28    
29     double mincusize; /* minimum cube size from resolu */
30    
31 schorsch 2.8 static void addface(CUBE *cu, OBJECT obj);
32     static void add2full(CUBE *cu, OBJECT obj);
33 greg 2.1
34 schorsch 2.8
35     int
36     main( /* compile a .OBJ file into a mesh */
37     int argc,
38     char *argv[]
39     )
40 greg 2.1 {
41 greg 2.3 int nmatf = 0;
42 greg 2.11 char pathnames[12800];
43     char *pns = pathnames;
44     char *matinp[128];
45     char *cp;
46 greg 2.3 int i, j;
47 greg 2.1
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 greg 2.3 case 'a': /* material file */
60     matinp[nmatf++] = argv[++i];
61     break;
62 greg 2.11 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 greg 2.1 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 greg 2.7
83     if (i < argc-2)
84     error(USER, "too many file arguments");
85 greg 2.1 /* initialize mesh */
86     cvinit(i==argc-2 ? argv[i+1] : "<stdout>");
87 greg 2.3 /* 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 greg 2.1 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 schorsch 2.5 SET_FILE_BINARY(stdout);
102 greg 2.1 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 greg 2.3 if (objptr(i)->otype == OBJ_FACE)
111     addface(&ourmesh->mcube, i);
112 greg 2.1
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 greg 2.4 /* printmeshstats(ourmesh, stderr); */
124 greg 2.1
125     quit(0);
126 schorsch 2.8 return 0; /* pro forma return */
127 greg 2.1 }
128    
129    
130     void
131 schorsch 2.8 quit( /* exit program */
132     int code
133     )
134 greg 2.1 {
135     exit(code);
136     }
137    
138    
139     void
140 schorsch 2.8 cputs(void) /* interactive error */
141 greg 2.1 {
142     /* referenced, but not used */
143     }
144    
145    
146     void
147 schorsch 2.8 wputs( /* warning message */
148     char *s
149     )
150 greg 2.1 {
151     if (!nowarn)
152     eputs(s);
153     }
154    
155    
156     void
157 schorsch 2.8 eputs( /* put string to stderr */
158     register char *s
159     )
160 greg 2.1 {
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 schorsch 2.8 static void
174     addface( /* add a face to a cube */
175     register CUBE *cu,
176     OBJECT obj
177     )
178 greg 2.1 {
179    
180     if (o_face(objptr(obj), cu) == O_MISS)
181     return;
182    
183     if (istree(cu->cutree)) {
184 greg 2.2 CUBE cukid; /* do children */
185     int i, j;
186 greg 2.1 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 greg 2.2 OBJECT oset[2]; /* singular set */
201 greg 2.1 oset[0] = 1; oset[1] = obj;
202     cu->cutree = fullnode(oset);
203     return;
204     }
205     /* add to full node */
206 greg 2.2 add2full(cu, obj);
207     }
208    
209    
210 schorsch 2.8 static void
211     add2full( /* add object to full node */
212     register CUBE *cu,
213     OBJECT obj
214     )
215 greg 2.2 {
216     OCTREE ot;
217     OBJECT oset[MAXSET+1];
218     CUBE cukid;
219     register int i, j;
220    
221 greg 2.1 objset(oset, cu->cutree);
222     cukid.cusize = cu->cusize * 0.5;
223    
224 greg 2.10 if (oset[0] < objlim || cukid.cusize <
225 greg 2.9 (oset[0] < MAXSET ? mincusize : mincusize/256.0)) {
226 greg 2.1 /* add to set */
227     if (oset[0] >= MAXSET) {
228 greg 2.2 sprintf(errmsg, "set overflow in addobject (%s)",
229 greg 2.1 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     }