ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/sm_qtree.c
(Generate patch)

Comparing ray/src/hd/sm_qtree.c (file contents):
Revision 3.1 by gwlarson, Wed Aug 19 17:45:24 1998 UTC vs.
Revision 3.17 by schorsch, Mon Jun 30 14:59:12 2003 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines