ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/sm_qtree.c
Revision: 3.13
Committed: Thu Jun 10 15:22:23 1999 UTC (24 years, 10 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 3.12: +216 -8 lines
Log Message:
Implemented sample quadtree in place of triangle quadtree
Made geometric predicates more robust
Added #define LORES which utilizes a single precision floating point
  sample array, the default is a double sample array
Added topology DEBUG commands (for DEBUG > 1)
Made code optimizations

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     * sm_qtree.c: adapted from octree.c from radiance code
9     */
10     /*
11     * octree.c - routines dealing with octrees and cubes.
12     *
13     * 7/28/85
14     */
15    
16     #include "standard.h"
17 gwlarson 3.7 #include "sm_flag.h"
18 gwlarson 3.1 #include "sm_geom.h"
19     #include "sm_qtree.h"
20    
21     QUADTREE *quad_block[QT_MAX_BLK]; /* our quadtree */
22     static QUADTREE quad_free_list = EMPTY; /* freed octree nodes */
23     static QUADTREE treetop = 0; /* next free node */
24 gwlarson 3.4 int4 *quad_flag= NULL;
25 gwlarson 3.1
26 gwlarson 3.4 #ifdef TEST_DRIVER
27     extern FVECT Pick_v0[500],Pick_v1[500],Pick_v2[500];
28     extern int Pick_cnt,Pick_tri,Pick_samp;
29     extern FVECT Pick_point[500];
30 gwlarson 3.8 extern int Pick_q[500];
31 gwlarson 3.7
32 gwlarson 3.4 #endif
33    
34 gwlarson 3.13 qtremovelast(qt,id)
35     QUADTREE qt;
36     int id;
37     {
38     if(qtqueryset(qt)[(*(qtqueryset(qt)))] != id)
39     error(CONSISTENCY,"not removed\n");
40     ((*(qtqueryset(qt)))--);
41     }
42 gwlarson 3.1 QUADTREE
43     qtAlloc() /* allocate a quadtree */
44     {
45     register QUADTREE freet;
46    
47     if ((freet = quad_free_list) != EMPTY)
48     {
49     quad_free_list = QT_NTH_CHILD(freet, 0);
50     return(freet);
51     }
52     freet = treetop;
53     if (QT_BLOCK_INDEX(freet) == 0)
54     {
55     if (QT_BLOCK(freet) >= QT_MAX_BLK)
56     return(EMPTY);
57     if ((quad_block[QT_BLOCK(freet)] = (QUADTREE *)malloc(
58 gwlarson 3.3 QT_BLOCK_SIZE*4*sizeof(QUADTREE))) == NULL)
59 gwlarson 3.7 error(SYSTEM,"qtAlloc(): Unable to allocate memory\n");
60 gwlarson 3.4
61 gwlarson 3.7 /* Realloc the per/node flags */
62 gwlarson 3.3 quad_flag = (int4 *)realloc((char *)quad_flag,
63 gwlarson 3.7 (QT_BLOCK(freet)+1)*((QT_BLOCK_SIZE+7)>>3));
64 gwlarson 3.3 if (quad_flag == NULL)
65 gwlarson 3.7 error(SYSTEM,"qtAlloc(): Unable to allocate memory\n");
66 gwlarson 3.1 }
67     treetop += 4;
68     return(freet);
69     }
70    
71    
72 gwlarson 3.3 qtClearAllFlags() /* clear all quadtree branch flags */
73     {
74 gwlarson 3.7 if (!treetop)
75     return;
76    
77     /* Clear the node flags*/
78     bzero((char *)quad_flag, (QT_BLOCK(treetop-4)+1)*((QT_BLOCK_SIZE+7)>>3));
79     /* Clear set flags */
80     qtclearsetflags();
81 gwlarson 3.3 }
82    
83 gwlarson 3.1 qtFree(qt) /* free a quadtree */
84     register QUADTREE qt;
85     {
86     register int i;
87    
88     if (!QT_IS_TREE(qt))
89     {
90     qtfreeleaf(qt);
91     return;
92     }
93     for (i = 0; i < 4; i++)
94     qtFree(QT_NTH_CHILD(qt, i));
95     QT_NTH_CHILD(qt, 0) = quad_free_list;
96     quad_free_list = qt;
97     }
98    
99    
100     qtDone() /* free EVERYTHING */
101     {
102     register int i;
103 gwlarson 3.7
104 gwlarson 3.4 qtfreeleaves();
105 gwlarson 3.1 for (i = 0; i < QT_MAX_BLK; i++)
106     {
107 gwlarson 3.3 if (quad_block[i] == NULL)
108     break;
109     free((char *)quad_block[i]);
110 gwlarson 3.1 quad_block[i] = NULL;
111     }
112 gwlarson 3.7 /* Free the flags */
113 gwlarson 3.3 if (i) free((char *)quad_flag);
114     quad_flag = NULL;
115 gwlarson 3.1 quad_free_list = EMPTY;
116     treetop = 0;
117     }
118    
119     QUADTREE
120 gwlarson 3.9 qtLocate(qt,bcoord)
121 gwlarson 3.7 QUADTREE qt;
122     BCOORD bcoord[3];
123 gwlarson 3.2 {
124     int i;
125    
126 gwlarson 3.7 if(QT_IS_TREE(qt))
127     {
128 gwlarson 3.9 i = bary_child(bcoord);
129 gwlarson 3.4
130 gwlarson 3.9 return(qtLocate(QT_NTH_CHILD(qt,i),bcoord));
131 gwlarson 3.7 }
132     else
133     return(qt);
134 gwlarson 3.2 }
135    
136 gwlarson 3.6 int
137 gwlarson 3.9 move_to_nbr(b,db0,db1,db2,tptr)
138 gwlarson 3.6 BCOORD b[3];
139     BDIR db0,db1,db2;
140 gwlarson 3.9 double *tptr;
141 gwlarson 3.6 {
142 gwlarson 3.9 double t,dt;
143 gwlarson 3.6 BCOORD bc;
144     int nbr;
145    
146     nbr = -1;
147 gwlarson 3.9 *tptr = 0.0;
148 gwlarson 3.6 /* Advance to next node */
149 gwlarson 3.7 if(b[0]==0 && db0 < 0)
150     return(0);
151     if(b[1]==0 && db1 < 0)
152     return(1);
153     if(b[2]==0 && db2 < 0)
154     return(2);
155 gwlarson 3.6 if(db0 < 0)
156     {
157 gwlarson 3.9 t = ((double)b[0])/-db0;
158 gwlarson 3.6 nbr = 0;
159     }
160     else
161 gwlarson 3.9 t = MAXFLOAT;
162 gwlarson 3.6 if(db1 < 0)
163     {
164 gwlarson 3.9 dt = ((double)b[1])/-db1;
165 gwlarson 3.6 if( dt < t)
166     {
167     t = dt;
168     nbr = 1;
169     }
170     }
171     if(db2 < 0)
172     {
173 gwlarson 3.9 dt = ((double)b[2])/-db2;
174 gwlarson 3.6 if( dt < t)
175     {
176     t = dt;
177     nbr = 2;
178     }
179     }
180     *tptr = t;
181     return(nbr);
182     }
183 gwlarson 3.7
184 gwlarson 3.9 qtTrace_ray(qt,b,db0,db1,db2,nextptr,sign,sfactor,func,f)
185 gwlarson 3.7 QUADTREE qt;
186 gwlarson 3.6 BCOORD b[3];
187 gwlarson 3.9 BDIR db0,db1,db2;
188     int *nextptr;
189 gwlarson 3.7 int sign,sfactor;
190 gwlarson 3.9 FUNC func;
191     int *f;
192 gwlarson 3.4 {
193     int i,found;
194 gwlarson 3.7 QUADTREE child;
195 gwlarson 3.4 int nbr,next,w;
196 gwlarson 3.9 double t;
197 gwlarson 3.7
198     if(QT_IS_TREE(qt))
199 gwlarson 3.4 {
200 gwlarson 3.7 /* Find the appropriate child and reset the coord */
201 gwlarson 3.9 i = bary_child(b);
202 gwlarson 3.4
203 gwlarson 3.7 for(;;)
204     {
205     child = QT_NTH_CHILD(qt,i);
206     if(i != 3)
207 gwlarson 3.9 qtTrace_ray(child,b,db0,db1,db2,nextptr,sign,sfactor+1,func,f);
208 gwlarson 3.7 else
209     /* If the center cell- must flip direction signs */
210 gwlarson 3.9 qtTrace_ray(child,b,-db0,-db1,-db2,nextptr,1-sign,sfactor+1,func,f);
211 gwlarson 3.7
212     if(QT_FLAG_IS_DONE(*f))
213 gwlarson 3.9 return;
214 gwlarson 3.7 /* If in same block: traverse */
215     if(i==3)
216     next = *nextptr;
217     else
218     if(*nextptr == i)
219     next = 3;
220     else
221     {
222     /* reset the barycentric coordinates in the parents*/
223 gwlarson 3.9 bary_parent(b,i);
224 gwlarson 3.7 /* Else pop up to parent and traverse from there */
225     return(qt);
226     }
227 gwlarson 3.9 bary_from_child(b,i,next);
228 gwlarson 3.7 i = next;
229     }
230 gwlarson 3.4 }
231     else
232     {
233 gwlarson 3.8 #ifdef TEST_DRIVER
234     if(Pick_cnt < 500)
235     Pick_q[Pick_cnt++]=qt;
236     #endif;
237 gwlarson 3.9 F_FUNC(func)(qt,F_ARGS(func),f);
238 gwlarson 3.7 if(QT_FLAG_IS_DONE(*f))
239 gwlarson 3.9 return;
240     /* Advance to next node */
241     nbr = move_to_nbr(b,db0,db1,db2,&t);
242    
243     if(nbr==-1)
244 gwlarson 3.7 {
245 gwlarson 3.9 QT_FLAG_SET_DONE(*f);
246     return;
247 gwlarson 3.7 }
248 gwlarson 3.9 b[0] += (BCOORD)(t *db0);
249     b[1] += (BCOORD)(t *db1);
250     b[2] += (BCOORD)(t *db2);
251     *nextptr = nbr;
252     return;
253 gwlarson 3.7
254 gwlarson 3.9 }
255     }
256 gwlarson 3.4
257    
258 gwlarson 3.9
259    
260    
261    
262    
263    
264     #define TEST_INT(tl,th,d,q0,q1,h,l) \
265     tl=d>q0;th=d<q1; if(tl&&th) goto Lfunc_call; \
266     if(tl) if(l) goto Lfunc_call; else h=TRUE; \
267     if(th) if(h) goto Lfunc_call; else l = TRUE; \
268     if(th) if(h) goto Lfunc_call; else l = TRUE;
269    
270     /* Leaf node: Do definitive test */
271 gwlarson 3.7 QUADTREE
272 gwlarson 3.9 qtLeaf_insert_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
273     scale, s0,s1,s2,sq0,sq1,sq2,f,n)
274     int root;
275     QUADTREE qt;
276     BCOORD q0[3],q1[3],q2[3];
277     BCOORD t0[3],t1[3],t2[3];
278     BCOORD dt10[3],dt21[3],dt02[3];
279     unsigned int scale,s0,s1,s2,sq0,sq1,sq2;
280     FUNC f;
281     int n;
282     {
283     double db;
284     unsigned int e0,e1,e2;
285     char al,ah,bl,bh,cl,ch,testl,testh;
286     char test_t0t1,test_t1t2,test_t2t0;
287     BCOORD a,b,c;
288    
289     /* First check if can trivial accept: if vertex in cell */
290     if(s0 & s1 & s2)
291 gwlarson 3.13 {
292 gwlarson 3.9 goto Lfunc_call;
293 gwlarson 3.13 }
294 gwlarson 3.9 /* Assumption: Could not trivial reject*/
295     /* IF any coords lie on edge- must be in if couldnt reject */
296     a = q1[0];b= q0[1]; c= q0[2];
297     if(t0[0]== a || t0[1] == b || t0[2] == c)
298 gwlarson 3.13 {
299 gwlarson 3.9 goto Lfunc_call;
300 gwlarson 3.13 }
301 gwlarson 3.9 if(t1[0]== a || t1[1] == b || t1[2] == c)
302 gwlarson 3.13 {
303 gwlarson 3.9 goto Lfunc_call;
304 gwlarson 3.13 }
305 gwlarson 3.9 if(t2[0]== a || t2[1] == b || t2[2] == c)
306 gwlarson 3.13 {
307 gwlarson 3.9 goto Lfunc_call;
308 gwlarson 3.13 }
309 gwlarson 3.9 /* Test for edge crossings */
310     /* Test t0t1,t1t2,t2t0 against a */
311     /* Calculate edge crossings */
312     e0 = (s0 ^ ((s0 >> 1) | (s0 << 2 & 4)));
313     /* See if edge can be trivially rejected from intersetion testing */
314     test_t0t1 = !(((s0 & 6)==0) || ((s1 & 6)==0)|| ((s2 & 6)==0) ||
315     ((sq0 & 6)==6) ||((sq1 & 6)==6)|| ((sq2 & 6)==6));
316     bl=bh=0;
317     if(test_t0t1 && (e0 & 2) )
318 gwlarson 3.7 {
319 gwlarson 3.9 /* Must do double calculation to avoid overflow */
320     db = t0[1] + dt10[1]*((double)(a-t0[0]))/dt10[0];
321     TEST_INT(testl,testh,db,b,q1[1],bl,bh)
322 gwlarson 3.7 }
323 gwlarson 3.9 test_t1t2= !(((s0 & 3)==0) || ((s1 & 3)==0)|| ((s2 & 3)==0) ||
324     ((sq0 & 3)==3) ||((sq1 & 3)==3)|| ((sq2 & 3)==3));
325     if(test_t1t2 && (e0 & 1))
326     { /* test t1t2 against a */
327     db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
328     TEST_INT(testl,testh,db,b,q1[1],bl,bh)
329     }
330     test_t2t0 = !(((s0 & 5)==0) || ((s1 & 5)==0)|| ((s2 & 5)==0) ||
331     ((sq0 & 5)==5) ||((sq1 & 5)==5)|| ((sq2 & 5)==5));
332     if(test_t2t0 && (e0 & 4))
333     {
334     db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
335     TEST_INT(testl,testh,db,b,q1[1],bl,bh)
336     }
337     e1 = (s1 ^ ((s1 >> 1) | (s1 << 2 & 4)));
338     cl = ch = 0;
339     if(test_t0t1 && (e1 & 2))
340     {/* test t0t1 against b */
341     db = t0[2] + dt10[2]*((double)(b-t0[1]))/dt10[1];
342     TEST_INT(testl,testh,db,c,q2[2],cl,ch)
343     }
344     if(test_t1t2 && (e1 & 1))
345     {/* test t1t2 against b */
346     db = t1[2] + dt21[2]*((double)(q0[1] - t1[1]))/dt21[1];
347     TEST_INT(testl,testh,db,c,q2[2],cl,ch)
348     }
349     if(test_t2t0 && (e1 & 4))
350     {/* test t2t0 against b */
351     db = t2[2] + dt02[2]*((double)(q0[1] - t2[1]))/dt02[1];
352     TEST_INT(testl,testh,db,c,q2[2],cl,ch)
353     }
354    
355     /* test edges against c */
356     e2 = (s2 ^ ((s2 >> 1) | (s2 << 2 & 4)));
357     al = ah = 0;
358     if(test_t0t1 && (e2 & 2))
359     { /* test t0t1 against c */
360     db = t0[0] + dt10[0]*((double)(c-t0[2]))/dt10[2];
361     TEST_INT(testl,testh,db,a,q0[0],al,ah)
362     }
363     if(test_t1t2 && (e2 & 1))
364     {
365     db = t1[0] + dt21[0]*((double)(c - t1[2]))/dt21[2];
366     TEST_INT(testl,testh,db,a,q0[0],al,ah)
367     }
368     if(test_t2t0 && (e2 & 4))
369     { /* test t2t0 against c */
370     db = t2[0] + dt02[0]*((double)(c - t2[2]))/dt02[2];
371     TEST_INT(testl,testh,db,a,q0[0],al,ah)
372     }
373     /* Only remaining case is if some edge trivially rejected */
374     if(!e0 || !e1 || !e2)
375     return(qt);
376 gwlarson 3.4
377 gwlarson 3.9 /* Only one/none got tested - pick either of other two/any two */
378     /* Only need to test one edge */
379     if(!test_t0t1 && (e0 & 2))
380     {
381     db = t0[1] + dt10[1]*((double)(a-t0[0]))/dt10[0];
382     TEST_INT(testl,testh,db,b,q1[1],bl,bh)
383     }
384     if(!test_t1t2 && (e0 & 1))
385     {/* test t1t2 against a */
386     db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
387     TEST_INT(testl,testh,db,b,q1[1],bl,bh)
388     }
389     if(!test_t2t0 && (e0 & 4))
390     {
391     db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
392     TEST_INT(testl,testh,db,b,q1[1],bl,bh)
393     }
394 gwlarson 3.7
395 gwlarson 3.9 return(qt);
396    
397     Lfunc_call:
398     qt = f.func(f.argptr,root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
399     s0,s1,s2,sq0,sq1,sq2,0,f,n);
400     return(qt);
401    
402     }
403    
404    
405    
406     /* Leaf node: Do definitive test */
407     QUADTREE
408     qtLeaf_insert_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
409     scale, s0,s1,s2,sq0,sq1,sq2,f,n)
410     int root;
411     QUADTREE qt;
412     BCOORD q0[3],q1[3],q2[3];
413     BCOORD t0[3],t1[3],t2[3];
414     BCOORD dt10[3],dt21[3],dt02[3];
415     unsigned int scale,s0,s1,s2,sq0,sq1,sq2;
416     FUNC f;
417     int n;
418     {
419     double db;
420     unsigned int e0,e1,e2;
421     BCOORD a,b,c;
422     double p0[2], p1[2],cp;
423     char al,ah,bl,bh,cl,ch;
424     char testl,testh,test_t0t1,test_t1t2,test_t2t0;
425     unsigned int ls0,ls1,ls2;
426    
427 gwlarson 3.13
428 gwlarson 3.9 /* May have gotten passed trivial reject if one/two vertices are ON */
429     a = q1[0];b= q0[1]; c= q0[2];
430     SIDES_LESS(t0,t1,t2,ls0,ls1,ls2,a,b,c);
431    
432     /* First check if can trivial accept: if vertex in cell */
433     if(ls0 & ls1 & ls2)
434 gwlarson 3.13 {
435 gwlarson 3.9 goto Lfunc_call;
436 gwlarson 3.13 }
437 gwlarson 3.9 if(ls0==0 || ls1 == 0 || ls2 ==0)
438     return(qt);
439     /* Assumption: Could not trivial reject*/
440     /* IF any coords lie on edge- must be in if couldnt reject */
441    
442     if(t0[0]== a || t0[1] == b || t0[2] == c)
443 gwlarson 3.13 {
444 gwlarson 3.9 goto Lfunc_call;
445 gwlarson 3.13 }
446 gwlarson 3.9 if(t1[0]== a || t1[1] == b || t1[2] == c)
447 gwlarson 3.13 {
448 gwlarson 3.9 goto Lfunc_call;
449 gwlarson 3.13 }
450 gwlarson 3.9 if(t2[0]== a || t2[1] == b || t2[2] == c)
451 gwlarson 3.13 {
452 gwlarson 3.9 goto Lfunc_call;
453 gwlarson 3.13 }
454 gwlarson 3.9 /* Test for edge crossings */
455     /* Test t0t1 against a,b,c */
456     /* First test if t0t1 can be trivially rejected */
457     /* If both edges are outside bounds- dont need to test */
458    
459     /* Test t0t1,t1t2,t2t0 against a */
460     test_t0t1 = !(((ls0 & 6)==0) || ((ls1 & 6)==0)|| ((ls2 & 6)==0) ||
461     ((sq0 & 6)==0) ||((sq1 & 6)==0)|| ((sq2 & 6)==0));
462     e0 = (ls0 ^ ((ls0 >> 1) | (ls0 << 2 & 4)));
463     bl=bh=0;
464     /* Test t0t1,t1t2,t2t0 against a */
465     if(test_t0t1 && (e0 & 2) )
466 gwlarson 3.4 {
467 gwlarson 3.9 db = t0[1] + dt10[1]*((double)(a-t0[0])/dt10[0]);
468     TEST_INT(testl,testh,db,q1[1],b,bl,bh)
469 gwlarson 3.4 }
470 gwlarson 3.9 test_t1t2= !(((ls0 & 3)==0) || ((ls1 & 3)==0)|| ((ls2 & 3)==0) ||
471     ((sq0 & 3)==0) ||((sq1 & 3)==0)|| ((sq2 & 3)==0));
472     if(test_t1t2 && (e0 & 1))
473     { /* test t1t2 against a */
474     db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
475     TEST_INT(testl,testh,db,q1[1],b,bl,bh)
476     }
477 gwlarson 3.13 test_t2t0 = !(((ls0 & 5)==0) || ((ls1 & 5)==0)|| ((ls2 & 5)==0) ||
478 gwlarson 3.9 ((sq0 & 5)==0) ||((sq1 & 5)==0)|| ((sq2 & 5)==0));
479     if(test_t2t0 && (e0 & 4))
480     {
481     db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
482     TEST_INT(testl,testh,db,q1[1],b,bl,bh)
483     }
484     cl = ch = 0;
485     e1 = (ls1 ^ ((ls1 >> 1) | (ls1 << 2 & 4)));
486     if(test_t0t1 && (e1 & 2))
487     {/* test t0t1 against b */
488     db = t0[2] + dt10[2]*(((double)(b-t0[1]))/dt10[1]);
489     TEST_INT(testl,testh,db,q1[2],c,cl,ch)
490     }
491     if(test_t1t2 && (e1 & 1))
492     {/* test t1t2 against b */
493     db = t1[2] + dt21[2]*((double)(b - t1[1]))/dt21[1];
494     TEST_INT(testl,testh,db,q1[2],c,cl,ch)
495     }
496     if(test_t2t0 && (e1 & 4))
497     {/* test t2t0 against b */
498     db = t2[2] + dt02[2]*((double)(b - t2[1]))/dt02[1];
499     TEST_INT(testl,testh,db,q1[2],c,cl,ch)
500     }
501     al = ah = 0;
502     e2 = (ls2 ^ ((ls2 >> 1) | (ls2 << 2 & 4)));
503     if(test_t0t1 && (e2 & 2))
504     { /* test t0t1 against c */
505     db = t0[0] + dt10[0]*(((double)(c-t0[2]))/dt10[2]);
506     TEST_INT(testl,testh,db,q0[0],a,al,ah)
507     }
508     if(test_t1t2 && (e2 & 1))
509     {
510     db = t1[0] + dt21[0]*((double)(c - t1[2]))/dt21[2];
511     TEST_INT(testl,testh,db,q0[0],a,al,ah)
512     }
513     if(test_t2t0 && (e2 & 4))
514     { /* test t2t0 against c */
515     db = t2[0] + dt02[0]*((double)(c - t2[2]))/dt02[2];
516     TEST_INT(testl,testh,db,q0[0],a,al,ah)
517     }
518     /* Only remaining case is if some edge trivially rejected */
519     if(!e0 || !e1 || !e2)
520     return(qt);
521 gwlarson 3.4
522 gwlarson 3.9 /* Only one/none got tested - pick either of other two/any two */
523     /* Only need to test one edge */
524     if(!test_t0t1 && (e0 & 2))
525 gwlarson 3.4 {
526 gwlarson 3.9 db = t0[1] + dt10[1]*((double)(a-t0[0]))/dt10[0];
527     TEST_INT(testl,testh,db,q1[1],b,bl,bh)
528 gwlarson 3.4 }
529 gwlarson 3.9 if(!test_t1t2 && (e0 & 1))
530     {/* test t1t2 against a */
531     db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
532     TEST_INT(testl,testh,db,q1[1],b,bl,bh)
533 gwlarson 3.4 }
534 gwlarson 3.9 if(!test_t2t0 && (e0 & 4))
535 gwlarson 3.7 {
536 gwlarson 3.9 db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
537     TEST_INT(testl,testh,db,q1[1],b,bl,bh)
538 gwlarson 3.7 }
539 gwlarson 3.9
540 gwlarson 3.7 return(qt);
541 gwlarson 3.9 Lfunc_call:
542     qt = f.func(f.argptr,root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
543     s0,s1,s2,sq0,sq1,sq2,1,f,n);
544     return(qt);
545     }
546    
547    
548    
549     /* ASSUMPTION: that triangle t0,t1,t2 intersects quad cell q0,q1,q2 */
550    
551     /*-------q2--------- sq2
552     / \
553     s1 /sc \ s0
554     qb_____qa
555     / \ / \
556     \sq0/sa \ /sb \ /sq1
557     \ q0____qc____q1/
558     \ /
559     \ s2 /
560     */
561    
562     int Find_id=0;
563    
564     QUADTREE
565     qtInsert_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
566     s0,s1,s2,sq0,sq1,sq2,f,n)
567     int root;
568     QUADTREE qt;
569     BCOORD q0[3],q1[3],q2[3];
570     BCOORD t0[3],t1[3],t2[3];
571     BCOORD dt10[3],dt21[3],dt02[3];
572     BCOORD scale;
573     unsigned int s0,s1,s2,sq0,sq1,sq2;
574     FUNC f;
575     int n;
576     {
577     BCOORD a,b,c;
578     BCOORD va[3],vb[3],vc[3];
579     unsigned int sa,sb,sc;
580    
581     /* If a tree: trivial reject and recurse on potential children */
582     if(QT_IS_TREE(qt))
583     {
584     /* Test against new a edge: if entirely to left: only need
585     to visit child 0
586     */
587     a = q1[0] + scale;
588     b = q0[1] + scale;
589     c = q0[2] + scale;
590    
591     SIDES_GTR(t0,t1,t2,sa,sb,sc,a,b,c);
592    
593     if(sa==7)
594     {
595     vb[1] = q0[1];
596     vc[2] = q0[2];
597     vc[1] = b;
598     vb[2] = c;
599     vb[0] = vc[0] = a;
600     QT_NTH_CHILD(qt,0) = qtInsert_tri(root,QT_NTH_CHILD(qt,0),q0,vc,
601     vb,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,s1,s2,sq0,sb,sc,f,n+1);
602     return(qt);
603     }
604     if(sb==7)
605     {
606     va[0] = q1[0];
607     vc[2] = q0[2];
608     va[1] = vc[1] = b;
609     va[2] = c;
610     vc[0] = a;
611     QT_NTH_CHILD(qt,1) = qtInsert_tri(root,QT_NTH_CHILD(qt,1),vc,q1,va,
612     t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n+1);
613     return(qt);
614     }
615     if(sc==7)
616     {
617     va[0] = q1[0];
618     vb[1] = q0[1];
619     va[1] = b;
620     va[2] = vb[2] = c;
621     vb[0] = a;
622     QT_NTH_CHILD(qt,2) = qtInsert_tri(root,QT_NTH_CHILD(qt,2),vb,va,
623     q2,t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n+1);
624     return(qt);
625     }
626    
627     va[0] = q1[0];
628     vb[1] = q0[1];
629     vc[2] = q0[2];
630     va[1] = vc[1] = b;
631     va[2] = vb[2] = c;
632     vb[0] = vc[0] = a;
633     /* If outside of all edges: only need to Visit 3 */
634     if(sa==0 && sb==0 && sc==0)
635     {
636     QT_NTH_CHILD(qt,3) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,3),va,vb,
637     vc,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,sb,sc,s0,s1,s2,f,n+1);
638     return(qt);
639     }
640    
641     if(sa)
642     QT_NTH_CHILD(qt,0) = qtInsert_tri(root,QT_NTH_CHILD(qt,0),q0,vc,vb,t0,
643     t1,t2,dt10,dt21,dt02,scale>>1,sa,s1,s2,sq0,sb,sc,f,n+1);
644     if(sb)
645     QT_NTH_CHILD(qt,1) = qtInsert_tri(root,QT_NTH_CHILD(qt,1),vc,q1,va,t0,
646     t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n+1);
647     if(sc)
648     QT_NTH_CHILD(qt,2) = qtInsert_tri(root,QT_NTH_CHILD(qt,2),vb,va,q2,t0,
649     t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n+1);
650     QT_NTH_CHILD(qt,3) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,3),va,vb,vc,t0,
651     t1,t2,dt10,dt21,dt02,scale>>1,sa,sb,sc,s0,s1,s2,f,n+1);
652     return(qt);
653     }
654     /* Leaf node: Do definitive test */
655     else
656     return(qt = qtLeaf_insert_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
657     scale,s0,s1,s2,sq0,sq1,sq2,f,n));
658 gwlarson 3.4 }
659    
660    
661 gwlarson 3.7 QUADTREE
662 gwlarson 3.9 qtInsert_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
663     s0,s1,s2,sq0,sq1,sq2,f,n)
664     int root;
665     QUADTREE qt;
666     BCOORD q0[3],q1[3],q2[3];
667     BCOORD t0[3],t1[3],t2[3];
668     BCOORD dt10[3],dt21[3],dt02[3];
669     BCOORD scale;
670     unsigned int s0,s1,s2,sq0,sq1,sq2;
671     FUNC f;
672 gwlarson 3.13 int n;
673 gwlarson 3.7 {
674 gwlarson 3.9 BCOORD a,b,c;
675     BCOORD va[3],vb[3],vc[3];
676     unsigned int sa,sb,sc;
677 gwlarson 3.4
678 gwlarson 3.9 /* If a tree: trivial reject and recurse on potential children */
679     if(QT_IS_TREE(qt))
680     {
681     /* Test against new a edge: if entirely to left: only need
682     to visit child 0
683     */
684     a = q1[0] - scale;
685     b = q0[1] - scale;
686     c = q0[2] - scale;
687 gwlarson 3.7
688 gwlarson 3.9 SIDES_GTR(t0,t1,t2,sa,sb,sc,a,b,c);
689 gwlarson 3.7
690 gwlarson 3.9 if(sa==0)
691     {
692     vb[1] = q0[1];
693     vc[2] = q0[2];
694     vc[1] = b;
695     vb[2] = c;
696     vb[0] = vc[0] = a;
697    
698     QT_NTH_CHILD(qt,0) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,0),q0,vc,
699     vb,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,s1,s2,sq0,sb,sc,f,n+1);
700     return(qt);
701     }
702     if(sb==0)
703     {
704     va[0] = q1[0];
705     vc[2] = q0[2];
706     va[1] = vc[1] = b;
707     va[2] = c;
708     vc[0] = a;
709     QT_NTH_CHILD(qt,1) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,1),vc,q1,va,
710     t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n+1);
711     return(qt);
712     }
713     if(sc==0)
714     {
715     va[0] = q1[0];
716     vb[1] = q0[1];
717     va[1] = b;
718     va[2] = vb[2] = c;
719     vb[0] = a;
720     QT_NTH_CHILD(qt,2) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,2),vb,va,
721     q2,t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n+1);
722     return(qt);
723     }
724     va[0] = q1[0];
725     vb[1] = q0[1];
726     vc[2] = q0[2];
727     va[1] = vc[1] = b;
728     va[2] = vb[2] = c;
729     vb[0] = vc[0] = a;
730     /* If outside of all edges: only need to Visit 3 */
731     if(sa==7 && sb==7 && sc==7)
732     {
733     QT_NTH_CHILD(qt,3) = qtInsert_tri(root,QT_NTH_CHILD(qt,3),va,vb,
734     vc,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,sb,sc,s0,s1,s2,f,n+1);
735     return(qt);
736     }
737     if(sa!=7)
738     QT_NTH_CHILD(qt,0) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,0),q0,vc,vb,
739     t0,t1,t2,dt10,dt21,dt02,scale>>1,sa,s1,s2,sq0,sb,sc,f,n+1);
740     if(sb!=7)
741     QT_NTH_CHILD(qt,1) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,1),vc,q1,va,
742     t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n+1);
743     if(sc!=7)
744     QT_NTH_CHILD(qt,2) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,2),vb,va,q2,
745     t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n+1);
746    
747     QT_NTH_CHILD(qt,3) = qtInsert_tri(root,QT_NTH_CHILD(qt,3),va,vb,vc,t0,t1,
748     t2,dt10,dt21,dt02,scale>>1,sa,sb,sc,s0,s1,s2,f,n+1);
749     return(qt);
750     }
751     /* Leaf node: Do definitive test */
752 gwlarson 3.7 else
753 gwlarson 3.9 return(qt = qtLeaf_insert_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
754     scale,s0,s1,s2,sq0,sq1,sq2,f,n));
755     }
756    
757    
758    
759    
760     /*************************************************************************/
761     /* Visit code for applying functions: NOTE THIS IS THE SAME AS INSERT CODE:
762     except sets flags: wanted insert to be as efficient as possible: so
763 gwlarson 3.13 broke into two sets of routines. Also traverses only to n levels.
764 gwlarson 3.9 */
765    
766     qtVisit_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
767 gwlarson 3.12 s0,s1,s2,sq0,sq1,sq2,f,n)
768 gwlarson 3.9 int root;
769     QUADTREE qt;
770     BCOORD q0[3],q1[3],q2[3];
771     BCOORD t0[3],t1[3],t2[3];
772     BCOORD dt10[3],dt21[3],dt02[3];
773     BCOORD scale;
774     unsigned int s0,s1,s2,sq0,sq1,sq2;
775     FUNC f;
776 gwlarson 3.12 int n;
777 gwlarson 3.9 {
778     BCOORD a,b,c;
779     BCOORD va[3],vb[3],vc[3];
780     unsigned int sa,sb,sc;
781    
782 gwlarson 3.12 if(n == 0)
783     return;
784 gwlarson 3.9 /* If a tree: trivial reject and recurse on potential children */
785     if(QT_IS_TREE(qt))
786 gwlarson 3.7 {
787 gwlarson 3.9 QT_SET_FLAG(qt);
788    
789     /* Test against new a edge: if entirely to left: only need
790     to visit child 0
791     */
792     a = q1[0] + scale;
793     b = q0[1] + scale;
794     c = q0[2] + scale;
795    
796     SIDES_GTR(t0,t1,t2,sa,sb,sc,a,b,c);
797    
798     if(sa==7)
799     {
800     vb[1] = q0[1];
801     vc[2] = q0[2];
802     vc[1] = b;
803     vb[2] = c;
804     vb[0] = vc[0] = a;
805     qtVisit_tri(root,QT_NTH_CHILD(qt,0),q0,vc,
806 gwlarson 3.12 vb,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,s1,s2,sq0,sb,sc,f,n-1);
807 gwlarson 3.9 return;
808     }
809     if(sb==7)
810     {
811     va[0] = q1[0];
812     vc[2] = q0[2];
813     va[1] = vc[1] = b;
814     va[2] = c;
815     vc[0] = a;
816     qtVisit_tri(root,QT_NTH_CHILD(qt,1),vc,q1,va,
817 gwlarson 3.12 t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n-1);
818 gwlarson 3.9 return;
819     }
820     if(sc==7)
821     {
822     va[0] = q1[0];
823     vb[1] = q0[1];
824     va[1] = b;
825     va[2] = vb[2] = c;
826     vb[0] = a;
827     qtVisit_tri(root,QT_NTH_CHILD(qt,2),vb,va,
828 gwlarson 3.12 q2,t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n-1);
829 gwlarson 3.9 return;
830     }
831    
832     va[0] = q1[0];
833     vb[1] = q0[1];
834     vc[2] = q0[2];
835     va[1] = vc[1] = b;
836     va[2] = vb[2] = c;
837     vb[0] = vc[0] = a;
838     /* If outside of all edges: only need to Visit 3 */
839     if(sa==0 && sb==0 && sc==0)
840     {
841     qtVisit_tri_rev(root,QT_NTH_CHILD(qt,3),va,vb,
842 gwlarson 3.12 vc,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,sb,sc,s0,s1,s2,f,n-1);
843 gwlarson 3.9 return;
844     }
845    
846     if(sa)
847     qtVisit_tri(root,QT_NTH_CHILD(qt,0),q0,vc,vb,t0,
848 gwlarson 3.12 t1,t2,dt10,dt21,dt02,scale>>1,sa,s1,s2,sq0,sb,sc,f,n-1);
849 gwlarson 3.9 if(sb)
850     qtVisit_tri(root,QT_NTH_CHILD(qt,1),vc,q1,va,t0,
851 gwlarson 3.12 t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n-1);
852 gwlarson 3.9 if(sc)
853     qtVisit_tri(root,QT_NTH_CHILD(qt,2),vb,va,q2,t0,
854 gwlarson 3.12 t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n-1);
855 gwlarson 3.9 qtVisit_tri_rev(root,QT_NTH_CHILD(qt,3),va,vb,vc,t0,
856 gwlarson 3.12 t1,t2,dt10,dt21,dt02,scale>>1,sa,sb,sc,s0,s1,s2,f,n-1);
857 gwlarson 3.7 }
858 gwlarson 3.9 /* Leaf node: Do definitive test */
859     else
860     qtLeaf_visit_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
861 gwlarson 3.12 scale,s0,s1,s2,sq0,sq1,sq2,f,n);
862 gwlarson 3.9
863 gwlarson 3.7 }
864 gwlarson 3.4
865 gwlarson 3.3
866 gwlarson 3.9 qtVisit_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
867 gwlarson 3.12 s0,s1,s2,sq0,sq1,sq2,f,n)
868 gwlarson 3.9 int root;
869     QUADTREE qt;
870     BCOORD q0[3],q1[3],q2[3];
871     BCOORD t0[3],t1[3],t2[3];
872     BCOORD dt10[3],dt21[3],dt02[3];
873     BCOORD scale;
874     unsigned int s0,s1,s2,sq0,sq1,sq2;
875     FUNC f;
876 gwlarson 3.12 int n;
877 gwlarson 3.9 {
878     BCOORD a,b,c;
879     BCOORD va[3],vb[3],vc[3];
880     unsigned int sa,sb,sc;
881 gwlarson 3.2
882 gwlarson 3.12 if(n==0)
883     return;
884 gwlarson 3.9 /* If a tree: trivial reject and recurse on potential children */
885     if(QT_IS_TREE(qt))
886     {
887     QT_SET_FLAG(qt);
888     /* Test against new a edge: if entirely to left: only need
889     to visit child 0
890     */
891     a = q1[0] - scale;
892     b = q0[1] - scale;
893     c = q0[2] - scale;
894 gwlarson 3.2
895 gwlarson 3.9 SIDES_GTR(t0,t1,t2,sa,sb,sc,a,b,c);
896 gwlarson 3.2
897 gwlarson 3.9 if(sa==0)
898     {
899     vb[1] = q0[1];
900     vc[2] = q0[2];
901     vc[1] = b;
902     vb[2] = c;
903     vb[0] = vc[0] = a;
904     qtVisit_tri_rev(root,QT_NTH_CHILD(qt,0),q0,vc,
905 gwlarson 3.12 vb,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,s1,s2,sq0,sb,sc,f,n-1);
906 gwlarson 3.9 return;
907     }
908     if(sb==0)
909     {
910     va[0] = q1[0];
911     vc[2] = q0[2];
912     va[1] = vc[1] = b;
913     va[2] = c;
914     vc[0] = a;
915     qtVisit_tri_rev(root,QT_NTH_CHILD(qt,1),vc,q1,va,
916 gwlarson 3.12 t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n-1);
917 gwlarson 3.9 return;
918     }
919     if(sc==0)
920     {
921     va[0] = q1[0];
922     vb[1] = q0[1];
923     va[1] = b;
924     va[2] = vb[2] = c;
925     vb[0] = a;
926     qtVisit_tri_rev(root,QT_NTH_CHILD(qt,2),vb,va,
927 gwlarson 3.12 q2,t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n-1);
928 gwlarson 3.9 return;
929     }
930     va[0] = q1[0];
931     vb[1] = q0[1];
932     vc[2] = q0[2];
933     va[1] = vc[1] = b;
934     va[2] = vb[2] = c;
935     vb[0] = vc[0] = a;
936     /* If outside of all edges: only need to Visit 3 */
937     if(sa==7 && sb==7 && sc==7)
938     {
939     qtVisit_tri(root,QT_NTH_CHILD(qt,3),va,vb,
940 gwlarson 3.12 vc,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,sb,sc,s0,s1,s2,f,n-1);
941 gwlarson 3.9 return;
942     }
943     if(sa!=7)
944     qtVisit_tri_rev(root,QT_NTH_CHILD(qt,0),q0,vc,vb,
945 gwlarson 3.12 t0,t1,t2,dt10,dt21,dt02,scale>>1,sa,s1,s2,sq0,sb,sc,f,n-1);
946 gwlarson 3.9 if(sb!=7)
947     qtVisit_tri_rev(root,QT_NTH_CHILD(qt,1),vc,q1,va,
948 gwlarson 3.12 t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n-1);
949 gwlarson 3.9 if(sc!=7)
950     qtVisit_tri_rev(root,QT_NTH_CHILD(qt,2),vb,va,q2,
951 gwlarson 3.12 t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n-1);
952 gwlarson 3.2
953 gwlarson 3.9 qtVisit_tri(root,QT_NTH_CHILD(qt,3),va,vb,vc,t0,t1,
954 gwlarson 3.12 t2,dt10,dt21,dt02,scale>>1,sa,sb,sc,s0,s1,s2,f,n-1);
955 gwlarson 3.9 return;
956     }
957     /* Leaf node: Do definitive test */
958     else
959     qtLeaf_visit_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
960 gwlarson 3.12 scale,s0,s1,s2,sq0,sq1,sq2,f,n);
961 gwlarson 3.9 }
962 gwlarson 3.2
963    
964    
965 gwlarson 3.9 qtLeaf_visit_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
966 gwlarson 3.12 scale, s0,s1,s2,sq0,sq1,sq2,f,n)
967 gwlarson 3.9 int root;
968     QUADTREE qt;
969     BCOORD q0[3],q1[3],q2[3];
970     BCOORD t0[3],t1[3],t2[3];
971     BCOORD dt10[3],dt21[3],dt02[3];
972     unsigned int scale,s0,s1,s2,sq0,sq1,sq2;
973     FUNC f;
974 gwlarson 3.12 int n;
975 gwlarson 3.9 {
976     double db;
977     unsigned int e0,e1,e2;
978     char al,ah,bl,bh,cl,ch,testl,testh;
979     char test_t0t1,test_t1t2,test_t2t0;
980     BCOORD a,b,c;
981 gwlarson 3.12
982 gwlarson 3.9 /* First check if can trivial accept: if vertex in cell */
983     if(s0 & s1 & s2)
984     goto Lfunc_call;
985    
986     /* Assumption: Could not trivial reject*/
987     /* IF any coords lie on edge- must be in if couldnt reject */
988     a = q1[0];b= q0[1]; c= q0[2];
989     if(t0[0]== a || t0[1] == b || t0[2] == c)
990     goto Lfunc_call;
991     if(t1[0]== a || t1[1] == b || t1[2] == c)
992     goto Lfunc_call;
993     if(t2[0]== a || t2[1] == b || t2[2] == c)
994     goto Lfunc_call;
995    
996     /* Test for edge crossings */
997     /* Test t0t1,t1t2,t2t0 against a */
998     /* Calculate edge crossings */
999     e0 = (s0 ^ ((s0 >> 1) | (s0 << 2 & 4)));
1000     /* See if edge can be trivially rejected from intersetion testing */
1001     test_t0t1 = !(((s0 & 6)==0) || ((s1 & 6)==0)|| ((s2 & 6)==0) ||
1002     ((sq0 & 6)==6) ||((sq1 & 6)==6)|| ((sq2 & 6)==6));
1003     bl=bh=0;
1004     if(test_t0t1 && (e0 & 2) )
1005     {
1006     /* Must do double calculation to avoid overflow */
1007     db = t0[1] + dt10[1]*((double)(a-t0[0]))/dt10[0];
1008     TEST_INT(testl,testh,db,b,q1[1],bl,bh)
1009     }
1010     test_t1t2= !(((s0 & 3)==0) || ((s1 & 3)==0)|| ((s2 & 3)==0) ||
1011     ((sq0 & 3)==3) ||((sq1 & 3)==3)|| ((sq2 & 3)==3));
1012     if(test_t1t2 && (e0 & 1))
1013     { /* test t1t2 against a */
1014     db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
1015     TEST_INT(testl,testh,db,b,q1[1],bl,bh)
1016     }
1017     test_t2t0 = !(((s0 & 5)==0) || ((s1 & 5)==0)|| ((s2 & 5)==0) ||
1018     ((sq0 & 5)==5) ||((sq1 & 5)==5)|| ((sq2 & 5)==5));
1019     if(test_t2t0 && (e0 & 4))
1020     {
1021     db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
1022     TEST_INT(testl,testh,db,b,q1[1],bl,bh)
1023     }
1024     e1 = (s1 ^ ((s1 >> 1) | (s1 << 2 & 4)));
1025     cl = ch = 0;
1026     if(test_t0t1 && (e1 & 2))
1027     {/* test t0t1 against b */
1028     db = t0[2] + dt10[2]*((double)(b-t0[1]))/dt10[1];
1029     TEST_INT(testl,testh,db,c,q2[2],cl,ch)
1030     }
1031     if(test_t1t2 && (e1 & 1))
1032     {/* test t1t2 against b */
1033     db = t1[2] + dt21[2]*((double)(q0[1] - t1[1]))/dt21[1];
1034     TEST_INT(testl,testh,db,c,q2[2],cl,ch)
1035     }
1036     if(test_t2t0 && (e1 & 4))
1037     {/* test t2t0 against b */
1038     db = t2[2] + dt02[2]*((double)(q0[1] - t2[1]))/dt02[1];
1039     TEST_INT(testl,testh,db,c,q2[2],cl,ch)
1040     }
1041    
1042     /* test edges against c */
1043     e2 = (s2 ^ ((s2 >> 1) | (s2 << 2 & 4)));
1044     al = ah = 0;
1045     if(test_t0t1 && (e2 & 2))
1046     { /* test t0t1 against c */
1047     db = t0[0] + dt10[0]*((double)(c-t0[2]))/dt10[2];
1048     TEST_INT(testl,testh,db,a,q0[0],al,ah)
1049     }
1050     if(test_t1t2 && (e2 & 1))
1051     {
1052     db = t1[0] + dt21[0]*((double)(c - t1[2]))/dt21[2];
1053     TEST_INT(testl,testh,db,a,q0[0],al,ah)
1054     }
1055     if(test_t2t0 && (e2 & 4))
1056     { /* test t2t0 against c */
1057     db = t2[0] + dt02[0]*((double)(c - t2[2]))/dt02[2];
1058     TEST_INT(testl,testh,db,a,q0[0],al,ah)
1059     }
1060     /* Only remaining case is if some edge trivially rejected */
1061     if(!e0 || !e1 || !e2)
1062     return;
1063    
1064     /* Only one/none got tested - pick either of other two/any two */
1065     /* Only need to test one edge */
1066     if(!test_t0t1 && (e0 & 2))
1067     {
1068     db = t0[1] + dt10[1]*((double)(a-t0[0]))/dt10[0];
1069     TEST_INT(testl,testh,db,b,q1[1],bl,bh)
1070     }
1071     if(!test_t1t2 && (e0 & 1))
1072     {/* test t1t2 against a */
1073     db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
1074     TEST_INT(testl,testh,db,b,q1[1],bl,bh)
1075     }
1076     if(!test_t2t0 && (e0 & 4))
1077     {
1078     db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
1079     TEST_INT(testl,testh,db,b,q1[1],bl,bh)
1080     }
1081    
1082     return;
1083    
1084     Lfunc_call:
1085 gwlarson 3.12
1086     f.func(f.argptr,root,qt,n);
1087 gwlarson 3.9 if(!QT_IS_EMPTY(qt))
1088     QT_LEAF_SET_FLAG(qt);
1089 gwlarson 3.12
1090 gwlarson 3.9 }
1091    
1092    
1093    
1094     /* Leaf node: Do definitive test */
1095     QUADTREE
1096     qtLeaf_visit_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
1097 gwlarson 3.12 scale, s0,s1,s2,sq0,sq1,sq2,f,n)
1098 gwlarson 3.9 int root;
1099     QUADTREE qt;
1100     BCOORD q0[3],q1[3],q2[3];
1101     BCOORD t0[3],t1[3],t2[3];
1102     BCOORD dt10[3],dt21[3],dt02[3];
1103     unsigned int scale,s0,s1,s2,sq0,sq1,sq2;
1104     FUNC f;
1105 gwlarson 3.12 int n;
1106 gwlarson 3.9 {
1107     double db;
1108     unsigned int e0,e1,e2;
1109     BCOORD a,b,c;
1110     double p0[2], p1[2],cp;
1111     char al,ah,bl,bh,cl,ch;
1112     char testl,testh,test_t0t1,test_t1t2,test_t2t0;
1113     unsigned int ls0,ls1,ls2;
1114    
1115     /* May have gotten passed trivial reject if one/two vertices are ON */
1116     a = q1[0];b= q0[1]; c= q0[2];
1117     SIDES_LESS(t0,t1,t2,ls0,ls1,ls2,a,b,c);
1118    
1119     /* First check if can trivial accept: if vertex in cell */
1120     if(ls0 & ls1 & ls2)
1121     goto Lfunc_call;
1122    
1123     if(ls0==0 || ls1 == 0 || ls2 ==0)
1124     return;
1125     /* Assumption: Could not trivial reject*/
1126     /* IF any coords lie on edge- must be in if couldnt reject */
1127    
1128     if(t0[0]== a || t0[1] == b || t0[2] == c)
1129     goto Lfunc_call;
1130     if(t1[0]== a || t1[1] == b || t1[2] == c)
1131     goto Lfunc_call;
1132     if(t2[0]== a || t2[1] == b || t2[2] == c)
1133     goto Lfunc_call;
1134    
1135     /* Test for edge crossings */
1136     /* Test t0t1 against a,b,c */
1137     /* First test if t0t1 can be trivially rejected */
1138     /* If both edges are outside bounds- dont need to test */
1139    
1140     /* Test t0t1,t1t2,t2t0 against a */
1141     test_t0t1 = !(((ls0 & 6)==0) || ((ls1 & 6)==0)|| ((ls2 & 6)==0) ||
1142     ((sq0 & 6)==0) ||((sq1 & 6)==0)|| ((sq2 & 6)==0));
1143     e0 = (ls0 ^ ((ls0 >> 1) | (ls0 << 2 & 4)));
1144     bl=bh=0;
1145     /* Test t0t1,t1t2,t2t0 against a */
1146     if(test_t0t1 && (e0 & 2) )
1147     {
1148     db = t0[1] + dt10[1]*((double)(a-t0[0])/dt10[0]);
1149     TEST_INT(testl,testh,db,q1[1],b,bl,bh)
1150     }
1151     test_t1t2= !(((ls0 & 3)==0) || ((ls1 & 3)==0)|| ((ls2 & 3)==0) ||
1152     ((sq0 & 3)==0) ||((sq1 & 3)==0)|| ((sq2 & 3)==0));
1153     if(test_t1t2 && (e0 & 1))
1154     { /* test t1t2 against a */
1155     db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
1156     TEST_INT(testl,testh,db,q1[1],b,bl,bh)
1157     }
1158     test_t2t0 = !(((ls0 & 5)==0) || ((ls1 & 5)==0)|| ((ls2 & 5)==0) ||
1159     ((sq0 & 5)==0) ||((sq1 & 5)==0)|| ((sq2 & 5)==0));
1160     if(test_t2t0 && (e0 & 4))
1161     {
1162     db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
1163     TEST_INT(testl,testh,db,q1[1],b,bl,bh)
1164     }
1165     cl = ch = 0;
1166     e1 = (ls1 ^ ((ls1 >> 1) | (ls1 << 2 & 4)));
1167     if(test_t0t1 && (e1 & 2))
1168     {/* test t0t1 against b */
1169     db = t0[2] + dt10[2]*(((double)(b-t0[1]))/dt10[1]);
1170     TEST_INT(testl,testh,db,q1[2],c,cl,ch)
1171     }
1172     if(test_t1t2 && (e1 & 1))
1173     {/* test t1t2 against b */
1174     db = t1[2] + dt21[2]*((double)(b - t1[1]))/dt21[1];
1175     TEST_INT(testl,testh,db,q1[2],c,cl,ch)
1176     }
1177     if(test_t2t0 && (e1 & 4))
1178     {/* test t2t0 against b */
1179     db = t2[2] + dt02[2]*((double)(b - t2[1]))/dt02[1];
1180     TEST_INT(testl,testh,db,q1[2],c,cl,ch)
1181     }
1182     al = ah = 0;
1183     e2 = (ls2 ^ ((ls2 >> 1) | (ls2 << 2 & 4)));
1184     if(test_t0t1 && (e2 & 2))
1185     { /* test t0t1 against c */
1186     db = t0[0] + dt10[0]*(((double)(c-t0[2]))/dt10[2]);
1187     TEST_INT(testl,testh,db,q0[0],a,al,ah)
1188     }
1189     if(test_t1t2 && (e2 & 1))
1190     {
1191     db = t1[0] + dt21[0]*((double)(c - t1[2]))/dt21[2];
1192     TEST_INT(testl,testh,db,q0[0],a,al,ah)
1193     }
1194     if(test_t2t0 && (e2 & 4))
1195     { /* test t2t0 against c */
1196     db = t2[0] + dt02[0]*((double)(c - t2[2]))/dt02[2];
1197     TEST_INT(testl,testh,db,q0[0],a,al,ah)
1198     }
1199     /* Only remaining case is if some edge trivially rejected */
1200     if(!e0 || !e1 || !e2)
1201     return;
1202    
1203     /* Only one/none got tested - pick either of other two/any two */
1204     /* Only need to test one edge */
1205     if(!test_t0t1 && (e0 & 2))
1206     {
1207     db = t0[1] + dt10[1]*((double)(a-t0[0]))/dt10[0];
1208     TEST_INT(testl,testh,db,q1[1],b,bl,bh)
1209     }
1210     if(!test_t1t2 && (e0 & 1))
1211     {/* test t1t2 against a */
1212     db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
1213     TEST_INT(testl,testh,db,q1[1],b,bl,bh)
1214     }
1215     if(!test_t2t0 && (e0 & 4))
1216     {
1217     db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
1218     TEST_INT(testl,testh,db,q1[1],b,bl,bh)
1219     }
1220    
1221     return;
1222    
1223     Lfunc_call:
1224 gwlarson 3.12 f.func(f.argptr,root,qt,n);
1225 gwlarson 3.9 if(!QT_IS_EMPTY(qt))
1226     QT_LEAF_SET_FLAG(qt);
1227     }
1228 gwlarson 3.13
1229    
1230     QUADTREE
1231     qtInsert_point(root,qt,parent,q0,q1,q2,bc,scale,f,n,doneptr)
1232     int root;
1233     QUADTREE qt,parent;
1234     BCOORD q0[3],q1[3],q2[3],bc[3],scale;
1235     FUNC f;
1236     int n,*doneptr;
1237     {
1238     BCOORD a,b,c;
1239     BCOORD va[3],vb[3],vc[3];
1240    
1241     if(QT_IS_TREE(qt))
1242     {
1243     a = q1[0] + scale;
1244     b = q0[1] + scale;
1245     c = q0[2] + scale;
1246     if(bc[0] > a)
1247     {
1248     vc[0] = a; vc[1] = b; vc[2] = q0[2];
1249     vb[0] = a; vb[1] = q0[1]; vb[2] = c;
1250     QT_NTH_CHILD(qt,0) = qtInsert_point(root,QT_NTH_CHILD(qt,0),
1251     qt,q0,vc,vb,bc,scale>>1,f,n+1,doneptr);
1252     if(!*doneptr)
1253     {
1254     f.func_after(f.argptr,QT_NTH_CHILD(qt,1),f,doneptr);
1255     if(!*doneptr)
1256     f.func_after(f.argptr,QT_NTH_CHILD(qt,2),f,doneptr);
1257     if(!*doneptr)
1258     f.func_after(f.argptr,QT_NTH_CHILD(qt,3),f,doneptr);
1259     }
1260     return(qt);
1261     }
1262     if(bc[1] > b)
1263     {
1264     vc[0] = a; vc[1] = b; vc[2] = q0[2];
1265     va[0] = q1[0]; va[1] = b; va[2] = c;
1266     QT_NTH_CHILD(qt,1) =qtInsert_point(root,QT_NTH_CHILD(qt,1),
1267     qt,vc,q1,va,bc,scale >>1,f,n+1,doneptr);
1268     if(!*doneptr)
1269     {
1270     f.func_after(f.argptr,QT_NTH_CHILD(qt,0),f,doneptr);
1271     if(!*doneptr)
1272     f.func_after(f.argptr,QT_NTH_CHILD(qt,2),f,doneptr);
1273     if(!*doneptr)
1274     f.func_after(f.argptr,QT_NTH_CHILD(qt,3),f,doneptr);
1275     }
1276     return(qt);
1277     }
1278     if(bc[2] > c)
1279     {
1280     va[0] = q1[0]; va[1] = b; va[2] = c;
1281     vb[0] = a; vb[1] = q0[1]; vb[2] = c;
1282     QT_NTH_CHILD(qt,2) = qtInsert_point(root,QT_NTH_CHILD(qt,2),
1283     qt,vb,va,q2,bc,scale>>1,f,n+1,doneptr);
1284     if(!*doneptr)
1285     {
1286     f.func_after(f.argptr,QT_NTH_CHILD(qt,0),f,doneptr);
1287     if(!*doneptr)
1288     f.func_after(f.argptr,QT_NTH_CHILD(qt,1),f,doneptr);
1289     if(!*doneptr)
1290     f.func_after(f.argptr,QT_NTH_CHILD(qt,3),f,doneptr);
1291     }
1292     return(qt);
1293     }
1294     else
1295     {
1296     va[0] = q1[0]; va[1] = b; va[2] = c;
1297     vb[0] = a; vb[1] = q0[1]; vb[2] = c;
1298     vc[0] = a; vc[1] = b; vc[2] = q0[2];
1299     QT_NTH_CHILD(qt,3) = qtInsert_point_rev(root,QT_NTH_CHILD(qt,3),
1300     qt,va,vb,vc,bc,scale>>1,f,n+1,doneptr);
1301     if(!*doneptr)
1302     {
1303     f.func_after(f.argptr,QT_NTH_CHILD(qt,0),f,doneptr);
1304     if(!*doneptr)
1305     f.func_after(f.argptr,QT_NTH_CHILD(qt,1),f,doneptr);
1306     if(!*doneptr)
1307     f.func_after(f.argptr,QT_NTH_CHILD(qt,2),f,doneptr);
1308     }
1309     return(qt);
1310     }
1311     }
1312     else
1313     {
1314     qt = f.func(f.argptr,root,qt,parent,q0,q1,q2,bc,scale,0,f,n,doneptr);
1315     return(qt);
1316     }
1317     }
1318    
1319    
1320     QUADTREE
1321     qtInsert_point_rev(root,qt,parent,q0,q1,q2,bc,scale,f,n,doneptr)
1322     int root;
1323     QUADTREE qt,parent;
1324     BCOORD q0[3],q1[3],q2[3],bc[3];
1325     BCOORD scale;
1326     FUNC f;
1327     int n,*doneptr;
1328     {
1329     BCOORD a,b,c;
1330     BCOORD va[3],vb[3],vc[3];
1331    
1332     if(QT_IS_TREE(qt))
1333     {
1334     a = q1[0] - scale;
1335     b = q0[1] - scale;
1336     c = q0[2] - scale;
1337     if(bc[0] < a)
1338     {
1339     vc[0] = a; vc[1] = b; vc[2] = q0[2];
1340     vb[0] = a; vb[1] = q0[1]; vb[2] = c;
1341     QT_NTH_CHILD(qt,0) = qtInsert_point_rev(root,QT_NTH_CHILD(qt,0),
1342     qt,q0,vc,vb,bc,scale>>1,f,n+1,doneptr);
1343     if(!*doneptr)
1344     {
1345     f.func_after(f.argptr,QT_NTH_CHILD(qt,1),f,doneptr);
1346     if(!*doneptr)
1347     f.func_after(f.argptr,QT_NTH_CHILD(qt,2),f,doneptr);
1348     if(!*doneptr)
1349     f.func_after(f.argptr,QT_NTH_CHILD(qt,3),f,doneptr);
1350     }
1351     return(qt);
1352     }
1353     if(bc[1] < b)
1354     {
1355     vc[0] = a; vc[1] = b; vc[2] = q0[2];
1356     va[0] = q1[0]; va[1] = b; va[2] = c;
1357     QT_NTH_CHILD(qt,1) = qtInsert_point_rev(root,QT_NTH_CHILD(qt,1),
1358     qt,vc,q1,va,bc,scale>>1,f,n+1,doneptr);
1359     if(!*doneptr)
1360     {
1361     f.func_after(f.argptr,QT_NTH_CHILD(qt,0),f,doneptr);
1362     if(!*doneptr)
1363     f.func_after(f.argptr,QT_NTH_CHILD(qt,2),f,doneptr);
1364     if(!*doneptr)
1365     f.func_after(f.argptr,QT_NTH_CHILD(qt,3),f,doneptr);
1366     }
1367     return(qt);
1368     }
1369     if(bc[2] < c)
1370     {
1371     va[0] = q1[0]; va[1] = b; va[2] = c;
1372     vb[0] = a; vb[1] = q0[1]; vb[2] = c;
1373     QT_NTH_CHILD(qt,2) = qtInsert_point_rev(root,QT_NTH_CHILD(qt,2),
1374     qt,vb,va,q2,bc,scale>>1,f,n+1,doneptr);
1375     if(!*doneptr)
1376     {
1377     f.func_after(f.argptr,QT_NTH_CHILD(qt,0),f,doneptr);
1378     if(!*doneptr)
1379     f.func_after(f.argptr,QT_NTH_CHILD(qt,1),f,doneptr);
1380     if(!*doneptr)
1381     f.func_after(f.argptr,QT_NTH_CHILD(qt,3),f,doneptr);
1382     }
1383     return(qt);
1384     }
1385     else
1386     {
1387     va[0] = q1[0]; va[1] = b; va[2] = c;
1388     vb[0] = a; vb[1] = q0[1]; vb[2] = c;
1389     vc[0] = a; vc[1] = b; vc[2] = q0[2];
1390     QT_NTH_CHILD(qt,3) = qtInsert_point(root,QT_NTH_CHILD(qt,3),
1391     qt,va,vb,vc,bc,scale>>1,f,n+1,doneptr);
1392     if(!*doneptr)
1393     {
1394     f.func_after(f.argptr,QT_NTH_CHILD(qt,0),f,doneptr);
1395     if(!*doneptr)
1396     f.func_after(f.argptr,QT_NTH_CHILD(qt,1),f,doneptr);
1397     if(!*doneptr)
1398     f.func_after(f.argptr,QT_NTH_CHILD(qt,2),f,doneptr);
1399     }
1400     return(qt);
1401     }
1402     }
1403     else
1404     {
1405     qt = f.func(f.argptr,root,qt,parent,q0,q1,q2,bc,scale,1,f,n,doneptr);
1406     return(qt);
1407     }
1408     }
1409    
1410    
1411    
1412    
1413    
1414    
1415    
1416 gwlarson 3.2
1417    
1418