ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/objset.c
Revision: 1.4
Committed: Wed Sep 19 08:26:02 1990 UTC (33 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.3: +3 -1 lines
Log Message:
increased OSTSIZ for efficient conversion of large models

File Contents

# Content
1 /* Copyright (c) 1986 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * objset.c - routines for maintaining object sets.
9 *
10 * 7/28/85
11 */
12
13 #include "standard.h"
14
15 #include "octree.h"
16
17 #include "object.h"
18
19 #include "otypes.h"
20
21 #ifndef OSTSIZ
22 #define OSTSIZ 12329 /* object table size (a prime!) */
23 #endif
24
25 static OBJECT *ostable[OSTSIZ]; /* the object set table */
26
27
28 insertelem(os, obj) /* insert obj into os, no questions */
29 register OBJECT *os;
30 OBJECT obj;
31 {
32 register int i;
33
34 for (i = os[0]++; i > 0; i--)
35 if (os[i] > obj)
36 os[i+1] = os[i];
37 else
38 break;
39 os[i+1] = obj;
40 }
41
42
43 deletelem(os, obj) /* delete obj from os, no questions */
44 register OBJECT *os;
45 OBJECT obj;
46 {
47 register int i;
48
49 for (i = (*os++)--; i > 0 && *os < obj; i--, os++)
50 ;
51 while (--i > 0) {
52 os[0] = os[1];
53 os++;
54 }
55 }
56
57
58 inset(os, obj) /* determine if object is in set */
59 register OBJECT *os;
60 OBJECT obj;
61 {
62 int upper, lower;
63 register int cm, i;
64
65 lower = 1;
66 upper = cm = os[0] + 1;
67
68 while ((i = (lower + upper) >> 1) != cm) {
69 cm = obj - os[i];
70 if (cm > 0)
71 lower = i;
72 else if (cm < 0)
73 upper = i;
74 else
75 return(1);
76 cm = i;
77 }
78 return(0);
79 }
80
81
82 setequal(os1, os2) /* determine if two sets are equal */
83 register OBJECT *os1, *os2;
84 {
85 register int i;
86
87 for (i = *os1; i-- >= 0; )
88 if (*os1++ != *os2++)
89 return(0);
90 return(1);
91 }
92
93
94 setcopy(os1, os2) /* copy object set os2 into os1 */
95 register OBJECT *os1, *os2;
96 {
97 register int i;
98
99 for (i = *os2; i-- >= 0; )
100 *os1++ = *os2++;
101 }
102
103
104 OCTREE
105 fullnode(oset) /* return octree for object set */
106 OBJECT *oset;
107 {
108 int osentry, ntries;
109 long hval;
110 OCTREE ot;
111 register int i;
112 register OBJECT *os;
113 /* hash on set */
114 hval = 0;
115 os = oset;
116 i = *os++;
117 while (i-- > 0)
118 hval += *os++;
119 ntries = 0;
120 tryagain:
121 osentry = (hval + (long)ntries*ntries) % OSTSIZ;
122 os = ostable[osentry];
123 if (os == NULL) {
124 os = ostable[osentry] = (OBJECT *)malloc(
125 (unsigned)(oset[0]+2)*sizeof(OBJECT));
126 if (os == NULL)
127 goto memerr;
128 ot = oseti(osentry);
129 } else {
130 /* look for set */
131 for (i = 0; *os > 0; i++, os += *os + 1)
132 if (setequal(os, oset))
133 break;
134 ot = oseti(i*OSTSIZ + osentry);
135 if (*os > 0) /* found it */
136 return(ot);
137 if (!isfull(ot)) /* entry overflow */
138 if (++ntries < OSTSIZ)
139 goto tryagain;
140 else
141 error(INTERNAL, "hash table overflow in fullnode");
142 /* remember position */
143 i = os - ostable[osentry];
144 os = ostable[osentry] = (OBJECT *)realloc(
145 (char *)ostable[osentry],
146 (unsigned)(i+oset[0]+2)*sizeof(OBJECT));
147 if (os == NULL)
148 goto memerr;
149 os += i; /* last entry */
150 }
151 setcopy(os, oset); /* add new set */
152 os += *os + 1;
153 *os = 0; /* terminator */
154 return(ot);
155 memerr:
156 error(SYSTEM, "out of memory in fullnode");
157 }
158
159
160 objset(oset, ot) /* get object set for full node */
161 register OBJECT *oset;
162 OCTREE ot;
163 {
164 register OBJECT *os;
165 register int i;
166
167 if (!isfull(ot))
168 goto noderr;
169 i = oseti(ot);
170 if ((os = ostable[i%OSTSIZ]) == NULL)
171 goto noderr;
172 for (i /= OSTSIZ; i--; os += *os + 1)
173 if (*os <= 0)
174 goto noderr;
175 for (i = *os; i-- >= 0; ) /* copy set here */
176 *oset++ = *os++;
177 return;
178 noderr:
179 error(CONSISTENCY, "bad node in objset");
180 }
181
182
183 nonsurfinset(orig, nobjs) /* check sets for non-surfaces */
184 int orig, nobjs;
185 {
186 int n;
187 register OBJECT *os;
188 register OBJECT i, t;
189
190 for (n = 0; n < OSTSIZ; n++) {
191 if ((os = ostable[n]) == NULL)
192 continue;
193 while ((i = *os++) > 0)
194 while (i--) {
195 t = *os++;
196 if (t >= orig && t < orig+nobjs) {
197 t = objptr(t)->otype;
198 if (!issurface(t))
199 return(1);
200 }
201 }
202 }
203 return(0);
204 }