ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/genbox.c
(Generate patch)

Comparing ray/src/gen/genbox.c (file contents):
Revision 2.7 by schorsch, Sun Nov 16 10:29:38 2003 UTC vs.
Revision 2.12 by greg, Fri Apr 9 18:52:57 2021 UTC

# Line 7 | Line 7 | static const char      RCSid[] = "$Id$";
7   *     1/8/86
8   */
9  
10 < #include  <stdio.h>
10 > #include  "rtio.h"
11 > #include  "rtmath.h"
12 > #include  "objutil.h"
13 > #include  <stdlib.h>
14  
12 #include <stdlib.h>
15  
16 < #include  <math.h>
16 > char    *progname;
17  
18 + int     verbose = 0;
19  
20   char  let[]="0123456789._ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
21  
22 < char  *cmtype;          /* ppd material type */
22 > char    *cmtype;                /* ppd material type */
23  
24 < char  *cname;           /* ppd name */
24 > char    *cname;         /* ppd name */
25  
26 < double  size[3];        /* ppd size */
26 > double  size[3];        /* ppd size */
27  
28 < double  bevel = 0.0;    /* bevel amount */
28 > int     rounde = 0;     /* round edges? (#segments = 2^rounde) */
29  
30 < int  rounde = 0;                /* boolean true for rounde edges */
30 > double  bevel = 0.0;    /* bevel amount or round edge radius */
31  
32 < int  reverse = 0;       /* boolean true for reversed normals */
32 > int     rev = 0;        /* boolean true for reversed normals */
33  
34 + Scene   *obj = NULL;    /* save as .OBJ scene if not NULL */
35  
36 + int     vid[0100];      /* vertex ID's for .OBJ scene */
37  
38 +
39 + static int
40 + overtex(int v)                                  /* index a .OBJ vertex */
41 + {
42 +        double  vpos[3];
43 +        int     i;
44 +
45 +        if (vid[v] >= 0)                        /* already have this vertex? */
46 +                return(vid[v]);
47 +                                                /* else create new ID */
48 +        for (i = 0; i < 3; i++)
49 +                if (v>>i & 010)
50 +                        vpos[i] = (v>>i & 01)^rev ? size[i]-bevel : bevel;
51 +                else
52 +                        vpos[i] = (v>>i & 01)^rev ? size[i] : 0.0;
53 +
54 +        return(vid[v] = addVertex(obj, vpos[0], vpos[1], vpos[2]));
55 + }
56 +
57 +
58 + static int
59 + onormal(int vid1, int vid2, int vid3)           /* index a .OBJ normal */
60 + {
61 +        double  *p1 = obj->vert[vid1].p;
62 +        double  *p2 = obj->vert[vid2].p;
63 +        double  *p3 = obj->vert[vid3].p;
64 +        FVECT   sv1, sv2, nrm;
65 +
66 +        VSUB(sv1, p2, p1);
67 +        VSUB(sv2, p3, p2);
68 +        VCROSS(nrm, sv1, sv2);
69 +
70 +        return(addNormal(obj, nrm[0], nrm[1], nrm[2]));
71 + }
72 +
73 +
74   static void
75 < vertex(v)
35 < register int  v;
75 > vertex(int v)                                   /* print a Radiance vertex */
76   {
77 <        register int  i;
77 >        int  i;
78  
79          for (i = 0; i < 3; i++) {
80                  if (v & 010)
81 <                        printf("\t%18.12g", v & 01 ? size[i]-bevel : bevel);
81 >                        printf("\t%18.12g", (v&01)^rev ? size[i]-bevel : bevel);
82                  else
83 <                        printf("\t%18.12g", v & 01 ? size[i] : 0.0);
83 >                        printf("\t%18.12g", (v&01)^rev ? size[i] : 0.0);
84                  v >>= 1;
85          }
86 <        printf("\n");
86 >        fputc('\n', stdout);
87   }
88  
89  
90   static void
91 < side(a, b, c, d)                /* generate a rectangular face */
52 < int  a, b, c, d;
91 > side(int a, int b, int c, int d)                /* generate a rectangular face */
92   {
93 +        if (obj != NULL) {                      /* working on .OBJ? */
94 +                VNDX    quadv[4];
95 +                memset(quadv, 0xff, sizeof(quadv));
96 +                quadv[0][0] = overtex(a);
97 +                quadv[1][0] = overtex(b);
98 +                quadv[2][0] = overtex(c);
99 +                quadv[3][0] = overtex(d);
100 +                if (rounde)                     /* add normal if rounded */
101 +                        quadv[0][2] = quadv[1][2] = quadv[2][2] = quadv[3][2]
102 +                                = onormal(quadv[0][0], quadv[1][0], quadv[2][0]);
103 +                addFace(obj, quadv, 4);
104 +                return;
105 +        }
106 +                                                /* Radiance output */
107          printf("\n%s polygon %s.%c%c%c%c\n", cmtype, cname,
108                          let[a], let[b], let[c], let[d]);
109          printf("0\n0\n12\n");
110 <        if (reverse) {
111 <                vertex(d);
112 <                vertex(c);
113 <                vertex(b);
61 <                vertex(a);
62 <        } else {
63 <                vertex(a);
64 <                vertex(b);
65 <                vertex(c);
66 <                vertex(d);
67 <        }
110 >        vertex(a);
111 >        vertex(b);
112 >        vertex(c);
113 >        vertex(d);
114   }
115  
116  
117   static void
118 < corner(a, b, c)                 /* generate a triangular face */
73 < int  a, b, c;
118 > corner(int a, int b, int c)                     /* generate a triangular face */
119   {
120 +        if (obj != NULL) {                      /* working on .OBJ? */
121 +                VNDX    triv[3];
122 +                memset(triv, 0xff, sizeof(triv));
123 +                triv[0][0] = overtex(a);
124 +                triv[1][0] = overtex(b);
125 +                triv[2][0] = overtex(c);
126 +                addFace(obj, triv, 3);
127 +                return;
128 +        }
129 +                                                /* Radiance output */
130          printf("\n%s polygon %s.%c%c%c\n", cmtype, cname,
131                          let[a], let[b], let[c]);
132          printf("0\n0\n9\n");
133 <        if (reverse) {
134 <                vertex(c);
135 <                vertex(b);
81 <                vertex(a);
82 <        } else {
83 <                vertex(a);
84 <                vertex(b);
85 <                vertex(c);
86 <        }
133 >        vertex(a);
134 >        vertex(b);
135 >        vertex(c);
136   }
137  
138  
139   static void
140 < cylinder(v0, v1)                /* generate a cylinder */
92 < int  v0, v1;
140 > cylinder(int v0, int v1)                        /* generate a rounded edge */
141   {
142 <        printf("\n%s cylinder %s.%c%c\n", cmtype, cname, v0+'0', v1+'0');
142 >        if (obj != NULL) {                      /* segmenting for .OBJ? */
143 >                const int       nsgn = 1 - 2*rev;
144 >                const int       nseg = 1<<rounde;
145 >                const double    astep = 0.5*PI/(double)nseg;
146 >                const int       vid0 = overtex(v0);
147 >                const int       vid1 = overtex(v1);
148 >                FVECT           p0, p1;
149 >                FVECT           axis[2], voff;
150 >                int             previd[2];
151 >                int             prenid;
152 >                VNDX            quadv[4];
153 >                double          coef[2];
154 >                int             i, j;
155 >                                                /* need to copy b/c realloc */
156 >                VCOPY(p0, obj->vert[vid0].p);
157 >                VCOPY(p1, obj->vert[vid1].p);
158 >
159 >                memset(axis, 0, sizeof(axis));
160 >
161 >                switch ((v0 ^ v1) & 07) {
162 >                case 01:                        /* edge along X-axis */
163 >                        axis[1][1] = bevel*(1. - 2.*(p1[1] < .5*size[1]));
164 >                        axis[0][2] = bevel*(1. - 2.*(p1[2] < .5*size[2]));
165 >                        break;
166 >                case 02:                        /* edge along Y-axis */
167 >                        axis[0][0] = bevel*(1. - 2.*(p1[0] < .5*size[0]));
168 >                        axis[1][2] = bevel*(1. - 2.*(p1[2] < .5*size[2]));
169 >                        break;
170 >                case 04:                        /* edge along Z-axis */
171 >                        axis[0][1] = bevel*(1. - 2.*(p1[1] < .5*size[1]));
172 >                        axis[1][0] = bevel*(1. - 2.*(p1[0] < .5*size[0]));
173 >                        break;
174 >                }
175 >                previd[0] = addVertex(obj, p0[0]+axis[0][0],
176 >                                        p0[1]+axis[0][1], p0[2]+axis[0][2]);
177 >                previd[1] = addVertex(obj, p1[0]+axis[0][0],
178 >                                        p1[1]+axis[0][1], p1[2]+axis[0][2]);
179 >                prenid = addNormal(obj, axis[0][0]*nsgn,
180 >                                        axis[0][1]*nsgn, axis[0][2]*nsgn);
181 >                for (i = 1; i <= nseg; i++) {
182 >                        memset(quadv, 0xff, sizeof(quadv));
183 >                        quadv[0][0] = previd[0];
184 >                        quadv[1][0] = previd[1];
185 >                        quadv[0][2] = quadv[1][2] = prenid;
186 >                        coef[0] = cos(astep*i);
187 >                        coef[1] = sin(astep*i);
188 >                        for (j = 0; j < 3; j++)
189 >                                voff[j] = coef[0]*axis[0][j] + coef[1]*axis[1][j];
190 >                        previd[0] = quadv[3][0]
191 >                                = addVertex(obj, p0[0]+voff[0],
192 >                                                p0[1]+voff[1], p0[2]+voff[2]);
193 >                        previd[1] = quadv[2][0]
194 >                                = addVertex(obj, p1[0]+voff[0],
195 >                                                p1[1]+voff[1], p1[2]+voff[2]);
196 >                        prenid = quadv[2][2] = quadv[3][2]
197 >                                = addNormal(obj, voff[0]*nsgn,
198 >                                                voff[1]*nsgn, voff[2]*nsgn);
199 >                        addFace(obj, quadv, 4);
200 >                }
201 >                return;
202 >        }
203 >                                                /* Radiance output */
204 >        printf("\n%s cylinder %s.%c%c\n", cmtype, cname, let[v0], let[v1]);
205          printf("0\n0\n7\n");
206          vertex(v0);
207          vertex(v1);
# Line 99 | Line 209 | int  v0, v1;
209   }
210  
211  
212 < static void
213 < sphere(v0)                      /* generate a sphere */
104 < int  v0;
212 > static void                                     /* recursive corner subdivision */
213 > osubcorner(const FVECT orig, const FVECT c0, const FVECT c1, const FVECT c2, int lvl)
214   {
215 <        printf("\n%s sphere %s.%c\n", cmtype, cname, v0+'0');
216 <        printf("0\n0\n4\n");
217 <        vertex(v0);
218 <        printf("\t%18.12g\n", bevel);
215 >        if (lvl-- <= 0) {                       /* reached terminal depth? */
216 >                const int       nsgn = 1 - 2*rev;
217 >                FVECT           vpos;
218 >                VNDX            triv[3];        /* output smoothed triangle */
219 >                VSUM(vpos, orig, c0, bevel);
220 >                triv[0][0] = addVertex(obj, vpos[0], vpos[1], vpos[2]);
221 >                triv[0][2] = addNormal(obj, c0[0]*nsgn, c0[1]*nsgn, c0[2]*nsgn);
222 >                VSUM(vpos, orig, c1, bevel);
223 >                triv[1][0] = addVertex(obj, vpos[0], vpos[1], vpos[2]);
224 >                triv[1][2] = addNormal(obj, c1[0]*nsgn, c1[1]*nsgn, c1[2]*nsgn);
225 >                VSUM(vpos, orig, c2, bevel);
226 >                triv[2][0] = addVertex(obj, vpos[0], vpos[1], vpos[2]);
227 >                triv[2][2] = addNormal(obj, c2[0]*nsgn, c2[1]*nsgn, c2[2]*nsgn);
228 >                triv[0][1] = triv[1][1] = triv[2][1] = -1;
229 >                addFace(obj, triv, 3);
230 >        } else {                                /* else subdivide 4 subcorners */
231 >                FVECT   m01, m12, m20;
232 >                VADD(m01, c0, c1); normalize(m01);
233 >                VADD(m12, c1, c2); normalize(m12);
234 >                VADD(m20, c2, c0); normalize(m20);
235 >                osubcorner(orig, c0, m01, m20, lvl);
236 >                osubcorner(orig, c1, m12, m01, lvl);
237 >                osubcorner(orig, c2, m20, m12, lvl);
238 >                osubcorner(orig, m01, m12, m20, lvl);
239 >        }
240   }
241  
242  
243   static void
244 < printhead(ac, av)               /* print command header */
115 < register int  ac;
116 < register char  **av;
244 > sphere(int v0)                                  /* generate a rounded corner */
245   {
246 <        putchar('#');
247 <        while (ac--) {
248 <                putchar(' ');
249 <                fputs(*av++, stdout);
246 >        if (obj != NULL) {                      /* segmenting for .OBJ? */
247 >                FVECT   orig, cdir[3];
248 >                int     i;
249 >                memset(cdir, 0, sizeof(cdir));
250 >                for (i = 0; i < 3; i++)
251 >                        cdir[i][i] = 2*((v0>>i & 01)^rev) - 1;
252 >                switch (v0 & 07) {
253 >                        case 0:
254 >                        case 3:
255 >                        case 5:
256 >                        case 6:
257 >                                VCOPY(orig, cdir[0]);
258 >                                VCOPY(cdir[0], cdir[1]);
259 >                                VCOPY(cdir[1], orig);
260 >                }
261 >                i = overtex(v0);
262 >                VCOPY(orig, obj->vert[i].p);    /* realloc remedy */
263 >                osubcorner(orig, cdir[0], cdir[1], cdir[2], rounde);
264 >                return;
265          }
266 <        putchar('\n');
266 >                                                /* Radiance output */
267 >        printf("\n%s sphere %s.%c\n", cmtype, cname, let[v0]);
268 >        printf("0\n0\n4\n");
269 >        vertex(v0);
270 >        printf("\t%18.12g\n", bevel);
271   }
272  
273  
274   int
275 < main(argc, argv)
129 < int  argc;
130 < char  **argv;
275 > main(int argc, char *argv[])
276   {
277 +        int  nsegs = 1;
278 +        int  objout = 0;
279          int  i;
280 <        
280 >
281 >        progname = argv[0];
282 >
283          if (argc < 6)
284                  goto userr;
285  
# Line 139 | Line 288 | char  **argv;
288          size[0] = atof(argv[3]);
289          size[1] = atof(argv[4]);
290          size[2] = atof(argv[5]);
291 +        if ((size[0] <= 0.0) | (size[1] <= 0.0) | (size[2] <= 0.0))
292 +                goto userr;
293  
294          for (i = 6; i < argc; i++) {
295                  if (argv[i][0] != '-')
296                          goto userr;
297                  switch (argv[i][1]) {
298 <                case 'r':
298 >                case 'o':                       /* requesting .OBJ output */
299 >                        objout = 1;
300 >                        break;
301 >                case 'i':                       /* invert surface normals */
302 >                        rev = 1;
303 >                        break;
304 >                case 'r':                       /* rounded edges/corners */
305                          rounde = 1;
306                          /* fall through */
307 <                case 'b':
307 >                case 'b':                       /* beveled edges */
308                          bevel = atof(argv[++i]);
309 +                        if (bevel <= 0.0)
310 +                                goto userr;
311                          break;
312 <                case 'i':
313 <                        reverse = 1;
312 >                case 'n':                       /* #segments for rounding */
313 >                        nsegs = atoi(argv[++i]);
314 >                        if (nsegs <= 0)
315 >                                goto userr;
316                          break;
317                  default:
318                          goto userr;
319                  }
320          }
321 +        if ((objout|rev) & (nsegs==1))          /* default to 32 segments/edge */
322 +                nsegs = 32;
323 +        if (rounde) {                           /* rounding edges/corners? */
324 +                --nsegs;
325 +                while ((nsegs >>= 1))           /* segmentation requested? */
326 +                        ++rounde;
327 +        }
328 +        if (rounde > 1 || objout) {             /* save as .OBJ scene? */
329 +                obj = newScene();
330 +                setMaterial(obj, cmtype);
331 +                setGroup(obj, cname);
332 +                memset(vid, 0xff, sizeof(vid));
333 +        }
334 +        fputs("# ", stdout);                    /* write command as comment */
335 +        printargs(argc, argv, stdout);
336  
337 <        printhead(argc, argv);
162 <
163 <        if (bevel > 0.0) {
164 <                                        /* minor faces */
337 >        if (bevel > 0.0) {                      /* minor faces */
338                  side(051, 055, 054, 050);
339                  side(064, 066, 062, 060);
340                  side(032, 033, 031, 030);
# Line 169 | Line 342 | char  **argv;
342                  side(065, 061, 063, 067);
343                  side(036, 034, 035, 037);
344          }
345 <        if (bevel > 0.0 && !rounde) {
173 <                                        /* bevel faces */
345 >        if (bevel > 0.0 && !rounde) {           /* bevel faces */
346                  side(031, 051, 050, 030);
347                  side(060, 062, 032, 030);
348                  side(050, 054, 064, 060);
# Line 183 | Line 355 | char  **argv;
355                  side(065, 067, 037, 035);
356                  side(055, 051, 061, 065);
357                  side(034, 054, 055, 035);
358 <                                        /* bevel corners */
358 >                                                /* bevel corners */
359                  corner(030, 050, 060);
360                  corner(051, 031, 061);
361                  corner(032, 062, 052);
# Line 193 | Line 365 | char  **argv;
365                  corner(053, 063, 033);
366                  corner(037, 067, 057);
367          }
368 <        if (bevel > 0.0 && rounde) {
197 <                                        /* rounde edges */
368 >        if (bevel > 0.0 && rounde) {            /* round edges */
369                  cylinder(070, 071);
370                  cylinder(070, 074);
371                  cylinder(070, 072);
# Line 207 | Line 378 | char  **argv;
378                  cylinder(076, 072);
379                  cylinder(076, 074);
380                  cylinder(076, 077);
381 <                                        /* rounde corners */
381 >                                                /* round corners */
382                  sphere(070);
383                  sphere(071);
384                  sphere(072);
# Line 217 | Line 388 | char  **argv;
388                  sphere(076);
389                  sphere(077);
390          }
391 <        if (bevel == 0.0 ) {
221 <                                        /* only need major faces */
391 >        if (bevel == 0.0) {                     /* only need major faces */
392                  side(1, 5, 4, 0);
393                  side(4, 6, 2, 0);
394                  side(2, 3, 1, 0);
# Line 226 | Line 396 | char  **argv;
396                  side(5, 1, 3, 7);
397                  side(6, 4, 5, 7);
398          }
399 <        exit(0);
399 >        if (obj != NULL) {                      /* need to write output? */
400 >                if (objout) {
401 >                        if (rounde)             /* joins corners to edges */
402 >                                coalesceVertices(obj, 2.*FTINY);
403 >                        if (toOBJ(obj, stdout) <= 0)
404 >                                return(1);
405 >                } else if (toRadiance(obj, stdout, 0, 0) <= 0)
406 >                        return(1);
407 >                /* freeScene(obj);      we're exiting, anyway... */
408 >        }
409 >        return(0);
410   userr:
411          fprintf(stderr, "Usage: %s ", argv[0]);
412          fprintf(stderr, "material name xsize ysize zsize ");
413 <        fprintf(stderr, "[-i] [-b bevel | -r rounde]\n");
414 <        exit(1);
413 >        fprintf(stderr, "[-i] [-b bevel | -r round [-n nsegs]] [-o]\n");
414 >        return(1);
415   }
236

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines