ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/obj2mesh.c
Revision: 2.17
Committed: Mon Feb 6 22:40:21 2023 UTC (14 months, 3 weeks ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, HEAD
Changes since 2.16: +6 -6 lines
Log Message:
refactor: Changed some char* args to const char* to avoid warnings

File Contents

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