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.6 by gwlarson, Wed Sep 16 18:16:29 1998 UTC vs.
Revision 3.13 by gwlarson, Thu Jun 10 15:22:23 1999 UTC

# Line 14 | Line 14 | static char SCCSid[] = "$SunId$ SGI";
14   */
15  
16   #include "standard.h"
17 <
17 > #include "sm_flag.h"
18   #include "sm_geom.h"
19   #include "sm_qtree.h"
20  
# Line 27 | Line 27 | int4 *quad_flag= NULL;
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   {
# Line 46 | Line 56 | qtAlloc()                      /* allocate a quadtree */
56             return(EMPTY);
57          if ((quad_block[QT_BLOCK(freet)] = (QUADTREE *)malloc(
58                          QT_BLOCK_SIZE*4*sizeof(QUADTREE))) == NULL)
59 <           return(EMPTY);
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/8));
63 >                        (QT_BLOCK(freet)+1)*((QT_BLOCK_SIZE+7)>>3));
64          if (quad_flag == NULL)
65 <                return(EMPTY);
65 >           error(SYSTEM,"qtAlloc(): Unable to allocate memory\n");
66      }
67      treetop += 4;
68      return(freet);
# Line 60 | Line 71 | qtAlloc()                      /* allocate a quadtree */
71  
72   qtClearAllFlags()               /* clear all quadtree branch flags */
73   {
74 <        if (!treetop) return;
75 <        bzero((char *)quad_flag, (QT_BLOCK(treetop-4)+1)*(QT_BLOCK_SIZE/8));
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  
67
83   qtFree(qt)                      /* free a quadtree */
84     register QUADTREE  qt;
85   {
# Line 85 | Line 100 | qtFree(qt)                     /* free a quadtree */
100   qtDone()                        /* free EVERYTHING */
101   {
102          register int    i;
103 <
103 >        
104          qtfreeleaves();
105          for (i = 0; i < QT_MAX_BLK; i++)
106          {
# Line 94 | Line 109 | qtDone()                       /* free EVERYTHING */
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;
# Line 101 | Line 117 | qtDone()                       /* free EVERYTHING */
117   }
118  
119   QUADTREE
120 < *qtLocate_leaf(qtptr,bcoord,t0,t1,t2)
121 < QUADTREE *qtptr;
122 < double bcoord[3];
107 < FVECT t0,t1,t2;
120 > qtLocate(qt,bcoord)
121 > QUADTREE qt;
122 > BCOORD bcoord[3];
123   {
124    int i;
110  QUADTREE *child;
111  FVECT a,b,c;
125  
126 <    if(QT_IS_TREE(*qtptr))
127 <    {  
128 <      i = bary_child(bcoord);
116 < #ifdef DEBUG_TEST_DRIVER
117 <      qtSubdivide_tri(Pick_v0[Pick_cnt-1],Pick_v1[Pick_cnt-1],
118 <                      Pick_v2[Pick_cnt-1],a,b,c);
119 <      qtNth_child_tri(Pick_v0[Pick_cnt-1],Pick_v1[Pick_cnt-1],
120 <                           Pick_v2[Pick_cnt-1],a,b,c,i,
121 <                           Pick_v0[Pick_cnt],Pick_v1[Pick_cnt],
122 <                           Pick_v2[Pick_cnt]);
123 <           Pick_cnt++;
124 < #endif
126 >  if(QT_IS_TREE(qt))
127 >  {  
128 >    i = bary_child(bcoord);
129  
130 <      child = QT_NTH_CHILD_PTR(*qtptr,i);
131 <      if(t0)
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 <        qtSubdivide_tri(t0,t1,t2,a,b,c);
177 <        qtNth_child_tri(t0,t1,t2,a,b,c,i,t0,t1,t2);
176 >        t = dt;
177 >        nbr = 2;
178        }
132      return(qtLocate_leaf(child,bcoord,t0,t1,t2));
179      }
180 <    else
181 <      return(qtptr);
180 >  *tptr = t;
181 >  return(nbr);
182   }
183  
184 <
185 < QUADTREE
186 < *qtRoot_point_locate(qtptr,v0,v1,v2,pt,t0,t1,t2)
187 < QUADTREE *qtptr;
188 < FVECT v0,v1,v2;
189 < FVECT pt;
190 < FVECT t0,t1,t2;
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 d;
194 <    int i,x,y;
195 <    QUADTREE *child;
196 <    FVECT n,i_pt,a,b,c;
150 <    double pd,bcoord[3];
193 >    int i,found;
194 >    QUADTREE child;
195 >    int nbr,next,w;
196 >    double t;
197  
198 <    /* Determine if point lies within pyramid (and therefore
199 <       inside a spherical quadtree cell):GT_INTERIOR, on one of the
200 <       pyramid sides (and on cell edge):GT_EDGE(1,2 or 3),
201 <       or on pyramid vertex (and on cell vertex):GT_VERTEX(1,2, or 3).
156 <       For each triangle edge: compare the
157 <       point against the plane formed by the edge and the view center
158 <    */
159 <    d = point_in_stri(v0,v1,v2,pt);  
198 >    if(QT_IS_TREE(qt))
199 >    {
200 >      /* Find the appropriate child and reset the coord */
201 >      i = bary_child(b);
202  
203 <    
162 <    /* Not in this triangle */
163 <    if(!d)
164 <      return(NULL);
165 <
166 <    /* Will return lowest level triangle containing point: It the
167 <       point is on an edge or vertex: will return first associated
168 <       triangle encountered in the child traversal- the others can
169 <       be derived using triangle adjacency information
170 <    */
171 <    if(QT_IS_TREE(*qtptr))
172 <    {  
173 <      /* Find the intersection point */
174 <      tri_plane_equation(v0,v1,v2,n,&pd,FALSE);
175 <      intersect_vector_plane(pt,n,pd,NULL,i_pt);
176 <
177 <      i = max_index(n,NULL);
178 <      x = (i+1)%3;
179 <      y = (i+2)%3;
180 <      /* Calculate barycentric coordinates of i_pt */
181 <      bary2d(v0[x],v0[y],v1[x],v1[y],v2[x],v2[y],i_pt[x],i_pt[y],bcoord);
182 <
183 <      i = bary_child(bcoord);
184 <      child = QT_NTH_CHILD_PTR(*qtptr,i);
185 < #ifdef DEBUG_TEST_DRIVER
186 <      Pick_cnt = 0;
187 <      VCOPY(Pick_v0[0],v0);
188 <      VCOPY(Pick_v1[0],v1);
189 <      VCOPY(Pick_v2[0],v2);
190 <      Pick_cnt++;
191 <      qtSubdivide_tri(Pick_v0[Pick_cnt-1],Pick_v1[Pick_cnt-1],
192 <                      Pick_v2[Pick_cnt-1],a,b,c);
193 <      qtNth_child_tri(Pick_v0[Pick_cnt-1],Pick_v1[Pick_cnt-1],
194 <                      Pick_v2[Pick_cnt-1],a,b,c,i,
195 <                             Pick_v0[Pick_cnt],Pick_v1[Pick_cnt],
196 <                             Pick_v2[Pick_cnt]);
197 <           Pick_cnt++;
198 < #endif
199 <      if(t0)
203 >      for(;;)
204        {
205 <        qtSubdivide_tri(v0,v1,v2,a,b,c);
206 <        qtNth_child_tri(v0,v1,v2,a,b,c,i,t0,t1,t2);
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        }
204      return(qtLocate_leaf(child,bcoord,t0,t1,t2));
230      }
231      else
232 <    {
233 <        if(t0)
234 <        {
235 <            VCOPY(t0,v0);
236 <            VCOPY(t1,v1);
237 <            VCOPY(t2,v2);
238 <        }
239 <        return(qtptr);
240 <    }
241 < }
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  
219 QUADTREE
220 qtSubdivide(qtptr)
221 QUADTREE *qtptr;
222 {
223  QUADTREE node;
224  node = qtAlloc();
225  QT_CLEAR_CHILDREN(node);
226  *qtptr = node;
227  return(node);
228 }
257  
258  
231 QUADTREE
232 qtSubdivide_nth_child(qt,n)
233 QUADTREE qt;
234 int n;
235 {
236  QUADTREE node;
259  
238  node = qtSubdivide(&(QT_NTH_CHILD(qt,n)));
239  
240  return(node);
241 }
260  
243 /* for triangle v0-v1-v2- returns a,b,c: children are:
261  
245        v2                     0: v0,a,c
246        /\                     1: a,v1,b                  
247       /2 \                    2: c,b,v2
248     c/____\b                  3: b,c,a
249     /\    /\  
250    /0 \3 /1 \
251  v0____\/____\v1
252        a
253 */
262  
255 qtSubdivide_tri(v0,v1,v2,a,b,c)
256 FVECT v0,v1,v2;
257 FVECT a,b,c;
258 {
259    EDGE_MIDPOINT_VEC3(a,v0,v1);
260    EDGE_MIDPOINT_VEC3(b,v1,v2);
261    EDGE_MIDPOINT_VEC3(c,v2,v0);
262 }
263  
264 < qtNth_child_tri(v0,v1,v2,a,b,c,i,r0,r1,r2)
265 < FVECT v0,v1,v2;
266 < FVECT a,b,c;
267 < int i;
268 < FVECT r0,r1,r2;
269 < {
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 <  switch(i){
271 <  case 0:  
272 <  VCOPY(r0,v0); VCOPY(r1,a);    VCOPY(r2,c);
273 <    break;
274 <  case 1:  
275 <  VCOPY(r0,a); VCOPY(r1,v1);    VCOPY(r2,b);
276 <    break;
277 <  case 2:  
278 <  VCOPY(r0,c); VCOPY(r1,b);    VCOPY(r2,v2);
279 <    break;
280 <  case 3:  
282 <  VCOPY(r0,b); VCOPY(r1,c);    VCOPY(r2,a);
283 <    break;
284 <  }
285 < }
286 <
287 < /* Add triangle "id" to all leaf level cells that are children of
288 < quadtree pointed to by "qtptr" with cell vertices "t1,t2,t3"
289 < that it overlaps (vertex and edge adjacencies do not count
290 < as overlapping). If the addition of the triangle causes the cell to go over
291 < threshold- the cell is split- and the triangle must be recursively inserted
292 < into the new child cells: it is assumed that "v1,v2,v3" are normalized
293 < */
294 <
295 < int
296 < qtRoot_add_tri(qtptr,q0,q1,q2,t0,t1,t2,id,n)
297 < QUADTREE *qtptr;
298 < FVECT q0,q1,q2;
299 < FVECT t0,t1,t2;
300 < int id;
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 <  int test;
284 <  int found;
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 <  test = stri_intersect(q0,q1,q2,t0,t1,t2);
290 <  if(!test)
291 <    return(FALSE);
292 <  
293 <  found = qtAdd_tri(qtptr,q0,q1,q2,t0,t1,t2,id,n);
294 <  
295 <  return(found);
296 < }
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 < int
378 < qtAdd_tri(qtptr,q0,q1,q2,t0,t1,t2,id,n)
379 < QUADTREE *qtptr;
318 < FVECT q0,q1,q2;
319 < FVECT t0,t1,t2;
320 < int id;
321 < int n;
322 < {
323 <  int i,index,test,found;
324 <  FVECT a,b,c;
325 <  OBJECT os[QT_MAXSET+1],*optr;
326 <  QUADTREE qt;
327 <  FVECT r0,r1,r2;
328 <
329 <  found = 0;
330 <  /* if this is tree: recurse */
331 <  if(QT_IS_TREE(*qtptr))
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 <    n++;
382 <    qtSubdivide_tri(q0,q1,q2,a,b,c);
335 <    test = stri_intersect(t0,t1,t2,q0,a,c);
336 <    if(test)
337 <      found |= qtAdd_tri(QT_NTH_CHILD_PTR(*qtptr,0),q0,a,c,t0,t1,t2,id,n);
338 <    test = stri_intersect(t0,t1,t2,a,q1,b);
339 <    if(test)
340 <      found |= qtAdd_tri(QT_NTH_CHILD_PTR(*qtptr,1),a,q1,b,t0,t1,t2,id,n);
341 <    test = stri_intersect(t0,t1,t2,c,b,q2);
342 <    if(test)
343 <      found |= qtAdd_tri(QT_NTH_CHILD_PTR(*qtptr,2),c,b,q2,t0,t1,t2,id,n);
344 <    test = stri_intersect(t0,t1,t2,b,c,a);
345 <    if(test)
346 <      found |= qtAdd_tri(QT_NTH_CHILD_PTR(*qtptr,3),b,c,a,t0,t1,t2,id,n);
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 <  else
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 <      /* If this leave node emptry- create a new set */
392 <      if(QT_IS_EMPTY(*qtptr))
393 <        *qtptr = qtaddelem(*qtptr,id);
353 <      else
354 <      {
355 <          /* If the set is too large: subdivide */
356 <        optr = qtqueryset(*qtptr);
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 <        if(QT_SET_CNT(optr) < QT_SET_THRESHOLD)
359 <          *qtptr = qtaddelem(*qtptr,id);
360 <          else
361 <          {
362 <            if (n < QT_MAX_LEVELS)
363 <            {
364 <                 /* If set size exceeds threshold: subdivide cell and
365 <                    reinsert set tris into cell
366 <                    */
367 <              qtgetset(os,*qtptr);      
395 >  return(qt);
396  
397 <              n++;
398 <              qtfreeleaf(*qtptr);
399 <              qtSubdivide(qtptr);
400 <              found = qtAdd_tri(qtptr,q0,q1,q2,t0,t1,t2,id,n);
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  
374              for(optr = QT_SET_PTR(os),i = QT_SET_CNT(os); i > 0; i--)
375                {
376                  id = QT_SET_NEXT_ELEM(optr);
377                  qtTri_from_id(id,r0,r1,r2,NULL,NULL,NULL,NULL,NULL,NULL);
378                  found=qtAdd_tri(qtptr,q0,q1,q2,r0,r1,r2,id,n);
379 #ifdef DEBUG
380                  if(!found)
381                    eputs("qtAdd_tri():Reinsert-in parent but not children\n");
382 #endif
383                }
384            }
385            else
386              if(QT_SET_CNT(optr) < QT_MAXSET)
387                  *qtptr = qtaddelem(*qtptr,id);
388              else
389                {
390 #ifdef DEBUG
391                    eputs("qtAdd_tri():two many levels\n");
392 #endif
393                    return(FALSE);
394                }
395          }
396      }
397  }
398  return(TRUE);
402   }
403  
404  
402 int
403 qtApply_to_tri_cells(qtptr,t0,t1,t2,v0,v1,v2,func,arg)
404 QUADTREE *qtptr;
405 FVECT t0,t1,t2;
406 FVECT v0,v1,v2;
407 int (*func)();
408 int *arg;
409 {
410  int test;
411  FVECT a,b,c;
405  
406 <  /* test if triangle (t0,t1,t2) overlaps cell triangle (v0,v1,v2) */
407 <  test = stri_intersect(t0,t1,t2,v0,v1,v2);
408 <
409 <  /* If triangles do not overlap: done */
410 <  if(!test)
411 <    return(FALSE);
412 <
413 <  /* if this is tree: recurse */
414 <  func(qtptr,arg);
415 <
416 <  if(QT_IS_TREE(*qtptr))
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 <     QT_SET_FLAG(*qtptr);
426 <     qtSubdivide_tri(v0,v1,v2,a,b,c);
427 <    qtApply_to_tri_cells(QT_NTH_CHILD_PTR(*qtptr,0),t0,t1,t2,v0,a,c,func,arg);
428 <    qtApply_to_tri_cells(QT_NTH_CHILD_PTR(*qtptr,1),t0,t1,t2,a,v1,b,func,arg);
429 <    qtApply_to_tri_cells(QT_NTH_CHILD_PTR(*qtptr,2),t0,t1,t2,c,b,v2,func,arg);
430 <    qtApply_to_tri_cells(QT_NTH_CHILD_PTR(*qtptr,3),t0,t1,t2,b,c,a,func,arg);
435 >    goto Lfunc_call;
436    }
437 < }
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 < int
443 < qtRemove_tri(qtptr,id,t0,t1,t2,v0,v1,v2)
444 < QUADTREE *qtptr;
445 < int id;
446 < FVECT t0,t1,t2;
447 < FVECT v0,v1,v2;
448 < {
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 <  int test;
460 <  int i;
461 <  FVECT a,b,c;
462 <  OBJECT os[QT_MAXSET+1];
463 <  
464 <  /* test if triangle (t0,t1,t2) overlaps cell triangle (v0,v1,v2) */
465 <  test = stri_intersect(t0,t1,t2,v0,v1,v2);
449 <
450 <  /* If triangles do not overlap: done */
451 <  if(!test)
452 <    return(FALSE);
453 <
454 <  /* if this is tree: recurse */
455 <  if(QT_IS_TREE(*qtptr))
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 <    qtSubdivide_tri(v0,v1,v2,a,b,c);
468 <    qtRemove_tri(QT_NTH_CHILD_PTR(*qtptr,0),id,t0,t1,t2,v0,a,c);
459 <    qtRemove_tri(QT_NTH_CHILD_PTR(*qtptr,1),id,t0,t1,t2,a,v1,b);
460 <    qtRemove_tri(QT_NTH_CHILD_PTR(*qtptr,2),id,t0,t1,t2,c,b,v2);
461 <    qtRemove_tri(QT_NTH_CHILD_PTR(*qtptr,3),id,t0,t1,t2,b,c,a);
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 <  else
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 <      if(QT_IS_EMPTY(*qtptr))
482 <      {
467 < #ifdef DEBUG    
468 <          eputs("qtRemove_tri(): triangle not found\n");
469 < #endif
470 <      }
471 <      /* remove id from set */
472 <      else
473 <      {
474 <          if(!qtinset(*qtptr,id))
475 <          {
476 < #ifdef DEBUG          
477 <              eputs("qtRemove_tri(): tri not in set\n");
478 < #endif
479 <          }
480 <          else
481 <          {
482 <            *qtptr = qtdelelem(*qtptr,id);
483 <        }
484 <      }
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 <  return(TRUE);
485 < }
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 <
523 < int
524 < move_to_nbr(b,db0,db1,db2,tptr)
525 < double b[3],db0,db1,db2;
526 < double *tptr;
527 < {
528 <  double t,dt;
529 <  int nbr;
530 <
531 <  nbr = -1;
532 <  /* Advance to next node */
500 <  if(!ZERO(db0) && db0 < 0.0)
501 <   {
502 <     t = -b[0]/db0;
503 <     nbr = 0;
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 <  else
506 <    t = FHUGE;
507 <  if(!ZERO(db1) && db1 < 0.0 )
534 >  if(!test_t2t0 && (e0 & 4))
535    {
536 <    dt = -b[1]/db1;
537 <    if( dt < t)
511 <    {
512 <      t = dt;
513 <      nbr = 1;
514 <    }
536 >    db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
537 >    TEST_INT(testl,testh,db,q1[1],b,bl,bh)
538    }
516  if(!ZERO(db2) && db2 < 0.0 )
517    {
518      dt = -b[2]/db2;
519      if( dt < t)
520      {
521        t = dt;
522        nbr = 2;
523      }
524    }
525  *tptr = t;
526  return(nbr);
527 }
539  
540 < int
541 < qtTrace_ray(qtptr,b,db0,db1,db2,orig,dir,func,arg1,arg2)
542 <   QUADTREE *qtptr;
543 <   double b[3],db0,db1,db2;
544 <   FVECT orig,dir;
545 <   int (*func)();
535 <   int *arg1,arg2;
536 < {
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  
538    int i,found;
539    QUADTREE *child;
540    int nbr,next;
541    double t;
542 #ifdef DEBUG_TEST_DRIVER
543    
544    FVECT a1,b1,c1;
545    int Pick_parent = Pick_cnt-1;
546    qtSubdivide_tri(Pick_v0[Pick_parent],Pick_v1[Pick_parent],
547                           Pick_v2[Pick_parent],a1,b1,c1);
547  
549 #endif
550    if(QT_IS_TREE(*qtptr))
551    {
552        /* Find the appropriate child and reset the coord */
553        i = bary_child(b);
548  
549 <        QT_SET_FLAG(*qtptr);
549 > /* ASSUMPTION: that triangle t0,t1,t2 intersects quad cell q0,q1,q2 */
550  
551 <        for(;;)
552 <        {
553 <           child = QT_NTH_CHILD_PTR(*qtptr,i);
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 <           if(i != 3)
562 <              nbr = qtTrace_ray(child,b,db0,db1,db2,orig,dir,func,arg1,arg2);
563 <           else
564 <               /* If the center cell- must flip direction signs */
565 <              nbr =qtTrace_ray(child,b,-db0,-db1,-db2,orig,dir,func,arg1,arg2);
566 <           if(nbr == QT_DONE)
567 <              return(nbr);
562 > int Find_id=0;
563  
564 <           /* If in same block: traverse */
565 <           if(i==3)
566 <              next = nbr;
567 <             else
568 <                if(nbr == i)
569 <                   next = 3;
570 <             else
571 <               {
572 <                 /* reset the barycentric coordinates in the parents*/
573 <                 bary_parent(b,i);
574 <                 /* Else pop up to parent and traverse from there */
575 <                 return(nbr);
576 <               }
577 <             bary_from_child(b,i,next);
578 <             i = next;
579 <         }
585 <    }
586 <    else
587 <   {
588 < #ifdef DEBUG_TEST_DRIVER
589 <           qtNth_child_tri(Pick_v0[Pick_parent],Pick_v1[Pick_parent],
590 <                           Pick_v2[Pick_parent],a1,b1,c1,i,
591 <                           Pick_v0[Pick_cnt],Pick_v1[Pick_cnt],
592 <                           Pick_v2[Pick_cnt]);
593 <           Pick_cnt++;
594 < #endif
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(func(qtptr,orig,dir,arg1,arg2) == QT_DONE)
582 <          return(QT_DONE);
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 <       /* Advance to next node */
600 <       /* NOTE: Optimize: should only have to check 1/2 */
601 <       nbr = move_to_nbr(b,db0,db1,db2,&t);
591 >    SIDES_GTR(t0,t1,t2,sa,sb,sc,a,b,c);
592  
593 <       if(nbr != -1)
594 <       {
595 <         b[0] += t * db0;
596 <         b[1] += t * db1;
597 <         b[2] += t * db2;
598 <       }
599 <       return(nbr);
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 <    
616 < }
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 < int
628 < qtRoot_trace_ray(qtptr,q0,q1,q2,orig,dir,func,arg1,arg2)
629 <   QUADTREE *qtptr;
630 <   FVECT q0,q1,q2;
631 <   FVECT orig,dir;
632 <   int (*func)();
633 <   int *arg1,arg2;
634 < {
635 <  int i,x,y,nbr;
636 <  QUADTREE *child;
637 <  FVECT n,c,i_pt,d;
638 <  double pd,b[3],db[3],t;
639 <    /* Determine if point lies within pyramid (and therefore
627 <       inside a spherical quadtree cell):GT_INTERIOR, on one of the
628 <       pyramid sides (and on cell edge):GT_EDGE(1,2 or 3),
629 <       or on pyramid vertex (and on cell vertex):GT_VERTEX(1,2, or 3).
630 <       For each triangle edge: compare the
631 <       point against the plane formed by the edge and the view center
632 <    */
633 <  i = point_in_stri(q0,q1,q2,orig);  
634 <    
635 <  /* Not in this triangle */
636 <  if(!i)
637 <     return(INVALID);
638 <  /* Project the origin onto the root node plane */
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 <  /* Find the intersection point of the origin */
642 <  tri_plane_equation(q0,q1,q2,n,&pd,FALSE);
643 <  intersect_vector_plane(orig,n,pd,NULL,i_pt);
644 <  /* project the dir as well */
645 <  VADD(c,orig,dir);
646 <  intersect_vector_plane(c,n,pd,&t,c);
647 <
648 <    /* map to 2d by dropping maximum magnitude component of normal */
649 <  i = max_index(n,NULL);
650 <  x = (i+1)%3;
651 <  y = (i+2)%3;
652 <  /* Calculate barycentric coordinates of orig */
653 <  bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],i_pt[x],i_pt[y],b);
654 <  /* Calculate barycentric coordinates of dir */
654 <  bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],c[x],c[y],db);
655 <  if(t < 0.0)
656 <     VSUB(db,b,db);
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 <     VSUB(db,db,b);
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 < #ifdef DEBUG_TEST_DRIVER
662 <    VCOPY(Pick_v0[Pick_cnt],q0);
663 <    VCOPY(Pick_v1[Pick_cnt],q1);
664 <    VCOPY(Pick_v2[Pick_cnt],q2);
665 <    Pick_cnt++;
666 < #endif
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 <      /* trace the ray starting with this node */
679 <    nbr = qtTrace_ray(qtptr,b,db[0],db[1],db[2],orig,dir,func,arg1,arg2);
680 <    return(nbr);
681 <    
682 < }
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 < qtVisit_tri_interior(qtptr,q0,q1,q2,t0,t1,t2,n,func,arg1,arg2,arg3)
675 <   QUADTREE *qtptr;
676 <   FVECT q0,q1,q2;
677 <   FVECT t0,t1,t2;
678 <   int n;
679 <   int (*func)();
680 <   int *arg1,arg2,*arg3;
681 < {
682 <    int i,found,test;
683 <    QUADTREE *child;
684 <    FVECT c0,c1,c2,a,b,c;
685 <    OBJECT os[QT_MAXSET+1],*optr;
686 <    int w;
687 <    
688 <    /* If qt Flag set, or qt vertices interior to t0t1t2-descend */
689 < tree_modified:
688 >    SIDES_GTR(t0,t1,t2,sa,sb,sc,a,b,c);
689  
690 <    if(QT_IS_TREE(*qtptr))
691 <    {  
692 <        if(QT_IS_FLAG(*qtptr) ||  point_in_stri(t0,t1,t2,q0))
693 <        {
694 <            QT_SET_FLAG(*qtptr);
695 <            qtSubdivide_tri(q0,q1,q2,a,b,c);
696 <            /* descend to children */
697 <            for(i=0;i < 4; i++)
698 <            {
699 <                child = QT_NTH_CHILD_PTR(*qtptr,i);
700 <                qtNth_child_tri(q0,q1,q2,a,b,c,i,c0,c1,c2);
702 <                qtVisit_tri_interior(child,c0,c1,c2,t0,t1,t2,n+1,
703 <                                     func,arg1,arg2,arg3);
704 <            }
705 <        }
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 <    else
702 >    if(sb==0)
703      {
704 <      /* NOTE THIS IN TRI TEST Could be replaced by a flag */
705 <      if(!QT_IS_EMPTY(*qtptr))
706 <      {
707 <         if(qtinset(*qtptr,arg2))
708 <           if(func(qtptr,q0,q1,q2,t0,t1,t2,n,arg1,arg2,arg3)==QT_MODIFIED)
709 <             goto tree_modified;
710 <           else
711 <             return;
717 <      }
718 <      if(point_in_stri(t0,t1,t2,q0) )
719 <          if(func(qtptr,q0,q1,q2,t0,t1,t2,n,arg1,arg2,arg3)==QT_MODIFIED)
720 <            goto tree_modified;
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 <
767 < /* NOTE: SINCE DIR could be unit: then we could use integer math */
768 < int
769 < qtVisit_tri_edges(qtptr,b,db0,db1,db2,
770 <                   db,wptr,t,sign,sfactor,func,arg1,arg2,arg3)
771 <   QUADTREE *qtptr;
772 <   double b[3],db0,db1,db2,db[3][3];
773 <   int *wptr;
774 <   double t[3];
775 <   int sign;
776 <   double sfactor;
739 <   int (*func)();
740 <   int *arg1,arg2,*arg3;
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 <    int i,found;
779 <    QUADTREE *child;
780 <    int nbr,next,w;
745 <    double t_l,t_g;
746 < #ifdef DEBUG_TEST_DRIVER
747 <    FVECT a1,b1,c1;
748 <    int Pick_parent = Pick_cnt-1;
749 <    qtSubdivide_tri(Pick_v0[Pick_parent],Pick_v1[Pick_parent],
750 <                           Pick_v2[Pick_parent],a1,b1,c1);
751 < #endif
752 <    if(QT_IS_TREE(*qtptr))
753 <    {
754 <        /* Find the appropriate child and reset the coord */
755 <        i = bary_child(b);
778 >  BCOORD a,b,c;
779 >  BCOORD va[3],vb[3],vc[3];
780 >  unsigned int sa,sb,sc;
781  
782 <        QT_SET_FLAG(*qtptr);
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 <        for(;;)
790 <        {
791 <          w = *wptr;
792 <           child = QT_NTH_CHILD_PTR(*qtptr,i);
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 <           if(i != 3)
765 <               nbr = qtVisit_tri_edges(child,b,db0,db1,db2,
766 <                                        db,wptr,t,sign,
767 <                                        sfactor*2.0,func,arg1,arg2,arg3);
768 <           else
769 <             /* If the center cell- must flip direction signs */
770 <             nbr = qtVisit_tri_edges(child,b,-db0,-db1,-db2,
771 <                                     db,wptr,t,1-sign,
772 <                                     sfactor*2.0,func,arg1,arg2,arg3);
796 >    SIDES_GTR(t0,t1,t2,sa,sb,sc,a,b,c);
797  
798 <           if(nbr == QT_DONE)
799 <             return(nbr);
800 <           if(*wptr != w)
801 <           {
802 <             w = *wptr;
803 <             db0 = db[w][0];db1 = db[w][1];db2 = db[w][2];
804 <             if(sign)
805 <               {  db0 *= -1.0;db1 *= -1.0; db2 *= -1.0;}
806 <           }
807 <           /* If in same block: traverse */
784 <           if(i==3)
785 <              next = nbr;
786 <             else
787 <                if(nbr == i)
788 <                   next = 3;
789 <             else
790 <               {
791 <                 /* reset the barycentric coordinates in the parents*/
792 <                 bary_parent(b,i);
793 <                 /* Else pop up to parent and traverse from there */
794 <                 return(nbr);
795 <               }
796 <           bary_from_child(b,i,next);
797 <           i = next;
798 <        }
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 <    else
809 >   if(sb==7)
810     {
811 < #ifdef DEBUG_TEST_DRIVER
812 <           qtNth_child_tri(Pick_v0[Pick_parent],Pick_v1[Pick_parent],
813 <                           Pick_v2[Pick_parent],a1,b1,c1,i,Pick_v0[Pick_cnt],
814 <                           Pick_v1[Pick_cnt],Pick_v2[Pick_cnt]);
815 <           Pick_cnt++;
816 < #endif
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 <       if(func(qtptr,arg1,arg2,arg3) == QT_DONE)
833 <          return(QT_DONE);
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 <       /* Advance to next node */
847 <       w = *wptr;
848 <       while(1)
849 <       {
850 <         nbr = move_to_nbr(b,db0,db1,db2,&t_l);
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  
818         t_g = t_l/sfactor;
819 #ifdef DEBUG
820         if(t[w] <= 0.0)
821           eputs("qtVisit_tri_edges():negative t\n");
822 #endif
823         if(t_g >= t[w])
824         {
825           if(w == 2)
826             return(QT_DONE);
827
828           b[0] += (t[w])*sfactor*db0;
829           b[1] += (t[w])*sfactor*db1;
830           b[2] += (t[w])*sfactor*db2;
831           w++;
832           db0 = db[w][0];
833           db1 = db[w][1];
834           db2 = db[w][2];
835           if(sign)
836          {  db0 *= -1.0;db1 *= -1.0; db2 *= -1.0;}
837         }
838       else
839         if(nbr != INVALID)
840         {
841           b[0] += t_l * db0;
842           b[1] += t_l * db1;
843           b[2] += t_l * db2;
844
845           t[w] -= t_g;
846           *wptr = w;
847           return(nbr);
848         }
849         else
850           return(INVALID);
851       }
852   }
853    
863   }
864  
865  
866 < int
867 < qtRoot_visit_tri_edges(qtptr,q0,q1,q2,tri,i_pt,wptr,func,arg1,arg2,arg3)
868 <   QUADTREE *qtptr;
869 <   FVECT q0,q1,q2;
870 <   FVECT tri[3],i_pt;
871 <   int *wptr;
872 <   int (*func)();
873 <   int *arg1,arg2,*arg3;
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 <  int x,y,z,nbr,w,i,j;
879 <  QUADTREE *child;
880 <  FVECT n,c,d,v[3];
869 <  double pd,b[4][3],db[3][3],et[3],t[3],exit_pt;
870 <    
871 <  w = *wptr;
878 >  BCOORD a,b,c;
879 >  BCOORD va[3],vb[3],vc[3];
880 >  unsigned int sa,sb,sc;
881  
882 <  /* Project the origin onto the root node plane */
883 <
884 <  /* Find the intersection point of the origin */
885 <  tri_plane_equation(q0,q1,q2,n,&pd,FALSE);
877 <  /* map to 2d by dropping maximum magnitude component of normal */
878 <  z = max_index(n,NULL);
879 <  x = (z+1)%3;
880 <  y = (z+2)%3;
881 <  /* Calculate barycentric coordinates for current vertex */
882 <  if(w != -1)
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 <    bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],i_pt[x],i_pt[y],b[3]);  
888 <    intersect_vector_plane(tri[w],n,pd,&(et[w]),v[w]);
889 <    bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[w][x],v[w][y],b[w]);  
890 <  }
891 <  else
892 <  /* Just starting: b[0] is the origin point: guaranteed to be valid b*/
893 <  {
891 <    w = 0;
892 <    intersect_vector_plane(tri[0],n,pd,&(et[0]),v[0]);
893 <    bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[0][x],v[0][y],b[0]);  
894 <    VCOPY(b[3],b[0]);
895 <  }
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 <  j = (w+1)%3;
899 <  intersect_vector_plane(tri[j],n,pd,&(et[j]),v[j]);
900 <  bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[j][x],v[j][y],b[j]);  
901 <  if(et[j] < 0.0)
902 <  {
903 <      VSUB(db[w],b[3],b[j]);
904 <      t[w] = FHUGE;
905 <  }
906 <  else
907 < {
908 <   /* NOTE: for stability: do not increment with ipt- use full dir and
909 <      calculate t: but for wrap around case: could get same problem?
910 <      */
911 <   VSUB(db[w],b[j],b[3]);
912 <   t[w] = 1.0;
913 <   move_to_nbr(b[3],db[w][0],db[w][1],db[w][2],&exit_pt);
914 <   if(exit_pt >= 1.0)
915 <   {
916 <     for(;j < 3;j++)
917 <      {
918 <          i = (j+1)%3;
919 <          if(i!= w)
920 <            {
921 <              intersect_vector_plane(tri[i],n,pd,&(et[i]),v[i]);
922 <              bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[i][x],
923 <                     v[i][y],b[i]);
924 <            }
925 <          if(et[i] < 0.0)
926 <             {
927 <                 VSUB(db[j],b[j],b[i]);
928 <                 t[j] = FHUGE;
929 <                 break;
930 <             }
931 <          else
932 <             {
933 <                 VSUB(db[j],b[i],b[j]);
934 <                 t[j] = 1.0;
935 <             }
936 <          move_to_nbr(b[j],db[j][0],db[j][1],db[j][2],&exit_pt);
937 <          if(exit_pt < 1.0)
938 <             break;
939 <      }
940 <   }
941 < }
942 <  *wptr = w;
943 <  /* trace the ray starting with this node */
944 <    nbr = qtVisit_tri_edges(qtptr,b[3],db[w][0],db[w][1],db[w][2],
945 <                             db,wptr,t,0,1.0,func,arg1,arg2,arg3);
946 <    if(nbr != INVALID && nbr != QT_DONE)
897 >    if(sa==0)
898      {
899 <      i_pt[x] = b[3][0]*q0[x] + b[3][1]*q1[x] + b[3][2]*q2[x];
900 <      i_pt[y] = b[3][0]*q0[y] + b[3][1]*q1[y] + b[3][2]*q2[y];
901 <      i_pt[z] = (-n[x]*i_pt[x] - n[y]*i_pt[y] -pd)/n[z];
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 <    return(nbr);
953 <    
954 < }
955 <
956 < int
957 < move_to_nbri(b,db0,db1,db2,tptr)
958 < BCOORD b[3];
959 < BDIR db0,db1,db2;
960 < TINT *tptr;
961 < {
962 <  TINT t,dt;
963 <  BCOORD bc;
964 <  int nbr;
965 <  
966 <  nbr = -1;
967 <  /* Advance to next node */
968 <  if(db0 < 0)
969 <   {
970 <     bc = MAXBCOORD*b[0];
971 <     t = bc/-db0;
972 <     nbr = 0;
973 <   }
974 <  else
975 <    t = HUGET;
976 <  if(db1 < 0)
977 <  {
978 <     bc = MAXBCOORD*b[1];
979 <     dt = bc/-db1;
980 <    if( dt < t)
908 >    if(sb==0)
909      {
910 <      t = dt;
911 <      nbr = 1;
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 <  }
920 <  if(db2 < 0)
921 <  {
922 <     bc = MAXBCOORD*b[2];
923 <     dt = bc/-db2;
924 <       if( dt < t)
925 <      {
926 <        t = dt;
927 <        nbr = 2;
928 <      }
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 <  *tptr = t;
931 <  return(nbr);
932 < }
933 < /* NOTE: SINCE DIR could be unit: then we could use integer math */
934 < int
935 < qtVisit_tri_edgesi(qtptr,b,db0,db1,db2,
936 <                   db,wptr,t,sign,sfactor,func,arg1,arg2,arg3)
937 <   QUADTREE *qtptr;
1004 <   BCOORD b[3];
1005 <   BDIR db0,db1,db2,db[3][3];
1006 <   int *wptr;
1007 <   TINT t[3];
1008 <   int sign;
1009 <   int sfactor;
1010 <   int (*func)();
1011 <   int *arg1,arg2,*arg3;
1012 < {
1013 <    int i,found;
1014 <    QUADTREE *child;
1015 <    int nbr,next,w;
1016 <    TINT t_g,t_l,t_i;
1017 < #ifdef DEBUG_TEST_DRIVER
1018 <    FVECT a1,b1,c1;
1019 <    int Pick_parent = Pick_cnt-1;
1020 <    qtSubdivide_tri(Pick_v0[Pick_parent],Pick_v1[Pick_parent],
1021 <                           Pick_v2[Pick_parent],a1,b1,c1);
1022 < #endif
1023 <    if(QT_IS_TREE(*qtptr))
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 <        /* Find the appropriate child and reset the coord */
940 <        i = baryi_child(b);
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 <        QT_SET_FLAG(*qtptr);
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  
1030        for(;;)
1031        {
1032          w = *wptr;
1033           child = QT_NTH_CHILD_PTR(*qtptr,i);
963  
1035           if(i != 3)
1036               nbr = qtVisit_tri_edgesi(child,b,db0,db1,db2,
1037                                        db,wptr,t,sign,
1038                                        sfactor+1,func,arg1,arg2,arg3);
1039           else
1040             /* If the center cell- must flip direction signs */
1041             nbr = qtVisit_tri_edgesi(child,b,-db0,-db1,-db2,
1042                                     db,wptr,t,1-sign,
1043                                     sfactor+1,func,arg1,arg2,arg3);
964  
965 <           if(nbr == QT_DONE)
966 <             return(nbr);
967 <           if(*wptr != w)
968 <           {
969 <             w = *wptr;
970 <             db0 = db[w][0];db1 = db[w][1];db2 = db[w][2];
971 <             if(sign)
972 <               {  db0 *= -1;db1 *= -1; db2 *= -1;}
973 <           }
974 <           /* If in same block: traverse */
975 <           if(i==3)
976 <              next = nbr;
977 <             else
978 <                if(nbr == i)
979 <                   next = 3;
980 <             else
981 <               {
982 <                 /* reset the barycentric coordinates in the parents*/
983 <                 baryi_parent(b,i);
984 <                 /* Else pop up to parent and traverse from there */
1065 <                 return(nbr);
1066 <               }
1067 <           baryi_from_child(b,i,next);
1068 <           i = next;
1069 <        }
1070 <    }
1071 <    else
1072 <   {
1073 < #ifdef DEBUG_TEST_DRIVER
1074 <           qtNth_child_tri(Pick_v0[Pick_parent],Pick_v1[Pick_parent],
1075 <                           Pick_v2[Pick_parent],a1,b1,c1,i,Pick_v0[Pick_cnt],
1076 <                           Pick_v1[Pick_cnt],Pick_v2[Pick_cnt]);
1077 <           Pick_cnt++;
1078 < #endif
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 <       if(func(qtptr,arg1,arg2,arg3) == QT_DONE)
987 <          return(QT_DONE);
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 <       /* Advance to next node */
1065 <       w = *wptr;
1066 <       while(1)
1067 <       {
1068 <           nbr = move_to_nbri(b,db0,db1,db2,&t_i);
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 <         t_g = t_i >> sfactor;
1090 <                
1091 <         if(t_g >= t[w])
1092 <         {
1093 <           if(w == 2)
1094 <             return(QT_DONE);
1082 >  return;
1083  
1084 <           /* The edge fits in the cell- therefore the result of shifting db by
1097 <              sfactor is guaranteed to be less than MAXBCOORD
1098 <            */
1099 <           /* Caution: (t[w]*db) must occur before divide by MAXBCOORD
1100 <              since t[w] will always be < MAXBCOORD
1101 <           */
1102 <           b[0] = b[0] + (t[w]*db0*(1 << sfactor))/MAXBCOORD;
1103 <           b[1] = b[1] + (t[w]*db1*(1 << sfactor))/MAXBCOORD;
1104 <           b[2] = b[2] + (t[w]*db2*(1 << sfactor))/MAXBCOORD;
1105 <           w++;
1106 <           db0 = db[w][0]; db1 = db[w][1]; db2 = db[w][2];
1107 <           if(sign)
1108 <           {  db0 *= -1;db1 *= -1; db2 *= -1;}
1109 <         }
1110 <       else
1111 <         if(nbr != INVALID)
1112 <         {
1113 <           /* Caution: (t_i*db) must occur before divide by MAXBCOORD
1114 <              since t_i will always be < MAXBCOORD
1115 <           */
1116 <           b[0] = b[0] + (t_i *db0) / MAXBCOORD;
1117 <           b[1] = b[1] + (t_i *db1) / MAXBCOORD;
1118 <           b[2] = b[2] + (t_i *db2) / MAXBCOORD;
1084 > Lfunc_call:
1085  
1086 <           t[w] -= t_g;
1087 <           *wptr = w;
1088 <           return(nbr);
1089 <         }
1124 <         else
1125 <           return(INVALID);
1126 <       }
1127 <   }    
1086 >  f.func(f.argptr,root,qt,n);
1087 >  if(!QT_IS_EMPTY(qt))
1088 >    QT_LEAF_SET_FLAG(qt);
1089 >
1090   }
1091  
1092  
1131 int
1132 qtRoot_visit_tri_edgesi(qtptr,q0,q1,q2,tri,i_pt,wptr,func,arg1,arg2,arg3)
1133   QUADTREE *qtptr;
1134   FVECT q0,q1,q2;
1135   FVECT tri[3],i_pt;
1136   int *wptr;
1137   int (*func)();
1138   int *arg1,arg2,*arg3;
1139 {
1140  int x,y,z,nbr,w,i,j;
1141  QUADTREE *child;
1142  FVECT n,c,d,v[3];
1143  double pd,b[4][3],db[3][3],et[3],exit_pt;
1144  BCOORD bi[3];
1145  TINT t[3];
1146  BDIR dbi[3][3];
1147  w = *wptr;
1093  
1094 <  /* Project the origin onto the root node plane */
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 <  t[0] = t[1] = t[2] = 0;
1124 <  /* Find the intersection point of the origin */
1125 <  tri_plane_equation(q0,q1,q2,n,&pd,FALSE);
1126 <  /* map to 2d by dropping maximum magnitude component of normal */
1127 <  z = max_index(n,NULL);
1128 <  x = (z+1)%3;
1129 <  y = (z+2)%3;
1130 <  /* Calculate barycentric coordinates for current vertex */
1131 <  if(w != -1)
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 <    bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],i_pt[x],i_pt[y],b[3]);  
1149 <    intersect_vector_plane(tri[w],n,pd,&(et[w]),v[w]);
1163 <    bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[w][x],v[w][y],b[w]);  
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 <  else
1152 <  /* Just starting: b[0] is the origin point: guaranteed to be valid b*/
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 <    w = 0;
1163 <    intersect_vector_plane(tri[0],n,pd,&(et[0]),v[0]);
1170 <    bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[0][x],v[0][y],b[0]);  
1171 <    VCOPY(b[3],b[0]);
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 <
1204 <  j = (w+1)%3;
1205 <  intersect_vector_plane(tri[j],n,pd,&(et[j]),v[j]);
1177 <  bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[j][x],v[j][y],b[j]);  
1178 <  if(et[j] < 0.0)
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 <      VSUB(db[w],b[3],b[j]);
1208 <      t[w] = HUGET;
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 <  else
1211 < {
1212 <   /* NOTE: for stability: do not increment with ipt- use full dir and
1213 <      calculate t: but for wrap around case: could get same problem?
1187 <      */
1188 <   VSUB(db[w],b[j],b[3]);
1189 <   /* Check if the point is out side of the triangle: if so t[w] =HUGET */
1190 <   if((fabs(b[j][0])>(FTINY+1.0)) ||(fabs(b[j][1])>(FTINY+1.0)) ||
1191 <      (fabs(b[j][2])>(FTINY+1.0)))
1192 <      t[w] = HUGET;
1193 <   else
1194 <   {
1195 <       /* The next point is in the triangle- so db values will be in valid
1196 <          range and t[w]= MAXT
1197 <        */  
1198 <       t[w] = MAXT;
1199 <       if(j != 0)
1200 <          for(;j < 3;j++)
1201 <             {
1202 <                 i = (j+1)%3;
1203 <                 if(i!= w)
1204 <                 {
1205 <                     intersect_vector_plane(tri[i],n,pd,&(et[i]),v[i]);
1206 <                     bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[i][x],
1207 <                            v[i][y],b[i]);
1208 <                 }
1209 <                 if(et[i] < 0.0)
1210 <                 {
1211 <                     VSUB(db[j],b[j],b[i]);
1212 <                     t[j] = HUGET;
1213 <                     break;
1214 <                 }
1215 <                 else
1216 <                 {
1217 <                     VSUB(db[j],b[i],b[j]);
1218 <                     if((fabs(b[j][0])>(FTINY+1.0)) ||
1219 <                        (fabs(b[j][1])>(FTINY+1.0)) ||
1220 <                        (fabs(b[j][2])>(FTINY+1.0)))
1221 <                        {
1222 <                            t[j] = HUGET;
1223 <                            break;
1224 <                        }
1225 <                     else
1226 <                        t[j] = MAXT;
1227 <                 }
1228 <             }
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   }
1231  *wptr = w;
1232  bary_dtol(b[3],db,bi,dbi,t);
1228  
1229 <  /* trace the ray starting with this node */
1230 <    nbr = qtVisit_tri_edgesi(qtptr,bi,dbi[w][0],dbi[w][1],dbi[w][2],
1231 <                             dbi,wptr,t,0,0,func,arg1,arg2,arg3);
1232 <    if(nbr != INVALID && nbr != QT_DONE)
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 <        b[3][0] = (double)bi[0]/(double)MAXBCOORD;
1249 <        b[3][1] = (double)bi[1]/(double)MAXBCOORD;
1250 <        b[3][2] = (double)bi[2]/(double)MAXBCOORD;
1251 <        i_pt[x] = b[3][0]*q0[x] + b[3][1]*q1[x] + b[3][2]*q2[x];
1252 <        i_pt[y] = b[3][0]*q0[y] + b[3][1]*q1[y] + b[3][2]*q2[y];
1253 <        i_pt[z] = (-n[x]*i_pt[x] - n[y]*i_pt[y] -pd)/n[z];
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 <    return(nbr);
1263 <    
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 <
1333 <
1334 <
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  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines