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

Comparing src/gen/genbox.c (file contents):
Revision 2.3 by greg, Fri Jun 4 14:29:58 1993 UTC vs.
Revision 2.15 by greg, Sat Jun 7 05:09:45 2025 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines