ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/clumpbeams.c
Revision: 3.2
Committed: Tue Nov 10 18:05:41 1998 UTC (25 years, 5 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 3.1: +4 -27 lines
Log Message:
change clumpbeams() callback function to take clump's queue

File Contents

# User Rev Content
1 gwlarson 3.1 /* Copyright (c) 1998 Silicon Graphics, Inc. */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ SGI";
5     #endif
6    
7     /*
8     * Bundle holodeck beams together into clumps.
9     */
10    
11     #include "holo.h"
12    
13     #define flgop(p,i,op) ((p)[(i)>>5] op (1L<<((i)&0x1f)))
14     #define isset(p,i) flgop(p,i,&)
15     #define setfl(p,i) flgop(p,i,|=)
16     #define clrfl(p,i) flgop(p,i,&=~)
17    
18     static int bneighlist[9*9-1];
19     static int bneighrem;
20    
21     #define nextneigh() (bneighrem<=0 ? 0 : bneighlist[--bneighrem])
22    
23    
24     gcshifti(gc, ia, di, hp) /* shift cell row or column */
25     register GCOORD *gc;
26     int ia, di;
27     register HOLO *hp;
28     {
29     int nw;
30    
31     if (di > 0) {
32     if (++gc->i[ia] >= hp->grid[((gc->w>>1)+1+ia)%3]) {
33     nw = ((gc->w&~1) + (ia<<1) + 3) % 6;
34     gc->i[ia] = gc->i[1-ia];
35     gc->i[1-ia] = gc->w&1 ? hp->grid[((nw>>1)+2-ia)%3]-1 : 0;
36     gc->w = nw;
37     }
38     } else if (di < 0) {
39     if (--gc->i[ia] < 0) {
40     nw = ((gc->w&~1) + (ia<<1) + 2) % 6;
41     gc->i[ia] = gc->i[1-ia];
42     gc->i[1-ia] = gc->w&1 ? hp->grid[((nw>>1)+2-ia)%3]-1 : 0;
43     gc->w = nw;
44     }
45     }
46     }
47    
48    
49     mkneighgrid(ng, hp, gc) /* compute neighborhood for grid cell */
50     GCOORD ng[3*3];
51     HOLO *hp;
52     GCOORD *gc;
53     {
54     GCOORD gci0;
55     register int i, j;
56    
57     for (i = 3; i--; ) {
58     copystruct(&gci0, gc);
59     gcshifti(&gci0, 0, i-1, hp);
60     for (j = 3; j--; ) {
61     copystruct(ng+(3*i+j), &gci0);
62     gcshifti(ng+(3*i+j), gci0.w==gc->w, j-1, hp);
63     }
64     }
65     }
66    
67    
68     static int
69     firstneigh(hp, b) /* initialize neighbor list and return first */
70     HOLO *hp;
71     int b;
72     {
73     GCOORD wg0[9], wg1[9], bgc[2];
74     int i, j;
75    
76     hdbcoord(bgc, hp, b);
77     mkneighgrid(wg0, hp, bgc);
78     mkneighgrid(wg1, hp, bgc+1);
79     bneighrem = 0;
80     for (i = 9; i--; )
81     for (j = 9; j--; ) {
82     if (i == 4 & j == 4) /* don't copy starting beam */
83     continue;
84     if (wg0[i].w == wg1[j].w)
85     continue;
86     copystruct(bgc, wg0+i);
87     copystruct(bgc+1, wg1+j);
88     bneighlist[bneighrem++] = hdbindex(hp, bgc);
89     #ifdef DEBUG
90     if (bneighlist[bneighrem-1] <= 0)
91     error(CONSISTENCY, "bad beam in firstneigh");
92     #endif
93     }
94     return(nextneigh());
95     }
96    
97    
98 gwlarson 3.2 clumpbeams(hp, maxcnt, maxsiz, cf) /* clump beams from hinp */
99 gwlarson 3.1 register HOLO *hp;
100     int maxcnt, maxsiz;
101 gwlarson 3.2 int (*cf)();
102 gwlarson 3.1 {
103     static short primes[] = {9431,6803,4177,2659,1609,887,587,251,47,1};
104     unsigned int4 *bflags;
105     int *bqueue;
106     int bqlen;
107     int4 bqtotal;
108     int bc, bci, bqc, myprime;
109     register int i;
110     /* get clump size */
111     if (maxcnt <= 1)
112     maxcnt = nbeams(hp);
113     maxsiz /= sizeof(RAYVAL);
114     /* allocate beam queue */
115     bqueue = (int *)malloc(maxcnt*sizeof(int));
116     bflags = (unsigned int4 *)calloc((nbeams(hp)>>5)+1,
117     sizeof(unsigned int4));
118     if (bqueue == NULL | bflags == NULL)
119     error(SYSTEM, "out of memory in clumpbeams");
120     /* mark empty beams as done */
121     for (i = nbeams(hp); i > 0; i--)
122     if (!bnrays(hp, i))
123     setfl(bflags, i);
124     /* pick a good prime step size */
125     for (i = 0; primes[i]<<5 >= nbeams(hp); i++)
126     ;
127     while ((myprime = primes[i++]) > 1)
128     if (nbeams(hp) % myprime)
129     break;
130     /* add each input beam and neighbors */
131     for (bc = bci = nbeams(hp); bc > 0; bc--,
132     bci += bci>myprime ? -myprime : nbeams(hp)-myprime) {
133     if (isset(bflags, bci))
134     continue;
135     bqueue[0] = bci; /* initialize queue */
136     bqlen = 1;
137     bqtotal = bnrays(hp, i);
138     setfl(bflags, bci);
139     /* run through growing queue */
140     for (bqc = 0; bqc < bqlen; bqc++) {
141     /* add neighbors until full */
142     for (i = firstneigh(hp,bqueue[bqc]); i > 0;
143     i = nextneigh()) {
144     if (isset(bflags, i)) /* done already? */
145     continue;
146     bqueue[bqlen++] = i; /* add it */
147     bqtotal += bnrays(hp, i);
148     setfl(bflags, i);
149     if (bqlen >= maxcnt ||
150     (maxsiz && bqtotal >= maxsiz))
151     break; /* queue full */
152     }
153     if (i > 0)
154     break;
155     }
156 gwlarson 3.2 (*cf)(hp, bqueue, bqlen); /* transfer clump */
157 gwlarson 3.1 }
158 gwlarson 3.2 /* all done; clean up */
159 gwlarson 3.1 free((char *)bqueue);
160     free((char *)bflags);
161     }