ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/sm_qtree.c
Revision: 3.12
Committed: Fri Mar 5 16:32:49 1999 UTC (25 years, 2 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 3.11: +35 -25 lines
Log Message:
added variable level traversal to node visiting routines to support display list rendering.

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