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.3 by gwlarson, Tue Aug 25 11:03:27 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 #include "object.h"
20  
21   QUADTREE  *quad_block[QT_MAX_BLK];              /* our quadtree */
22   static QUADTREE  quad_free_list = EMPTY;  /* freed octree nodes */
23   static QUADTREE  treetop = 0;           /* next free node */
24 < int4 *quad_flag;
24 > int4 *quad_flag= NULL;
25  
26 + #ifdef TEST_DRIVER
27 + extern FVECT Pick_v0[500],Pick_v1[500],Pick_v2[500];
28 + extern int Pick_cnt,Pick_tri,Pick_samp;
29 + extern FVECT Pick_point[500];
30 + extern int Pick_q[500];
31 +
32 + #endif
33 +
34 + qtremovelast(qt,id)
35 + QUADTREE qt;
36 + int id;
37 + {
38 +  if(qtqueryset(qt)[(*(qtqueryset(qt)))] != id)
39 +    error(CONSISTENCY,"not removed\n");
40 +  ((*(qtqueryset(qt)))--);
41 + }
42   QUADTREE
43   qtAlloc()                       /* allocate a quadtree */
44   {
# Line 41 | 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*sizeof(int4)));
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 54 | Line 71 | qtAlloc()                      /* allocate a quadtree */
71  
72   qtClearAllFlags()               /* clear all quadtree branch flags */
73   {
74 <        if (!treetop) return;
75 <        bzero((char *)quad_flag,
76 <                (QT_BLOCK(treetop-1)+1)*QT_BLOCK_SIZE/(8*sizeof(int4)));
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  
62
83   qtFree(qt)                      /* free a quadtree */
84     register QUADTREE  qt;
85   {
# Line 80 | 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          {
107              if (quad_block[i] == NULL)
# Line 88 | 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;
116          treetop = 0;
117   }
118  
97
119   QUADTREE
120 < qtCompress(qt)                  /* recursively combine nodes */
121 < register QUADTREE  qt;
120 > qtLocate(qt,bcoord)
121 > QUADTREE qt;
122 > BCOORD bcoord[3];
123   {
102    register int  i;
103    register QUADTREE  qres;
104
105    if (!QT_IS_TREE(qt))        /* not a tree */
106       return(qt);
107    qres = QT_NTH_CHILD(qt,0) = qtCompress(QT_NTH_CHILD(qt,0));
108    for (i = 1; i < 4; i++)
109       if((QT_NTH_CHILD(qt,i) = qtCompress(QT_NTH_CHILD(qt,i))) != qres)
110          qres = qt;
111    if(!QT_IS_TREE(qres))
112    {   /* all were identical leaves */
113        QT_NTH_CHILD(qt,0) = quad_free_list;
114        quad_free_list = qt;
115    }
116    return(qres);
117 }
118
119
120 QUADTREE
121 *qtLocate_leaf(qtptr,bcoord,t0,t1,t2)
122 QUADTREE *qtptr;
123 double bcoord[3];
124 FVECT t0,t1,t2;
125 {
124    int i;
127  QUADTREE *child;
128  FVECT a,b,c;
125  
126 <    if(QT_IS_TREE(*qtptr))
127 <    {  
128 <      i = bary2d_child(bcoord);
129 <      child = QT_NTH_CHILD_PTR(*qtptr,i);
130 <      if(t0)
131 <      {
132 <        qtSubdivide_tri(t0,t1,t2,a,b,c);
133 <        qtNth_child_tri(t0,t1,t2,a,b,c,i,t0,t1,t2);
138 <      }
139 <      return(qtLocate_leaf(child,bcoord,t0,t1,t2));
140 <    }
141 <    else
142 <      return(qtptr);
126 >  if(QT_IS_TREE(qt))
127 >  {  
128 >    i = bary_child(bcoord);
129 >
130 >    return(qtLocate(QT_NTH_CHILD(qt,i),bcoord));
131 >  }
132 >  else
133 >    return(qt);
134   }
135  
145
146
136   int
137 < qtLeaf_add_tri_from_pt(qtptr,bcoord,id,v0,v1,v2,n)
138 < QUADTREE *qtptr;
139 < double bcoord[3];
140 < int id;
152 < FVECT v0,v1,v2;
153 < int n;
137 > move_to_nbr(b,db0,db1,db2,tptr)
138 > BCOORD b[3];
139 > BDIR db0,db1,db2;
140 > double *tptr;
141   {
142 <  int i;
143 <  QUADTREE *child;
144 <  OBJECT os[MAXSET+1],*optr;
158 <  int found;
159 <  FVECT r0,r1,r2;
142 >  double t,dt;
143 >  BCOORD bc;
144 >  int nbr;
145    
146 <  if(QT_IS_TREE(*qtptr))
147 <  {  
148 <    QT_SET_FLAG(*qtptr);
149 <    i = bary2d_child(bcoord);
150 <    child = QT_NTH_CHILD_PTR(*qtptr,i);
151 <    return(qtLeaf_add_tri_from_pt(child,bcoord,id,v0,v1,v2,++n));
152 <  }
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 <      /* If this leave node emptry- create a new set */
168 <      if(QT_IS_EMPTY(*qtptr))
169 <        *qtptr = qtaddelem(*qtptr,id);
170 <      else
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 <          qtgetset(os,*qtptr);
177 <          /* If the set is too large: subdivide */
177 <          if(QT_SET_CNT(os) < QT_SET_THRESHOLD)
178 <            *qtptr = qtaddelem(*qtptr,id);
179 <          else
180 <          {
181 <            if (n < QT_MAX_LEVELS)
182 <            {
183 <                 /* If set size exceeds threshold: subdivide cell and
184 <                    reinsert set tris into cell
185 <                    */
186 <                 n++;
187 <                 qtfreeleaf(*qtptr);
188 <                 qtSubdivide(qtptr);
189 <                 QT_SET_FLAG(*qtptr);
190 <                 found = qtLeaf_add_tri_from_pt(qtptr,bcoord,id,v0,v1,v2,n);
191 < #if 0
192 <                 if(!found)
193 <                 {
194 < #ifdef TEST_DRIVER    
195 <      HANDLE_ERROR("qtAdd_tri():Found in parent but not children\n");
196 < #else
197 <                   eputs("qtAdd_tri():Found in parent but not children\n");
198 < #endif
199 <                 }
200 < #endif
201 <                 for(optr = &(os[1]),i = QT_SET_CNT(os); i > 0; i--)
202 <                 {
203 <                   id = QT_SET_NEXT_ELEM(optr);
204 <                   qtTri_verts_from_id(id,r0,r1,r2);
205 <                   found= qtLeaf_add_tri_from_pt(qtptr,bcoord,id,v0,v1,v2,++n);
206 < #ifdef DEBUG
207 <                 if(!found)
208 <                    eputs("qtAdd_tri():Reinsert-in parent but not children\n");
209 < #endif
210 <               }
211 <             }
212 <            else
213 <              if(QT_SET_CNT(os) < QT_MAX_SET)
214 <                {
215 <                  *qtptr = qtaddelem(*qtptr,id);
216 <                }
217 <              else
218 <                {
219 < #ifdef DEBUG
220 <                    eputs("qtAdd_tri():two many levels\n");
221 < #endif
222 <                    return(FALSE);
223 <                }
224 <          }
176 >        t = dt;
177 >        nbr = 2;
178        }
179 <  }
180 <  return(TRUE);
179 >    }
180 >  *tptr = t;
181 >  return(nbr);
182   }
183  
184 <
185 < int
186 < qtAdd_tri_from_point(qtptr,v0,v1,v2,pt,id)
187 < QUADTREE *qtptr;
188 < FVECT v0,v1,v2;
189 < FVECT pt;
190 < int id;
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 <    char d,w;
194 <    int i,x,y;
195 <    QUADTREE *child;
196 <    QUADTREE qt;
242 <    FVECT i_pt,n,a,b,c,r0,r1,r2;
243 <    double pd,bcoord[3];
244 <    OBJECT os[MAXSET+1],*optr;
245 <    int found;
246 <        
247 <    /* Determine if point lies within pyramid (and therefore
248 <       inside a spherical quadtree cell):GT_INTERIOR, on one of the
249 <       pyramid sides (and on cell edge):GT_EDGE(1,2 or 3),
250 <       or on pyramid vertex (and on cell vertex):GT_VERTEX(1,2, or 3).
251 <       For each triangle edge: compare the
252 <       point against the plane formed by the edge and the view center
253 <    */
254 <    d = test_single_point_against_spherical_tri(v0,v1,v2,pt,&w);  
193 >    int i,found;
194 >    QUADTREE child;
195 >    int nbr,next,w;
196 >    double t;
197  
198 <    /* Not in this triangle */
199 <    if(!d)
200 <      return(FALSE);
198 >    if(QT_IS_TREE(qt))
199 >    {
200 >      /* Find the appropriate child and reset the coord */
201 >      i = bary_child(b);
202  
203 <    /* Will return lowest level triangle containing point: It the
204 <       point is on an edge or vertex: will return first associated
205 <       triangle encountered in the child traversal- the others can
206 <       be derived using triangle adjacency information
207 <    */
208 <    if(QT_IS_TREE(*qtptr))
209 <    {  
210 <      QT_SET_FLAG(*qtptr);
268 <      /* Find the intersection point */
269 <      tri_plane_equation(v0,v1,v2,n,&pd,FALSE);
270 <      intersect_vector_plane(pt,n,pd,NULL,i_pt);
203 >      for(;;)
204 >      {
205 >        child = QT_NTH_CHILD(qt,i);
206 >        if(i != 3)
207 >          qtTrace_ray(child,b,db0,db1,db2,nextptr,sign,sfactor+1,func,f);
208 >        else
209 >          /* If the center cell- must flip direction signs */
210 >          qtTrace_ray(child,b,-db0,-db1,-db2,nextptr,1-sign,sfactor+1,func,f);
211  
212 <      i = max_index(n);
213 <      x = (i+1)%3;
214 <      y = (i+2)%3;
215 <      /* Calculate barycentric coordinates of i_pt */
216 <      bary2d(v0[x],v0[y],v1[x],v1[y],v2[x],v2[y],i_pt[x],i_pt[y],bcoord);
217 <
218 <      i = bary2d_child(bcoord);
219 <      child = QT_NTH_CHILD_PTR(*qtptr,i);
220 <      /* NOTE: Optimize: only subdivide for specified child */
221 <      qtSubdivide_tri(v0,v1,v2,a,b,c);
222 <      qtNth_child_tri(v0,v1,v2,a,b,c,i,v0,v1,v2);
223 <      return(qtLeaf_add_tri_from_pt(child,bcoord,id,v0,v1,v2,1));
212 >        if(QT_FLAG_IS_DONE(*f))
213 >          return;
214 >        /* If in same block: traverse */
215 >        if(i==3)
216 >          next = *nextptr;
217 >        else
218 >          if(*nextptr == i)
219 >            next = 3;
220 >          else
221 >         {
222 >           /* reset the barycentric coordinates in the parents*/
223 >           bary_parent(b,i);
224 >           /* Else pop up to parent and traverse from there */
225 >           return(qt);
226 >         }
227 >        bary_from_child(b,i,next);
228 >        i = next;
229 >      }
230      }
231      else
232     {
233 <      /* If this leave node emptry- create a new set */
234 <      if(QT_IS_EMPTY(*qtptr))
235 <        *qtptr = qtaddelem(*qtptr,id);
236 <      else
237 <      {
238 <          qtgetset(os,*qtptr);
239 <          /* If the set is too large: subdivide */
240 <          if(QT_SET_CNT(os) < QT_SET_THRESHOLD)
241 <            *qtptr = qtaddelem(*qtptr,id);
242 <          else
243 <          {
244 <                 /* If set size exceeds threshold: subdivide cell and
245 <                    reinsert set tris into cell
246 <                    */
247 <                 qtfreeleaf(*qtptr);
248 <                 qtSubdivide(qtptr);
249 <                 found = qtLeaf_add_tri_from_pt(qtptr,bcoord,id,v0,v1,v2,1);
250 < #if 0
251 <                 if(!found)
252 <                 {
253 < #ifdef TEST_DRIVER    
254 <      HANDLE_ERROR("qtAdd_tri():Found in parent but not children\n");
255 < #else
256 <                   eputs("qtAdd_tri():Found in parent but not children\n");
257 < #endif
258 <                 }
259 < #endif
260 <                 for(optr = &(os[1]),i = QT_SET_CNT(os); i > 0; i--)
261 <                 {
262 <                   id = QT_SET_NEXT_ELEM(optr);
263 <                   qtTri_verts_from_id(id,r0,r1,r2);
264 <                   found=qtAdd_tri(qtptr,id,r0,r1,r2,v0,v1,v2,1);
265 < #ifdef DEBUG
266 <                 if(!found)
267 <                    eputs("qtAdd_tri():Reinsert-in parent but not children\n");
268 < #endif
269 <               }
270 <             }
271 <      }
233 > #ifdef TEST_DRIVER
234 >       if(Pick_cnt < 500)
235 >          Pick_q[Pick_cnt++]=qt;
236 > #endif;
237 >       F_FUNC(func)(qt,F_ARGS(func),f);
238 >     if(QT_FLAG_IS_DONE(*f))
239 >       return;
240 >     /* Advance to next node */
241 >     nbr = move_to_nbr(b,db0,db1,db2,&t);
242 >
243 >     if(nbr==-1)
244 >     {
245 >       QT_FLAG_SET_DONE(*f);
246 >       return;
247 >     }
248 >     b[0] += (BCOORD)(t *db0);
249 >     b[1] += (BCOORD)(t *db1);
250 >     b[2] += (BCOORD)(t *db2);
251 >     *nextptr = nbr;
252 >     return;
253 >    
254 >   }
255 > }    
256 >
257 >
258 >
259 >
260 >
261 >
262 >
263 >
264 > #define TEST_INT(tl,th,d,q0,q1,h,l) \
265 >                  tl=d>q0;th=d<q1; if(tl&&th) goto Lfunc_call; \
266 >                 if(tl) if(l) goto Lfunc_call; else h=TRUE; \
267 >                 if(th) if(h) goto Lfunc_call; else l = TRUE; \
268 >                 if(th) if(h) goto Lfunc_call; else l = TRUE;
269 >
270 > /* Leaf node: Do definitive test */
271 > QUADTREE
272 > qtLeaf_insert_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
273 >                 scale, s0,s1,s2,sq0,sq1,sq2,f,n)
274 > int root;
275 > QUADTREE qt;
276 > BCOORD q0[3],q1[3],q2[3];
277 > BCOORD t0[3],t1[3],t2[3];
278 > BCOORD dt10[3],dt21[3],dt02[3];
279 > unsigned int scale,s0,s1,s2,sq0,sq1,sq2;
280 > FUNC f;
281 > int n;
282 > {
283 >  double db;
284 >  unsigned int e0,e1,e2;
285 >  char al,ah,bl,bh,cl,ch,testl,testh;
286 >  char test_t0t1,test_t1t2,test_t2t0;
287 >  BCOORD a,b,c;
288 >
289 >  /* First check if can trivial accept: if vertex in cell */
290 >  if(s0 & s1 & s2)
291 >  {
292 >    goto Lfunc_call;
293    }
294 <  return(TRUE);
294 >  /* Assumption: Could not trivial reject*/
295 >  /* IF any coords lie on edge- must be in if couldnt reject */
296 >  a = q1[0];b= q0[1]; c= q0[2];
297 >  if(t0[0]== a || t0[1] == b || t0[2] == c)
298 >  {
299 >    goto Lfunc_call;
300 >  }
301 >  if(t1[0]== a || t1[1] == b || t1[2] == c)
302 >  {
303 >    goto Lfunc_call;
304 >  }
305 >  if(t2[0]== a || t2[1] == b || t2[2] == c)
306 >  {
307 >    goto Lfunc_call;
308 >  }
309 >  /* Test for edge crossings */
310 >  /* Test t0t1,t1t2,t2t0 against a */
311 >  /* Calculate edge crossings */
312 >  e0  = (s0 ^ ((s0 >> 1) | (s0 << 2 & 4)));
313 >  /* See if edge can be trivially rejected from intersetion testing */
314 >  test_t0t1 = !(((s0 & 6)==0) || ((s1 & 6)==0)|| ((s2 & 6)==0) ||
315 >       ((sq0 & 6)==6) ||((sq1 & 6)==6)|| ((sq2 & 6)==6));
316 >  bl=bh=0;
317 >  if(test_t0t1 && (e0 & 2) )
318 >  {
319 >    /* Must do double calculation to avoid overflow */
320 >    db = t0[1] + dt10[1]*((double)(a-t0[0]))/dt10[0];
321 >    TEST_INT(testl,testh,db,b,q1[1],bl,bh)
322 >  }
323 >  test_t1t2= !(((s0 & 3)==0) || ((s1 & 3)==0)|| ((s2 & 3)==0) ||
324 >       ((sq0 & 3)==3) ||((sq1 & 3)==3)|| ((sq2 & 3)==3));
325 >  if(test_t1t2 && (e0 & 1))
326 >  {    /* test t1t2 against a */
327 >      db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
328 >      TEST_INT(testl,testh,db,b,q1[1],bl,bh)
329 >  }
330 >  test_t2t0 = !(((s0 & 5)==0) || ((s1 & 5)==0)|| ((s2 & 5)==0) ||
331 >       ((sq0 & 5)==5) ||((sq1 & 5)==5)|| ((sq2 & 5)==5));
332 >  if(test_t2t0 && (e0 & 4))
333 >  {
334 >      db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
335 >      TEST_INT(testl,testh,db,b,q1[1],bl,bh)
336 >  }
337 >  e1  = (s1 ^ ((s1 >> 1) | (s1 << 2 & 4)));
338 >  cl = ch = 0;
339 >  if(test_t0t1 && (e1 & 2))
340 >  {/* test t0t1 against b */
341 >      db = t0[2] + dt10[2]*((double)(b-t0[1]))/dt10[1];
342 >      TEST_INT(testl,testh,db,c,q2[2],cl,ch)
343 >  }
344 >  if(test_t1t2 && (e1 & 1))
345 >  {/* test t1t2 against b */
346 >    db = t1[2] + dt21[2]*((double)(q0[1] - t1[1]))/dt21[1];
347 >    TEST_INT(testl,testh,db,c,q2[2],cl,ch)
348 >  }
349 >  if(test_t2t0 && (e1 & 4))
350 >  {/* test t2t0 against b */
351 >    db = t2[2] + dt02[2]*((double)(q0[1] - t2[1]))/dt02[1];
352 >    TEST_INT(testl,testh,db,c,q2[2],cl,ch)
353 >  }
354 >
355 >  /* test edges against c */
356 >  e2  = (s2 ^ ((s2 >> 1) | (s2 << 2 & 4)));
357 >  al = ah = 0;
358 >  if(test_t0t1 && (e2 & 2))
359 >  { /* test t0t1 against c */
360 >    db = t0[0] + dt10[0]*((double)(c-t0[2]))/dt10[2];
361 >    TEST_INT(testl,testh,db,a,q0[0],al,ah)
362 >   }
363 >  if(test_t1t2 && (e2 & 1))
364 >  {
365 >    db = t1[0] + dt21[0]*((double)(c - t1[2]))/dt21[2];
366 >    TEST_INT(testl,testh,db,a,q0[0],al,ah)
367 >  }
368 >  if(test_t2t0 && (e2 & 4))
369 >  { /* test t2t0 against c */
370 >    db = t2[0] + dt02[0]*((double)(c - t2[2]))/dt02[2];
371 >    TEST_INT(testl,testh,db,a,q0[0],al,ah)
372 >  }
373 >  /* Only remaining case is if some edge trivially rejected */
374 >  if(!e0 || !e1 || !e2)
375 >    return(qt);
376 >
377 >  /* Only one/none got tested - pick either of other two/any two */
378 >  /* Only need to test one edge */
379 >  if(!test_t0t1 && (e0 & 2))
380 >  {
381 >     db = t0[1] + dt10[1]*((double)(a-t0[0]))/dt10[0];
382 >     TEST_INT(testl,testh,db,b,q1[1],bl,bh)
383 >  }
384 >  if(!test_t1t2 && (e0 & 1))
385 >    {/* test t1t2 against a */
386 >      db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
387 >      TEST_INT(testl,testh,db,b,q1[1],bl,bh)
388 >   }
389 >  if(!test_t2t0 && (e0 & 4))
390 >  {
391 >    db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
392 >    TEST_INT(testl,testh,db,b,q1[1],bl,bh)
393 >  }
394 >
395 >  return(qt);
396 >
397 > Lfunc_call:
398 >  qt = f.func(f.argptr,root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
399 >              s0,s1,s2,sq0,sq1,sq2,0,f,n);
400 >  return(qt);
401 >
402   }
403  
404  
405 +
406 + /* Leaf node: Do definitive test */
407   QUADTREE
408 < *qtRoot_point_locate(qtptr,v0,v1,v2,pt,t0,t1,t2)
409 < QUADTREE *qtptr;
410 < FVECT v0,v1,v2;
411 < FVECT pt;
412 < FVECT t0,t1,t2;
413 < {
414 <    char d,w;
415 <    int i,x,y;
416 <    QUADTREE *child;
417 <    QUADTREE qt;
418 <    FVECT n,i_pt,a,b,c;
419 <    double pd,bcoord[3];
408 > qtLeaf_insert_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
409 >                 scale, s0,s1,s2,sq0,sq1,sq2,f,n)
410 > int root;
411 > QUADTREE qt;
412 > BCOORD q0[3],q1[3],q2[3];
413 > BCOORD t0[3],t1[3],t2[3];
414 > BCOORD dt10[3],dt21[3],dt02[3];
415 > unsigned int scale,s0,s1,s2,sq0,sq1,sq2;
416 > FUNC f;
417 > int n;
418 > {
419 >  double db;
420 >  unsigned int e0,e1,e2;
421 >  BCOORD a,b,c;
422 >  double p0[2], p1[2],cp;
423 >  char al,ah,bl,bh,cl,ch;
424 >  char testl,testh,test_t0t1,test_t1t2,test_t2t0;
425 >  unsigned int ls0,ls1,ls2;
426 >  
427 >  
428 >  /* May have gotten passed trivial reject if one/two vertices are ON */
429 >  a = q1[0];b= q0[1]; c= q0[2];
430 >  SIDES_LESS(t0,t1,t2,ls0,ls1,ls2,a,b,c);
431 >  
432 >  /* First check if can trivial accept: if vertex in cell */
433 >  if(ls0 & ls1 & ls2)
434 >  {
435 >    goto Lfunc_call;
436 >  }
437 >  if(ls0==0 || ls1 == 0 || ls2 ==0)
438 >    return(qt);
439 >  /* Assumption: Could not trivial reject*/
440 >  /* IF any coords lie on edge- must be in if couldnt reject */
441  
442 <    /* Determine if point lies within pyramid (and therefore
443 <       inside a spherical quadtree cell):GT_INTERIOR, on one of the
444 <       pyramid sides (and on cell edge):GT_EDGE(1,2 or 3),
445 <       or on pyramid vertex (and on cell vertex):GT_VERTEX(1,2, or 3).
446 <       For each triangle edge: compare the
447 <       point against the plane formed by the edge and the view center
448 <    */
449 <    d = test_single_point_against_spherical_tri(v0,v1,v2,pt,&w);  
442 >  if(t0[0]== a || t0[1] == b || t0[2] == c)
443 >  {
444 >    goto Lfunc_call;
445 >  }
446 >  if(t1[0]== a || t1[1] == b || t1[2] == c)
447 >  {
448 >    goto Lfunc_call;
449 >  }
450 >  if(t2[0]== a || t2[1] == b || t2[2] == c)
451 >  {
452 >    goto Lfunc_call;
453 >  }
454 >  /* Test for edge crossings */
455 >  /* Test t0t1 against a,b,c */
456 >  /* First test if t0t1 can be trivially rejected */
457 >  /* If both edges are outside bounds- dont need to test */
458 >  
459 >  /* Test t0t1,t1t2,t2t0 against a */
460 >  test_t0t1 = !(((ls0 & 6)==0) || ((ls1 & 6)==0)|| ((ls2 & 6)==0) ||
461 >       ((sq0 & 6)==0) ||((sq1 & 6)==0)|| ((sq2 & 6)==0));
462 >  e0  = (ls0 ^ ((ls0 >> 1) | (ls0 << 2 & 4)));
463 >  bl=bh=0;
464 >  /* Test t0t1,t1t2,t2t0 against a */
465 >  if(test_t0t1 && (e0 & 2) )
466 >  {
467 >      db = t0[1] + dt10[1]*((double)(a-t0[0])/dt10[0]);
468 >      TEST_INT(testl,testh,db,q1[1],b,bl,bh)
469 >  }
470 >  test_t1t2= !(((ls0 & 3)==0) || ((ls1 & 3)==0)|| ((ls2 & 3)==0) ||
471 >       ((sq0 & 3)==0) ||((sq1 & 3)==0)|| ((sq2 & 3)==0));
472 >  if(test_t1t2 && (e0 & 1))
473 >  {    /* test t1t2 against a */
474 >      db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
475 >      TEST_INT(testl,testh,db,q1[1],b,bl,bh)
476 >  }
477 > test_t2t0 = !(((ls0 & 5)==0) || ((ls1 & 5)==0)|| ((ls2 & 5)==0) ||
478 >       ((sq0 & 5)==0) ||((sq1 & 5)==0)|| ((sq2 & 5)==0));
479 >  if(test_t2t0 && (e0 & 4))
480 >  {
481 >      db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
482 >      TEST_INT(testl,testh,db,q1[1],b,bl,bh)
483 >  }
484 >  cl = ch = 0;
485 >  e1  = (ls1 ^ ((ls1 >> 1) | (ls1 << 2 & 4)));
486 >  if(test_t0t1 && (e1 & 2))
487 >  {/* test t0t1 against b */
488 >      db = t0[2] + dt10[2]*(((double)(b-t0[1]))/dt10[1]);
489 >      TEST_INT(testl,testh,db,q1[2],c,cl,ch)
490 >  }
491 >  if(test_t1t2 && (e1 & 1))
492 >  {/* test t1t2 against b */
493 >    db = t1[2] + dt21[2]*((double)(b - t1[1]))/dt21[1];
494 >    TEST_INT(testl,testh,db,q1[2],c,cl,ch)
495 >  }
496 >  if(test_t2t0 && (e1 & 4))
497 >  {/* test t2t0 against b */
498 >    db = t2[2] + dt02[2]*((double)(b - t2[1]))/dt02[1];
499 >    TEST_INT(testl,testh,db,q1[2],c,cl,ch)
500 >  }
501 >  al = ah = 0;
502 >  e2  = (ls2 ^ ((ls2 >> 1) | (ls2 << 2 & 4)));
503 >  if(test_t0t1 && (e2 & 2))
504 >  { /* test t0t1 against c */
505 >    db = t0[0] + dt10[0]*(((double)(c-t0[2]))/dt10[2]);
506 >    TEST_INT(testl,testh,db,q0[0],a,al,ah)
507 >   }
508 >  if(test_t1t2 && (e2 & 1))
509 >  {
510 >    db = t1[0] + dt21[0]*((double)(c - t1[2]))/dt21[2];
511 >    TEST_INT(testl,testh,db,q0[0],a,al,ah)
512 >  }
513 >  if(test_t2t0 && (e2 & 4))
514 >  { /* test t2t0 against c */
515 >    db = t2[0] + dt02[0]*((double)(c - t2[2]))/dt02[2];
516 >    TEST_INT(testl,testh,db,q0[0],a,al,ah)
517 >  }
518 >  /* Only remaining case is if some edge trivially rejected */
519 >  if(!e0 || !e1 || !e2)
520 >    return(qt);
521  
522 <    /* Not in this triangle */
523 <    if(!d)
524 <    {
525 <      return(NULL);
526 <    }
522 >  /* Only one/none got tested - pick either of other two/any two */
523 >  /* Only need to test one edge */
524 >  if(!test_t0t1 && (e0 & 2))
525 >  {
526 >     db = t0[1] + dt10[1]*((double)(a-t0[0]))/dt10[0];
527 >     TEST_INT(testl,testh,db,q1[1],b,bl,bh)
528 >  }
529 >  if(!test_t1t2 && (e0 & 1))
530 >    {/* test t1t2 against a */
531 >      db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
532 >      TEST_INT(testl,testh,db,q1[1],b,bl,bh)
533 >   }
534 >  if(!test_t2t0 && (e0 & 4))
535 >  {
536 >    db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
537 >    TEST_INT(testl,testh,db,q1[1],b,bl,bh)
538 >  }
539  
540 <    /* Will return lowest level triangle containing point: It the
541 <       point is on an edge or vertex: will return first associated
542 <       triangle encountered in the child traversal- the others can
543 <       be derived using triangle adjacency information
544 <    */
545 <    if(QT_IS_TREE(*qtptr))
366 <    {  
367 <      /* Find the intersection point */
368 <      tri_plane_equation(v0,v1,v2,n,&pd,FALSE);
369 <      intersect_vector_plane(pt,n,pd,NULL,i_pt);
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  
371      i = max_index(n);
372      x = (i+1)%3;
373      y = (i+2)%3;
374      /* Calculate barycentric coordinates of i_pt */
375      bary2d(v0[x],v0[y],v1[x],v1[y],v2[x],v2[y],i_pt[x],i_pt[y],bcoord);
547  
377      i = bary2d_child(bcoord);
378      child = QT_NTH_CHILD_PTR(*qtptr,i);
379      if(t0)
380      {
381        qtSubdivide_tri(v0,v1,v2,a,b,c);
382        qtNth_child_tri(v0,v1,v2,a,b,c,i,t0,t1,t2);
383      }
384      return(qtLocate_leaf(child,bcoord,t0,t1,t2));
385    }
386    else
387      return(qtptr);
388 }
548  
549 < int
550 < qtPoint_in_tri(qtptr,v0,v1,v2,pt,type,which)
551 < QUADTREE *qtptr;
552 < FVECT v0,v1,v2;
553 < FVECT pt;
554 < char *type,*which;
549 > /* ASSUMPTION: that triangle t0,t1,t2 intersects quad cell q0,q1,q2 */
550 >
551 > /*-------q2--------- sq2
552 >        / \
553 > s1     /sc \ s0
554 >     qb_____qa
555 >     / \   / \
556 > \sq0/sa \ /sb \   /sq1
557 > \ q0____qc____q1/
558 >  \             /
559 >   \     s2    /
560 > */
561 >
562 > int Find_id=0;
563 >
564 > QUADTREE
565 > qtInsert_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
566 >            s0,s1,s2,sq0,sq1,sq2,f,n)
567 > int root;
568 > QUADTREE qt;
569 > BCOORD q0[3],q1[3],q2[3];
570 > BCOORD t0[3],t1[3],t2[3];
571 > BCOORD dt10[3],dt21[3],dt02[3];
572 > BCOORD scale;
573 > unsigned int s0,s1,s2,sq0,sq1,sq2;
574 > FUNC f;
575 > int n;
576   {
577 <    OBJECT os[MAXSET+1],*optr;
578 <    char d,w;
579 <    int i,id;
400 <    FVECT p0,p1,p2;
577 >  BCOORD a,b,c;
578 >  BCOORD va[3],vb[3],vc[3];
579 >  unsigned int sa,sb,sc;
580  
581 <    qtptr = qtRoot_point_locate(qtptr,v0,v1,v2,pt,NULL,NULL,NULL);
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 <    if(!qtptr || QT_IS_EMPTY(*qtptr))
592 <       return(EMPTY);
593 <    
407 <    /* Get the set */
408 <    qtgetset(os,*qtptr);
409 <    for (i = QT_SET_CNT(os),optr = QT_SET_PTR(os); i > 0; i--)
591 >    SIDES_GTR(t0,t1,t2,sa,sb,sc,a,b,c);
592 >
593 >    if(sa==7)
594      {
595 <        /* Find the triangle that pt falls in (NOTE:FOR now return first 1) */
596 <        id = QT_SET_NEXT_ELEM(optr);
597 <        qtTri_verts_from_id(id,p0,p1,p2);
598 <        d = test_single_point_against_spherical_tri(p0,p1,p2,pt,&w);  
599 <        if(d)
600 <        {
601 <          if(type)
602 <            *type = d;
419 <          if(which)
420 <            *which = w;
421 <          return(id);
422 <        }
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 <    return(EMPTY);
605 < }
604 >   if(sb==7)
605 >   {
606 >     va[0] = q1[0];
607 >     vc[2] = q0[2];
608 >     va[1] = vc[1] = b;
609 >     va[2] = c;
610 >     vc[0] = a;
611 >     QT_NTH_CHILD(qt,1) = qtInsert_tri(root,QT_NTH_CHILD(qt,1),vc,q1,va,
612 >             t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n+1);
613 >     return(qt);
614 >   }
615 >   if(sc==7)
616 >   {
617 >     va[0] = q1[0];
618 >     vb[1] = q0[1];
619 >     va[1] = b;
620 >     va[2] = vb[2] = c;
621 >     vb[0] = a;
622 >     QT_NTH_CHILD(qt,2) = qtInsert_tri(root,QT_NTH_CHILD(qt,2),vb,va,
623 >       q2,t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n+1);
624 >     return(qt);
625 >   }
626  
627 < QUADTREE
628 < qtSubdivide(qtptr)
629 < QUADTREE *qtptr;
630 < {
631 <  QUADTREE node;
632 <  node = qtAlloc();
633 <  QT_CLEAR_CHILDREN(node);
634 <  *qtptr = node;
635 <  return(node);
627 >   va[0] = q1[0];
628 >   vb[1] = q0[1];
629 >   vc[2] = q0[2];
630 >   va[1] = vc[1] = b;
631 >   va[2] = vb[2] = c;
632 >   vb[0] = vc[0] = a;
633 >   /* If outside of all edges: only need to Visit 3  */
634 >   if(sa==0 && sb==0 && sc==0)
635 >   {
636 >      QT_NTH_CHILD(qt,3) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,3),va,vb,
637 >       vc,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,sb,sc,s0,s1,s2,f,n+1);
638 >      return(qt);
639 >   }
640 >
641 >   if(sa)
642 >     QT_NTH_CHILD(qt,0) = qtInsert_tri(root,QT_NTH_CHILD(qt,0),q0,vc,vb,t0,
643 >          t1,t2,dt10,dt21,dt02,scale>>1,sa,s1,s2,sq0,sb,sc,f,n+1);
644 >   if(sb)
645 >     QT_NTH_CHILD(qt,1) = qtInsert_tri(root,QT_NTH_CHILD(qt,1),vc,q1,va,t0,
646 >              t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n+1);
647 >   if(sc)
648 >        QT_NTH_CHILD(qt,2) = qtInsert_tri(root,QT_NTH_CHILD(qt,2),vb,va,q2,t0,
649 >              t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n+1);
650 >   QT_NTH_CHILD(qt,3) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,3),va,vb,vc,t0,
651 >             t1,t2,dt10,dt21,dt02,scale>>1,sa,sb,sc,s0,s1,s2,f,n+1);
652 >   return(qt);
653 >  }
654 >  /* Leaf node: Do definitive test */
655 >  else
656 >    return(qt = qtLeaf_insert_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
657 >                         scale,s0,s1,s2,sq0,sq1,sq2,f,n));
658   }
659  
660  
661   QUADTREE
662 < qtSubdivide_nth_child(qt,n)
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 <  QUADTREE node;
674 >  BCOORD a,b,c;
675 >  BCOORD va[3],vb[3],vc[3];
676 >  unsigned int sa,sb,sc;
677  
678 <  node = qtSubdivide(&(QT_NTH_CHILD(qt,n)));
679 <  
680 <  return(node);
681 < }
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 < /* for triangle v0-v1-v2- returns a,b,c: children are:
688 >    SIDES_GTR(t0,t1,t2,sa,sb,sc,a,b,c);
689  
690 <        v2                     0: v0,a,c
691 <        /\                     1: a,v1,b                  
692 <       /2 \                    2: c,b,v2
693 <     c/____\b                  3: b,c,a
694 <     /\    /\  
695 <    /0 \3 /1 \
696 <  v0____\/____\v1
460 <        a
461 < */
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 < qtSubdivide_tri(v0,v1,v2,a,b,c)
699 < FVECT v0,v1,v2;
700 < FVECT a,b,c;
701 < {
702 <    EDGE_MIDPOINT_VEC3(a,v0,v1);
703 <    EDGE_MIDPOINT_VEC3(b,v1,v2);
704 <    EDGE_MIDPOINT_VEC3(c,v2,v0);
705 < }
698 >      QT_NTH_CHILD(qt,0) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,0),q0,vc,
699 >          vb,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,s1,s2,sq0,sb,sc,f,n+1);
700 >      return(qt);
701 >    }
702 >    if(sb==0)
703 >    {
704 >      va[0] = q1[0];
705 >      vc[2] = q0[2];
706 >      va[1] = vc[1] = b;
707 >      va[2] = c;
708 >      vc[0] = a;
709 >      QT_NTH_CHILD(qt,1) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,1),vc,q1,va,
710 >         t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n+1);
711 >      return(qt);
712 >    }
713 >    if(sc==0)
714 >    {
715 >      va[0] = q1[0];
716 >      vb[1] = q0[1];
717 >      va[1] = b;
718 >      va[2] = vb[2] = c;
719 >      vb[0] = a;
720 >      QT_NTH_CHILD(qt,2) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,2),vb,va,
721 >         q2,t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n+1);
722 >      return(qt);
723 >    }
724 >    va[0] = q1[0];
725 >    vb[1] = q0[1];
726 >    vc[2] = q0[2];
727 >    va[1] = vc[1] = b;
728 >    va[2] = vb[2] = c;
729 >    vb[0] = vc[0] = a;
730 >    /* If outside of all edges: only need to Visit 3  */
731 >    if(sa==7 && sb==7 && sc==7)
732 >    {
733 >      QT_NTH_CHILD(qt,3) = qtInsert_tri(root,QT_NTH_CHILD(qt,3),va,vb,
734 >           vc,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,sb,sc,s0,s1,s2,f,n+1);
735 >      return(qt);
736 >    }
737 >    if(sa!=7)
738 >      QT_NTH_CHILD(qt,0) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,0),q0,vc,vb,
739 >           t0,t1,t2,dt10,dt21,dt02,scale>>1,sa,s1,s2,sq0,sb,sc,f,n+1);
740 >    if(sb!=7)
741 >      QT_NTH_CHILD(qt,1) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,1),vc,q1,va,
742 >           t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n+1);
743 >    if(sc!=7)
744 >      QT_NTH_CHILD(qt,2) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,2),vb,va,q2,
745 >           t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n+1);
746  
747 < qtNth_child_tri(v0,v1,v2,a,b,c,i,r0,r1,r2)
748 < FVECT v0,v1,v2;
749 < FVECT a,b,c;
475 < int i;
476 < FVECT r0,r1,r2;
477 < {
478 <  switch(i){
479 <  case 0:  
480 <  VCOPY(r0,v0); VCOPY(r1,a);    VCOPY(r2,c);
481 <    break;
482 <  case 1:  
483 <  VCOPY(r0,a); VCOPY(r1,v1);    VCOPY(r2,b);
484 <    break;
485 <  case 2:  
486 <  VCOPY(r0,c); VCOPY(r1,b);    VCOPY(r2,v2);
487 <    break;
488 <  case 3:  
489 <  VCOPY(r0,b); VCOPY(r1,c);    VCOPY(r2,a);
490 <    break;
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 < /* Add triangle "id" to all leaf level cells that are children of
758 < quadtree pointed to by "qtptr" with cell vertices "t1,t2,t3"
759 < that it overlaps (vertex and edge adjacencies do not count
760 < as overlapping). If the addition of the triangle causes the cell to go over
761 < threshold- the cell is split- and the triangle must be recursively inserted
762 < into the new child cells: it is assumed that "v1,v2,v3" are normalized
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 < int
767 < qtRoot_add_tri(qtptr,id,t0,t1,t2,v0,v1,v2,n)
768 < QUADTREE *qtptr;
769 < int id;
770 < FVECT t0,t1,t2;
771 < FVECT v0,v1,v2;
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 <  char test;
779 <  int found;
778 >  BCOORD a,b,c;
779 >  BCOORD va[3],vb[3],vc[3];
780 >  unsigned int sa,sb,sc;
781  
782 <  test = spherical_tri_intersect(t0,t1,t2,v0,v1,v2);
783 <  if(!test)
784 <    return(FALSE);
785 <  
786 <  found = qtAdd_tri(qtptr,id,t0,t1,t2,v0,v1,v2,n);
787 <  return(found);
519 < }
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 < int
790 < qtRoot_add_tri_from_point(qtptr,id,t0,t1,t2,v0,v1,v2,n)
791 < QUADTREE *qtptr;
792 < int id;
793 < FVECT t0,t1,t2;
794 < FVECT v0,v1,v2;
527 < int n;
528 < {
529 <  char test;
530 <  int found;
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 <  test = spherical_tri_intersect(t0,t1,t2,v0,v1,v2);
797 <  if(!test)
798 <    return(FALSE);
799 <  
800 <  found = qtAdd_tri_from_point(qtptr,id,t0,t1,t2,v0,v1,v2,n);
801 <  return(found);
796 >    SIDES_GTR(t0,t1,t2,sa,sb,sc,a,b,c);
797 >
798 >    if(sa==7)
799 >    {
800 >      vb[1] = q0[1];
801 >      vc[2] = q0[2];
802 >      vc[1] = b;
803 >      vb[2] = c;
804 >      vb[0] = vc[0] = a;
805 >      qtVisit_tri(root,QT_NTH_CHILD(qt,0),q0,vc,
806 >          vb,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,s1,s2,sq0,sb,sc,f,n-1);
807 >      return;
808 >    }
809 >   if(sb==7)
810 >   {
811 >     va[0] = q1[0];
812 >     vc[2] = q0[2];
813 >     va[1] = vc[1] = b;
814 >     va[2] = c;
815 >     vc[0] = a;
816 >     qtVisit_tri(root,QT_NTH_CHILD(qt,1),vc,q1,va,
817 >             t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n-1);
818 >     return;
819 >   }
820 >   if(sc==7)
821 >   {
822 >     va[0] = q1[0];
823 >     vb[1] = q0[1];
824 >     va[1] = b;
825 >     va[2] = vb[2] = c;
826 >     vb[0] = a;
827 >     qtVisit_tri(root,QT_NTH_CHILD(qt,2),vb,va,
828 >       q2,t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n-1);
829 >     return;
830 >   }
831 >
832 >   va[0] = q1[0];
833 >   vb[1] = q0[1];
834 >   vc[2] = q0[2];
835 >   va[1] = vc[1] = b;
836 >   va[2] = vb[2] = c;
837 >   vb[0] = vc[0] = a;
838 >   /* If outside of all edges: only need to Visit 3  */
839 >   if(sa==0 && sb==0 && sc==0)
840 >   {
841 >     qtVisit_tri_rev(root,QT_NTH_CHILD(qt,3),va,vb,
842 >       vc,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,sb,sc,s0,s1,s2,f,n-1);
843 >      return;
844 >   }
845 >
846 >   if(sa)
847 >     qtVisit_tri(root,QT_NTH_CHILD(qt,0),q0,vc,vb,t0,
848 >          t1,t2,dt10,dt21,dt02,scale>>1,sa,s1,s2,sq0,sb,sc,f,n-1);
849 >   if(sb)
850 >     qtVisit_tri(root,QT_NTH_CHILD(qt,1),vc,q1,va,t0,
851 >              t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n-1);
852 >   if(sc)
853 >     qtVisit_tri(root,QT_NTH_CHILD(qt,2),vb,va,q2,t0,
854 >              t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n-1);
855 >   qtVisit_tri_rev(root,QT_NTH_CHILD(qt,3),va,vb,vc,t0,
856 >             t1,t2,dt10,dt21,dt02,scale>>1,sa,sb,sc,s0,s1,s2,f,n-1);
857 >  }
858 >  /* Leaf node: Do definitive test */
859 >  else
860 >    qtLeaf_visit_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
861 >                         scale,s0,s1,s2,sq0,sq1,sq2,f,n);
862 >
863   }
864  
865 < int
866 < qtAdd_tri(qtptr,id,t0,t1,t2,v0,v1,v2,n)
867 < QUADTREE *qtptr;
868 < int id;
869 < FVECT t0,t1,t2;
870 < FVECT v0,v1,v2;
865 >
866 > qtVisit_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
867 >            s0,s1,s2,sq0,sq1,sq2,f,n)
868 > int root;
869 > QUADTREE qt;
870 > BCOORD q0[3],q1[3],q2[3];
871 > BCOORD t0[3],t1[3],t2[3];
872 > BCOORD dt10[3],dt21[3],dt02[3];
873 > BCOORD scale;
874 > unsigned int s0,s1,s2,sq0,sq1,sq2;
875 > FUNC f;
876   int n;
877   {
878 <  
879 <  char test;
880 <  int i,index;
551 <  FVECT a,b,c;
552 <  OBJECT os[MAXSET+1],*optr;
553 <  QUADTREE qt;
554 <  int found;
555 <  FVECT r0,r1,r2;
878 >  BCOORD a,b,c;
879 >  BCOORD va[3],vb[3],vc[3];
880 >  unsigned int sa,sb,sc;
881  
882 <  found = 0;
883 <  /* if this is tree: recurse */
884 <  if(QT_IS_TREE(*qtptr))
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 <    n++;
888 <    qtSubdivide_tri(v0,v1,v2,a,b,c);
889 <    test = spherical_tri_intersect(t0,t1,t2,v0,a,c);
890 <    if(test)
891 <      found |= qtAdd_tri(QT_NTH_CHILD_PTR(*qtptr,0),id,t0,t1,t2,v0,a,c,n);
892 <    test = spherical_tri_intersect(t0,t1,t2,a,v1,b);
893 <    if(test)
568 <      found |= qtAdd_tri(QT_NTH_CHILD_PTR(*qtptr,1),id,t0,t1,t2,a,v1,b,n);
569 <    test = spherical_tri_intersect(t0,t1,t2,c,b,v2);
570 <    if(test)
571 <      found |= qtAdd_tri(QT_NTH_CHILD_PTR(*qtptr,2),id,t0,t1,t2,c,b,v2,n);
572 <    test = spherical_tri_intersect(t0,t1,t2,b,c,a);
573 <    if(test)
574 <      found |= qtAdd_tri(QT_NTH_CHILD_PTR(*qtptr,3),id,t0,t1,t2,b,c,a,n);
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 < #if 0
896 <    if(!found)
895 >    SIDES_GTR(t0,t1,t2,sa,sb,sc,a,b,c);
896 >
897 >    if(sa==0)
898      {
899 < #ifdef TEST_DRIVER    
900 <      HANDLE_ERROR("qtAdd_tri():Found in parent but not children\n");
901 < #else
902 <      eputs("qtAdd_tri():Found in parent but not children\n");
903 < #endif
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 < #endif
908 >    if(sb==0)
909 >    {
910 >      va[0] = q1[0];
911 >      vc[2] = q0[2];
912 >      va[1] = vc[1] = b;
913 >      va[2] = c;
914 >      vc[0] = a;
915 >      qtVisit_tri_rev(root,QT_NTH_CHILD(qt,1),vc,q1,va,
916 >         t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n-1);
917 >      return;
918 >    }
919 >    if(sc==0)
920 >    {
921 >      va[0] = q1[0];
922 >      vb[1] = q0[1];
923 >      va[1] = b;
924 >      va[2] = vb[2] = c;
925 >      vb[0] = a;
926 >      qtVisit_tri_rev(root,QT_NTH_CHILD(qt,2),vb,va,
927 >         q2,t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n-1);
928 >      return;
929 >    }
930 >    va[0] = q1[0];
931 >    vb[1] = q0[1];
932 >    vc[2] = q0[2];
933 >    va[1] = vc[1] = b;
934 >    va[2] = vb[2] = c;
935 >    vb[0] = vc[0] = a;
936 >    /* If outside of all edges: only need to Visit 3  */
937 >    if(sa==7 && sb==7 && sc==7)
938 >    {
939 >     qtVisit_tri(root,QT_NTH_CHILD(qt,3),va,vb,
940 >           vc,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,sb,sc,s0,s1,s2,f,n-1);
941 >      return;
942 >    }
943 >    if(sa!=7)
944 >      qtVisit_tri_rev(root,QT_NTH_CHILD(qt,0),q0,vc,vb,
945 >           t0,t1,t2,dt10,dt21,dt02,scale>>1,sa,s1,s2,sq0,sb,sc,f,n-1);
946 >    if(sb!=7)
947 >      qtVisit_tri_rev(root,QT_NTH_CHILD(qt,1),vc,q1,va,
948 >           t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n-1);
949 >    if(sc!=7)
950 >      qtVisit_tri_rev(root,QT_NTH_CHILD(qt,2),vb,va,q2,
951 >           t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n-1);
952 >
953 >    qtVisit_tri(root,QT_NTH_CHILD(qt,3),va,vb,vc,t0,t1,
954 >              t2,dt10,dt21,dt02,scale>>1,sa,sb,sc,s0,s1,s2,f,n-1);
955 >    return;
956    }
957 +  /* Leaf node: Do definitive test */
958    else
959 <  {
960 <      /* If this leave node emptry- create a new set */
590 <      if(QT_IS_EMPTY(*qtptr))
591 <        *qtptr = qtaddelem(*qtptr,id);
592 <      else
593 <      {
594 <          qtgetset(os,*qtptr);
595 <          /* If the set is too large: subdivide */
596 <          if(QT_SET_CNT(os) < QT_SET_THRESHOLD)
597 <            *qtptr = qtaddelem(*qtptr,id);
598 <          else
599 <          {
600 <            if (n < QT_MAX_LEVELS)
601 <            {
602 <                 /* If set size exceeds threshold: subdivide cell and
603 <                    reinsert set tris into cell
604 <                    */
605 <                 n++;
606 <                 qtfreeleaf(*qtptr);
607 <                 qtSubdivide(qtptr);
608 <                 found = qtAdd_tri(qtptr,id,t0,t1,t2,v0,v1,v2,n);
609 < #if 0
610 <                 if(!found)
611 <                 {
612 < #ifdef TEST_DRIVER    
613 <      HANDLE_ERROR("qtAdd_tri():Found in parent but not children\n");
614 < #else
615 <                   eputs("qtAdd_tri():Found in parent but not children\n");
616 < #endif
617 <                 }
618 < #endif
619 <                 for(optr = &(os[1]),i = QT_SET_CNT(os); i > 0; i--)
620 <                 {
621 <                   id = QT_SET_NEXT_ELEM(optr);
622 <                   qtTri_verts_from_id(id,r0,r1,r2);
623 <                   found=qtAdd_tri(qtptr,id,r0,r1,r2,v0,v1,v2,n);
624 < #ifdef DEBUG
625 <                 if(!found)
626 <                    eputs("qtAdd_tri():Reinsert-in parent but not children\n");
627 < #endif
628 <               }
629 <             }
630 <            else
631 <              if(QT_SET_CNT(os) < QT_MAX_SET)
632 <                {
633 <                  *qtptr = qtaddelem(*qtptr,id);
634 < #if 0
635 <                  {
636 <              int k;
637 <              qtgetset(os,*qtptr);
638 <              printf("\n%d:\n",os[0]);
639 <              for(k=1; k <= os[0];k++)
640 <                 printf("%d ",os[k]);
641 <              printf("\n");
642 <          }
643 < #endif            
644 <                  /*
645 <                    insertelem(os,id);
646 <                    *qtptr = fullnode(os);
647 <                  */
648 <                }
649 <              else
650 <                {
651 < #ifdef DEBUG
652 <                    eputs("qtAdd_tri():two many levels\n");
653 < #endif
654 <                    return(FALSE);
655 <                }
656 <          }
657 <      }
658 <  }
659 <  return(TRUE);
959 >    qtLeaf_visit_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
960 >                         scale,s0,s1,s2,sq0,sq1,sq2,f,n);
961   }
962  
963  
663 int
664 qtApply_to_tri_cells(qtptr,t0,t1,t2,v0,v1,v2,func,arg)
665 QUADTREE *qtptr;
666 FVECT t0,t1,t2;
667 FVECT v0,v1,v2;
668 int (*func)();
669 char *arg;
670 {
671  char test;
672  FVECT a,b,c;
964  
965 <  /* test if triangle (t0,t1,t2) overlaps cell triangle (v0,v1,v2) */
966 <  test = spherical_tri_intersect(t0,t1,t2,v0,v1,v2);
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 triangles do not overlap: done */
987 <  if(!test)
988 <    return(FALSE);
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 <  /* if this is tree: recurse */
1065 <  if(QT_IS_TREE(*qtptr))
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 <    qtSubdivide_tri(v0,v1,v2,a,b,c);
1069 <    qtApply_to_tri_cells(QT_NTH_CHILD_PTR(*qtptr,0),t0,t1,t2,v0,a,c,func,arg);
686 <    qtApply_to_tri_cells(QT_NTH_CHILD_PTR(*qtptr,1),t0,t1,t2,a,v1,b,func,arg);
687 <    qtApply_to_tri_cells(QT_NTH_CHILD_PTR(*qtptr,2),t0,t1,t2,c,b,v2,func,arg);
688 <    qtApply_to_tri_cells(QT_NTH_CHILD_PTR(*qtptr,3),t0,t1,t2,b,c,a,func,arg);
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 <  else
1072 <    return(func(qtptr,arg));
1071 >  if(!test_t1t2 && (e0 & 1))
1072 >    {/* test t1t2 against a */
1073 >      db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
1074 >      TEST_INT(testl,testh,db,b,q1[1],bl,bh)
1075 >   }
1076 >  if(!test_t2t0 && (e0 & 4))
1077 >  {
1078 >    db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
1079 >    TEST_INT(testl,testh,db,b,q1[1],bl,bh)
1080 >  }
1081 >
1082 >  return;
1083 >
1084 > Lfunc_call:
1085 >
1086 >  f.func(f.argptr,root,qt,n);
1087 >  if(!QT_IS_EMPTY(qt))
1088 >    QT_LEAF_SET_FLAG(qt);
1089 >
1090   }
1091  
1092  
1093 < int
1094 < qtRemove_tri(qtptr,id,t0,t1,t2,v0,v1,v2)
1095 < QUADTREE *qtptr;
1096 < int id;
1097 < FVECT t0,t1,t2;
1098 < FVECT v0,v1,v2;
1099 < {
1093 >
1094 > /* Leaf node: Do definitive test */
1095 > QUADTREE
1096 > qtLeaf_visit_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
1097 >                 scale, s0,s1,s2,sq0,sq1,sq2,f,n)
1098 > int root;
1099 > QUADTREE qt;
1100 > BCOORD q0[3],q1[3],q2[3];
1101 > BCOORD t0[3],t1[3],t2[3];
1102 > BCOORD dt10[3],dt21[3],dt02[3];
1103 > unsigned int scale,s0,s1,s2,sq0,sq1,sq2;
1104 > FUNC f;
1105 > int n;
1106 > {
1107 >  double db;
1108 >  unsigned int e0,e1,e2;
1109 >  BCOORD a,b,c;
1110 >  double p0[2], p1[2],cp;
1111 >  char al,ah,bl,bh,cl,ch;
1112 >  char testl,testh,test_t0t1,test_t1t2,test_t2t0;
1113 >  unsigned int ls0,ls1,ls2;
1114    
1115 <  char test;
1116 <  int i;
1117 <  FVECT a,b,c;
706 <  OBJECT os[MAXSET+1];
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 <  /* test if triangle (t0,t1,t2) overlaps cell triangle (v0,v1,v2) */
1120 <  test = spherical_tri_intersect(t0,t1,t2,v0,v1,v2);
1119 >  /* First check if can trivial accept: if vertex in cell */
1120 >  if(ls0 & ls1 & ls2)
1121 >    goto Lfunc_call;
1122  
1123 <  /* If triangles do not overlap: done */
1124 <  if(!test)
1125 <    return(FALSE);
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 this is tree: recurse */
1129 <  if(QT_IS_TREE(*qtptr))
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 <    qtSubdivide_tri(v0,v1,v2,a,b,c);
1149 <    qtRemove_tri(QT_NTH_CHILD_PTR(*qtptr,0),id,t0,t1,t2,v0,a,c);
720 <    qtRemove_tri(QT_NTH_CHILD_PTR(*qtptr,1),id,t0,t1,t2,a,v1,b);
721 <    qtRemove_tri(QT_NTH_CHILD_PTR(*qtptr,2),id,t0,t1,t2,c,b,v2);
722 <    qtRemove_tri(QT_NTH_CHILD_PTR(*qtptr,3),id,t0,t1,t2,b,c,a);
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
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 <      if(QT_IS_EMPTY(*qtptr))
1162 >      db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
1163 >      TEST_INT(testl,testh,db,q1[1],b,bl,bh)
1164 >  }
1165 >  cl = ch = 0;
1166 >  e1  = (ls1 ^ ((ls1 >> 1) | (ls1 << 2 & 4)));
1167 >  if(test_t0t1 && (e1 & 2))
1168 >  {/* test t0t1 against b */
1169 >      db = t0[2] + dt10[2]*(((double)(b-t0[1]))/dt10[1]);
1170 >      TEST_INT(testl,testh,db,q1[2],c,cl,ch)
1171 >  }
1172 >  if(test_t1t2 && (e1 & 1))
1173 >  {/* test t1t2 against b */
1174 >    db = t1[2] + dt21[2]*((double)(b - t1[1]))/dt21[1];
1175 >    TEST_INT(testl,testh,db,q1[2],c,cl,ch)
1176 >  }
1177 >  if(test_t2t0 && (e1 & 4))
1178 >  {/* test t2t0 against b */
1179 >    db = t2[2] + dt02[2]*((double)(b - t2[1]))/dt02[1];
1180 >    TEST_INT(testl,testh,db,q1[2],c,cl,ch)
1181 >  }
1182 >  al = ah = 0;
1183 >  e2  = (ls2 ^ ((ls2 >> 1) | (ls2 << 2 & 4)));
1184 >  if(test_t0t1 && (e2 & 2))
1185 >  { /* test t0t1 against c */
1186 >    db = t0[0] + dt10[0]*(((double)(c-t0[2]))/dt10[2]);
1187 >    TEST_INT(testl,testh,db,q0[0],a,al,ah)
1188 >   }
1189 >  if(test_t1t2 && (e2 & 1))
1190 >  {
1191 >    db = t1[0] + dt21[0]*((double)(c - t1[2]))/dt21[2];
1192 >    TEST_INT(testl,testh,db,q0[0],a,al,ah)
1193 >  }
1194 >  if(test_t2t0 && (e2 & 4))
1195 >  { /* test t2t0 against c */
1196 >    db = t2[0] + dt02[0]*((double)(c - t2[2]))/dt02[2];
1197 >    TEST_INT(testl,testh,db,q0[0],a,al,ah)
1198 >  }
1199 >  /* Only remaining case is if some edge trivially rejected */
1200 >  if(!e0 || !e1 || !e2)
1201 >    return;
1202 >
1203 >  /* Only one/none got tested - pick either of other two/any two */
1204 >  /* Only need to test one edge */
1205 >  if(!test_t0t1 && (e0 & 2))
1206 >  {
1207 >     db = t0[1] + dt10[1]*((double)(a-t0[0]))/dt10[0];
1208 >     TEST_INT(testl,testh,db,q1[1],b,bl,bh)
1209 >  }
1210 >  if(!test_t1t2 && (e0 & 1))
1211 >    {/* test t1t2 against a */
1212 >      db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
1213 >      TEST_INT(testl,testh,db,q1[1],b,bl,bh)
1214 >   }
1215 >  if(!test_t2t0 && (e0 & 4))
1216 >  {
1217 >    db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
1218 >    TEST_INT(testl,testh,db,q1[1],b,bl,bh)
1219 >  }
1220 >
1221 >  return;
1222 >
1223 > Lfunc_call:
1224 >  f.func(f.argptr,root,qt,n);
1225 >  if(!QT_IS_EMPTY(qt))
1226 >    QT_LEAF_SET_FLAG(qt);
1227 > }
1228 >
1229 >
1230 > QUADTREE
1231 > qtInsert_point(root,qt,parent,q0,q1,q2,bc,scale,f,n,doneptr)
1232 > int root;
1233 > QUADTREE qt,parent;
1234 > BCOORD q0[3],q1[3],q2[3],bc[3],scale;
1235 > FUNC f;
1236 > int n,*doneptr;
1237 > {
1238 >  BCOORD a,b,c;
1239 >  BCOORD va[3],vb[3],vc[3];
1240 >
1241 >  if(QT_IS_TREE(qt))
1242 >  {  
1243 >    a = q1[0] + scale;
1244 >    b = q0[1] + scale;
1245 >    c = q0[2] + scale;
1246 >    if(bc[0] > a)
1247 >    {
1248 >      vc[0] = a; vc[1] = b; vc[2] = q0[2];
1249 >      vb[0] = a; vb[1] = q0[1]; vb[2] = c;
1250 >      QT_NTH_CHILD(qt,0) = qtInsert_point(root,QT_NTH_CHILD(qt,0),
1251 >                                  qt,q0,vc,vb,bc,scale>>1,f,n+1,doneptr);
1252 >      if(!*doneptr)
1253        {
1254 < #ifdef DEBUG    
1255 <          eputs("qtRemove_tri(): triangle not found\n");
1256 < #endif
1257 <      }
1258 <      /* remove id from set */
1259 <      else
1254 >        f.func_after(f.argptr,QT_NTH_CHILD(qt,1),f,doneptr);
1255 >        if(!*doneptr)
1256 >          f.func_after(f.argptr,QT_NTH_CHILD(qt,2),f,doneptr);
1257 >        if(!*doneptr)
1258 >          f.func_after(f.argptr,QT_NTH_CHILD(qt,3),f,doneptr);
1259 >      }      
1260 >      return(qt);
1261 >    }
1262 >    if(bc[1] > b)
1263 >    {
1264 >      vc[0] = a; vc[1] = b; vc[2] = q0[2];
1265 >      va[0] = q1[0]; va[1] = b; va[2] = c;
1266 >      QT_NTH_CHILD(qt,1) =qtInsert_point(root,QT_NTH_CHILD(qt,1),
1267 >                                 qt,vc,q1,va,bc,scale >>1,f,n+1,doneptr);
1268 >      if(!*doneptr)
1269        {
1270 <          qtgetset(os,*qtptr);
1271 <          if(!inset(os,id))
1272 <          {
1273 < #ifdef DEBUG          
1274 <              eputs("qtRemove_tri(): tri not in set\n");
1275 < #endif
1276 <          }
1277 <          else
1278 <          {
1279 <            *qtptr = qtdelelem(*qtptr,id);
1280 <        }
1281 <      }
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 <  return(TRUE);
1312 >  else
1313 >  {
1314 >    qt = f.func(f.argptr,root,qt,parent,q0,q1,q2,bc,scale,0,f,n,doneptr);
1315 >    return(qt);
1316 >  }
1317   }
1318  
1319  
1320 + QUADTREE
1321 + qtInsert_point_rev(root,qt,parent,q0,q1,q2,bc,scale,f,n,doneptr)
1322 + int root;
1323 + QUADTREE qt,parent;
1324 + BCOORD q0[3],q1[3],q2[3],bc[3];
1325 + BCOORD scale;
1326 + FUNC f;
1327 + int n,*doneptr;
1328 + {
1329 +  BCOORD a,b,c;
1330 +  BCOORD va[3],vb[3],vc[3];
1331 +
1332 +  if(QT_IS_TREE(qt))
1333 +  {  
1334 +    a = q1[0] - scale;
1335 +    b = q0[1] - scale;
1336 +    c = q0[2] - scale;
1337 +    if(bc[0] < a)
1338 +    {
1339 +      vc[0] = a; vc[1] = b; vc[2] = q0[2];
1340 +      vb[0] = a; vb[1] = q0[1]; vb[2] = c;
1341 +      QT_NTH_CHILD(qt,0) = qtInsert_point_rev(root,QT_NTH_CHILD(qt,0),
1342 +                                  qt,q0,vc,vb,bc,scale>>1,f,n+1,doneptr);
1343 +      if(!*doneptr)
1344 +      {
1345 +        f.func_after(f.argptr,QT_NTH_CHILD(qt,1),f,doneptr);
1346 +        if(!*doneptr)
1347 +          f.func_after(f.argptr,QT_NTH_CHILD(qt,2),f,doneptr);
1348 +        if(!*doneptr)
1349 +          f.func_after(f.argptr,QT_NTH_CHILD(qt,3),f,doneptr);
1350 +      }
1351 +      return(qt);
1352 +    }
1353 +    if(bc[1] < b)
1354 +    {
1355 +      vc[0] = a; vc[1] = b; vc[2] = q0[2];
1356 +      va[0] = q1[0]; va[1] = b; va[2] = c;
1357 +      QT_NTH_CHILD(qt,1) = qtInsert_point_rev(root,QT_NTH_CHILD(qt,1),
1358 +                                   qt,vc,q1,va,bc,scale>>1,f,n+1,doneptr);
1359 +      if(!*doneptr)
1360 +      {
1361 +        f.func_after(f.argptr,QT_NTH_CHILD(qt,0),f,doneptr);
1362 +        if(!*doneptr)
1363 +          f.func_after(f.argptr,QT_NTH_CHILD(qt,2),f,doneptr);
1364 +        if(!*doneptr)
1365 +          f.func_after(f.argptr,QT_NTH_CHILD(qt,3),f,doneptr);
1366 +      }
1367 +      return(qt);
1368 +    }
1369 +    if(bc[2] < c)
1370 +    {
1371 +      va[0] = q1[0]; va[1] = b; va[2] = c;
1372 +      vb[0] = a; vb[1] = q0[1]; vb[2] = c;
1373 +      QT_NTH_CHILD(qt,2) = qtInsert_point_rev(root,QT_NTH_CHILD(qt,2),
1374 +                                qt,vb,va,q2,bc,scale>>1,f,n+1,doneptr);
1375 +      if(!*doneptr)
1376 +      {
1377 +        f.func_after(f.argptr,QT_NTH_CHILD(qt,0),f,doneptr);
1378 +        if(!*doneptr)
1379 +          f.func_after(f.argptr,QT_NTH_CHILD(qt,1),f,doneptr);
1380 +        if(!*doneptr)
1381 +          f.func_after(f.argptr,QT_NTH_CHILD(qt,3),f,doneptr);
1382 +      }
1383 +      return(qt);
1384 +    }
1385 +    else
1386 +    {
1387 +      va[0] = q1[0]; va[1] = b; va[2] = c;
1388 +      vb[0] = a; vb[1] = q0[1]; vb[2] = c;
1389 +      vc[0] = a; vc[1] = b; vc[2] = q0[2];
1390 +      QT_NTH_CHILD(qt,3) = qtInsert_point(root,QT_NTH_CHILD(qt,3),
1391 +                                   qt,va,vb,vc,bc,scale>>1,f,n+1,doneptr);
1392 +      if(!*doneptr)
1393 +      {
1394 +        f.func_after(f.argptr,QT_NTH_CHILD(qt,0),f,doneptr);
1395 +        if(!*doneptr)
1396 +          f.func_after(f.argptr,QT_NTH_CHILD(qt,1),f,doneptr);
1397 +        if(!*doneptr)
1398 +          f.func_after(f.argptr,QT_NTH_CHILD(qt,2),f,doneptr);
1399 +      }
1400 +      return(qt);
1401 +    }
1402 +  }
1403 +  else
1404 +  {
1405 +    qt = f.func(f.argptr,root,qt,parent,q0,q1,q2,bc,scale,1,f,n,doneptr);
1406 +    return(qt);
1407 +  }
1408 + }
1409  
1410  
1411  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines