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

# Content
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 #include "sm_flag.h"
18 #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 int4 *quad_flag= NULL;
25
26 #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 extern int Pick_q[500];
31
32 #endif
33
34 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 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 QT_BLOCK_SIZE*4*sizeof(QUADTREE))) == NULL)
59 error(SYSTEM,"qtAlloc(): Unable to allocate memory\n");
60
61 /* Realloc the per/node flags */
62 quad_flag = (int4 *)realloc((char *)quad_flag,
63 (QT_BLOCK(freet)+1)*((QT_BLOCK_SIZE+7)>>3));
64 if (quad_flag == NULL)
65 error(SYSTEM,"qtAlloc(): Unable to allocate memory\n");
66 }
67 treetop += 4;
68 return(freet);
69 }
70
71
72 qtClearAllFlags() /* clear all quadtree branch flags */
73 {
74 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 }
82
83 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
104 qtfreeleaves();
105 for (i = 0; i < QT_MAX_BLK; i++)
106 {
107 if (quad_block[i] == NULL)
108 break;
109 free((char *)quad_block[i]);
110 quad_block[i] = NULL;
111 }
112 /* Free the flags */
113 if (i) free((char *)quad_flag);
114 quad_flag = NULL;
115 quad_free_list = EMPTY;
116 treetop = 0;
117 }
118
119 QUADTREE
120 qtLocate(qt,bcoord)
121 QUADTREE qt;
122 BCOORD bcoord[3];
123 {
124 int i;
125
126 if(QT_IS_TREE(qt))
127 {
128 i = bary_child(bcoord);
129
130 return(qtLocate(QT_NTH_CHILD(qt,i),bcoord));
131 }
132 else
133 return(qt);
134 }
135
136 int
137 move_to_nbr(b,db0,db1,db2,tptr)
138 BCOORD b[3];
139 BDIR db0,db1,db2;
140 double *tptr;
141 {
142 double t,dt;
143 BCOORD bc;
144 int nbr;
145
146 nbr = -1;
147 *tptr = 0.0;
148 /* Advance to next node */
149 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 if(db0 < 0)
156 {
157 t = ((double)b[0])/-db0;
158 nbr = 0;
159 }
160 else
161 t = MAXFLOAT;
162 if(db1 < 0)
163 {
164 dt = ((double)b[1])/-db1;
165 if( dt < t)
166 {
167 t = dt;
168 nbr = 1;
169 }
170 }
171 if(db2 < 0)
172 {
173 dt = ((double)b[2])/-db2;
174 if( dt < t)
175 {
176 t = dt;
177 nbr = 2;
178 }
179 }
180 *tptr = t;
181 return(nbr);
182 }
183
184 qtTrace_ray(qt,b,db0,db1,db2,nextptr,sign,sfactor,func,f)
185 QUADTREE qt;
186 BCOORD b[3];
187 BDIR db0,db1,db2;
188 int *nextptr;
189 int sign,sfactor;
190 FUNC func;
191 int *f;
192 {
193 int i,found;
194 QUADTREE child;
195 int nbr,next,w;
196 double t;
197
198 if(QT_IS_TREE(qt))
199 {
200 /* Find the appropriate child and reset the coord */
201 i = bary_child(b);
202
203 for(;;)
204 {
205 child = QT_NTH_CHILD(qt,i);
206 if(i != 3)
207 qtTrace_ray(child,b,db0,db1,db2,nextptr,sign,sfactor+1,func,f);
208 else
209 /* If the center cell- must flip direction signs */
210 qtTrace_ray(child,b,-db0,-db1,-db2,nextptr,1-sign,sfactor+1,func,f);
211
212 if(QT_FLAG_IS_DONE(*f))
213 return;
214 /* 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 bary_parent(b,i);
224 /* Else pop up to parent and traverse from there */
225 return(qt);
226 }
227 bary_from_child(b,i,next);
228 i = next;
229 }
230 }
231 else
232 {
233 #ifdef TEST_DRIVER
234 if(Pick_cnt < 500)
235 Pick_q[Pick_cnt++]=qt;
236 #endif;
237 F_FUNC(func)(qt,F_ARGS(func),f);
238 if(QT_FLAG_IS_DONE(*f))
239 return;
240 /* Advance to next node */
241 nbr = move_to_nbr(b,db0,db1,db2,&t);
242
243 if(nbr==-1)
244 {
245 QT_FLAG_SET_DONE(*f);
246 return;
247 }
248 b[0] += (BCOORD)(t *db0);
249 b[1] += (BCOORD)(t *db1);
250 b[2] += (BCOORD)(t *db2);
251 *nextptr = nbr;
252 return;
253
254 }
255 }
256
257
258
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 QUADTREE
272 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 {
292 goto Lfunc_call;
293 }
294 /* 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 {
299 goto Lfunc_call;
300 }
301 if(t1[0]== a || t1[1] == b || t1[2] == c)
302 {
303 goto Lfunc_call;
304 }
305 if(t2[0]== a || t2[1] == b || t2[2] == c)
306 {
307 goto Lfunc_call;
308 }
309 /* 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 {
319 /* 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 }
323 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
377 /* 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
395 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
428 /* 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 {
435 goto Lfunc_call;
436 }
437 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 {
444 goto Lfunc_call;
445 }
446 if(t1[0]== a || t1[1] == b || t1[2] == c)
447 {
448 goto Lfunc_call;
449 }
450 if(t2[0]== a || t2[1] == b || t2[2] == c)
451 {
452 goto Lfunc_call;
453 }
454 /* 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 {
467 db = t0[1] + dt10[1]*((double)(a-t0[0])/dt10[0]);
468 TEST_INT(testl,testh,db,q1[1],b,bl,bh)
469 }
470 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 test_t2t0 = !(((ls0 & 5)==0) || ((ls1 & 5)==0)|| ((ls2 & 5)==0) ||
478 ((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
522 /* 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 {
526 db = t0[1] + dt10[1]*((double)(a-t0[0]))/dt10[0];
527 TEST_INT(testl,testh,db,q1[1],b,bl,bh)
528 }
529 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 }
534 if(!test_t2t0 && (e0 & 4))
535 {
536 db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
537 TEST_INT(testl,testh,db,q1[1],b,bl,bh)
538 }
539
540 return(qt);
541 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 }
659
660
661 QUADTREE
662 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 int n;
673 {
674 BCOORD a,b,c;
675 BCOORD va[3],vb[3],vc[3];
676 unsigned int sa,sb,sc;
677
678 /* 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
688 SIDES_GTR(t0,t1,t2,sa,sb,sc,a,b,c);
689
690 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 else
753 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 broke into two sets of routines. Also traverses only to n levels.
764 */
765
766 qtVisit_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
767 s0,s1,s2,sq0,sq1,sq2,f,n)
768 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 int n;
777 {
778 BCOORD a,b,c;
779 BCOORD va[3],vb[3],vc[3];
780 unsigned int sa,sb,sc;
781
782 if(n == 0)
783 return;
784 /* If a tree: trivial reject and recurse on potential children */
785 if(QT_IS_TREE(qt))
786 {
787 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 vb,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,s1,s2,sq0,sb,sc,f,n-1);
807 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 t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n-1);
818 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 q2,t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n-1);
829 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 vc,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,sb,sc,s0,s1,s2,f,n-1);
843 return;
844 }
845
846 if(sa)
847 qtVisit_tri(root,QT_NTH_CHILD(qt,0),q0,vc,vb,t0,
848 t1,t2,dt10,dt21,dt02,scale>>1,sa,s1,s2,sq0,sb,sc,f,n-1);
849 if(sb)
850 qtVisit_tri(root,QT_NTH_CHILD(qt,1),vc,q1,va,t0,
851 t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n-1);
852 if(sc)
853 qtVisit_tri(root,QT_NTH_CHILD(qt,2),vb,va,q2,t0,
854 t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n-1);
855 qtVisit_tri_rev(root,QT_NTH_CHILD(qt,3),va,vb,vc,t0,
856 t1,t2,dt10,dt21,dt02,scale>>1,sa,sb,sc,s0,s1,s2,f,n-1);
857 }
858 /* Leaf node: Do definitive test */
859 else
860 qtLeaf_visit_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
861 scale,s0,s1,s2,sq0,sq1,sq2,f,n);
862
863 }
864
865
866 qtVisit_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
867 s0,s1,s2,sq0,sq1,sq2,f,n)
868 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 int n;
877 {
878 BCOORD a,b,c;
879 BCOORD va[3],vb[3],vc[3];
880 unsigned int sa,sb,sc;
881
882 if(n==0)
883 return;
884 /* 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
895 SIDES_GTR(t0,t1,t2,sa,sb,sc,a,b,c);
896
897 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 vb,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,s1,s2,sq0,sb,sc,f,n-1);
906 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 t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n-1);
917 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 q2,t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n-1);
928 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 vc,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,sb,sc,s0,s1,s2,f,n-1);
941 return;
942 }
943 if(sa!=7)
944 qtVisit_tri_rev(root,QT_NTH_CHILD(qt,0),q0,vc,vb,
945 t0,t1,t2,dt10,dt21,dt02,scale>>1,sa,s1,s2,sq0,sb,sc,f,n-1);
946 if(sb!=7)
947 qtVisit_tri_rev(root,QT_NTH_CHILD(qt,1),vc,q1,va,
948 t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n-1);
949 if(sc!=7)
950 qtVisit_tri_rev(root,QT_NTH_CHILD(qt,2),vb,va,q2,
951 t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n-1);
952
953 qtVisit_tri(root,QT_NTH_CHILD(qt,3),va,vb,vc,t0,t1,
954 t2,dt10,dt21,dt02,scale>>1,sa,sb,sc,s0,s1,s2,f,n-1);
955 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 scale,s0,s1,s2,sq0,sq1,sq2,f,n);
961 }
962
963
964
965 qtLeaf_visit_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
966 scale, s0,s1,s2,sq0,sq1,sq2,f,n)
967 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 int n;
975 {
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
982 /* 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
1086 f.func(f.argptr,root,qt,n);
1087 if(!QT_IS_EMPTY(qt))
1088 QT_LEAF_SET_FLAG(qt);
1089
1090 }
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 scale, s0,s1,s2,sq0,sq1,sq2,f,n)
1098 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 int n;
1106 {
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 f.func(f.argptr,root,qt,n);
1225 if(!QT_IS_EMPTY(qt))
1226 QT_LEAF_SET_FLAG(qt);
1227 }
1228
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
1417
1418