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

Comparing ray/src/hd/sm.c (file contents):
Revision 3.14 by gwlarson, Fri Mar 5 16:33:17 1999 UTC vs.
Revision 3.15 by gwlarson, Thu Jun 10 15:22:21 1999 UTC

# Line 11 | Line 11 | static char SCCSid[] = "$SunId$ SGI";
11   #include "sm_flag.h"
12   #include "sm_list.h"
13   #include "sm_geom.h"
14 #include "sm_qtree.h"
15 #include "sm_stree.h"
14   #include "sm.h"
15  
16  
17 +
18   SM *smMesh = NULL;
19   double smDist_sum=0;
21 #define S_INC 1000
22 int smNew_tri_cnt=0;
23 int smNew_tri_size=0;
20  
21 < #define SM_MIN_SAMP_DIFF 1e-4/* min edge length in radians */
22 <
23 < /* Each edge extends .5536 radians - 31.72 degrees */
21 > #ifdef DEBUG
22 > int Tcnt=0,Wcnt=0;
23 > #endif
24 > /* Each edge extends .372 radians  */
25   static FVECT icosa_verts[162] =
26   {{-0.018096,0.495400,0.868477},{0.018614,-0.554780,0.831789},
27   {0.850436,0.011329,0.525956},{0.850116,0.048016,-0.524402},
# Line 131 | Line 128 | static int icosa_tris[320][3] =
128   {34,112,114},{112,33,113},{114,113,1},{112,113,114},{32,111,107},{111,33,112},
129   {107,112,34},{111,112,107},{9,109,116},{109,32,115},{116,115,36},{109,115,116},
130   {32,106,118},{106,8,117},{118,117,35},{106,117,118},{36,119,121},{119,35,120},
131 < {121,120,11},{119,120,121},{32,118,115},{118,35,119},{115,119,36},{118,119,115},
132 < {10,122,124},{122,37,123},{124,123,39},{122,123,124},{37,125,127},{125,11,126},
133 < {127,126,38},{125,126,127},{39,128,130},{128,38,129},{130,129,3},{128,129,130},
131 > {121,120,11},{119,120,121},{32,118,115},{118,35,119},{115,119,36},
132 > {118,119,115},{10,122,124},{122,37,123},{124,123,39},{122,123,124},
133 > {37,125,127},{125,11,126},{127,126,38},{125,126,127},{39,128,130},
134 > {128,38,129},{130,129,3},{128,129,130},
135   {37,127,123},{127,38,128},{123,128,39},{127,128,123},{11,125,132},{125,37,131},
136 < {132,131,41},{125,131,132},{37,122,134},{122,10,133},{134,133,40},{122,133,134},
137 < {41,135,137},{135,40,136},{137,136,5},{135,136,137},{37,134,131},{134,40,135},
136 > {132,131,41},{125,131,132},{37,122,134},{122,10,133},{134,133,40},
137 > {122,133,134},{41,135,137},{135,40,136},{137,136,5},{135,136,137},
138 > {37,134,131},{134,40,135},
139   {131,135,41},{134,135,131},{6,65,94},{65,18,138},{94,138,28},{65,138,94},
140 < {18,62,139},{62,2,49},{139,49,13},{62,49,139},{28,140,97},{140,13,46},{97,46,0},
141 < {140,46,97},{18,139,138},{139,13,140},{138,140,28},{139,140,138},{1,44,114},
140 > {18,62,139},{62,2,49},{139,49,13},{62,49,139},{28,140,97},{140,13,46},
141 > {97,46,0},{140,46,97},{18,139,138},{139,13,140},{138,140,28},{139,140,138},
142 > {1,44,114},
143   {44,14,141},{114,141,34},{44,141,114},{14,50,142},{50,2,68},{142,68,21},
144   {50,68,142},{34,143,108},{143,21,73},{108,73,8},{143,73,108},{14,142,141},
145   {142,21,143},{141,143,34},{142,143,141},{0,52,98},{52,16,144},{98,144,29},
# Line 155 | Line 155 | static int icosa_tris[320][3] =
155   {155,38,126},{120,126,11},{155,126,120},{20,154,153},{154,38,155},{153,155,35},
156   {154,155,153},{7,81,101},{81,23,156},{101,156,30},{81,156,101},{23,78,157},
157   {78,5,136},{157,136,40},{78,136,157},{30,158,104},{158,40,133},{104,133,10},
158 < {158,133,104},{23,157,156},{157,40,158},{156,158,30},{157,158,156},{11,132,121},
158 > {158,133,104},{23,157,156},{157,40,158},{156,158,30},{157,158,156},{
159 > 11,132,121},
160   {132,41,159},{121,159,36},{132,159,121},{41,137,160},{137,5,84},{160,84,26},
161   {137,84,160},{36,161,116},{161,26,89},{116,89,9},{161,89,116},{41,160,159},
162   {160,26,161},{159,161,36},{160,161,159}};
# Line 195 | Line 196 | static int icosa_nbrs[320][3] =
196   {182,180,181},{187,308,190},{294,187,189},{293,309,187},{186,184,185},
197   {191,177,180},{185,191,182},{184,178,191},{190,188,189},{195,101,42},
198   {204,195,41},{206,102,195},{194,192,193},{199,204,38},{10,199,37},{9,205,199},
199 < {198,196,197},{203,105,206},{6,203,205},{5,106,203},{202,200,201},{207,193,196},
200 < {201,207,198},{200,194,207},{206,204,205},{211,138,0},{220,211,2},{222,136,211},
201 < {210,208,209},{215,220,8},{48,215,10},{50,221,215},{214,212,213},{219,130,222},
199 > {198,196,197},{203,105,206},{6,203,205},{5,106,203},{202,200,201},
200 > {207,193,196},{201,207,198},{200,194,207},{206,204,205},{211,138,0},
201 > {220,211,2}, {222,136,211},{210,208,209},{215,220,8},{48,215,10},{50,221,215},
202 > {214,212,213},{219,130,222},
203   {56,219,221},{58,128,219},{218,216,217},{223,209,212},{217,223,214},
204   {216,210,223},{222,220,221},{227,106,16},{236,227,18},{238,104,227},
205 < {226,224,225},{231,236,24},{64,231,26},{66,237,231},{230,228,229},{235,98,238},
205 > {226,224,225},{231,236,24},{64,231,26},{66,237,231},{230,228,229},
206 > {235,98,238},
207   {72,235,237},{74,96,235},{234,232,233},{239,225,228},{233,239,230},
208   {232,226,239},{238,236,237},{243,133,90},{252,243,89},{254,134,243},
209 < {242,240,241},{247,252,86},{26,247,85},{25,253,247},{246,244,245},{251,137,254},
209 > {242,240,241},{247,252,86},{26,247,85},{25,253,247},{246,244,245},
210 > {251,137,254},
211   {22,251,253},{21,138,251},{250,248,249},{255,241,244},{249,255,246},
212   {248,242,255},{254,252,253},{259,122,160},{268,259,162},{270,120,259},
213   {258,256,257},{263,268,168},{32,263,170},{34,269,263},{262,260,261},
# Line 233 | Line 237 | FVECT FrustumNear[4],FrustumFar[4];
237   double dev_zmin=.01,dev_zmax=1000;
238   #endif
239  
240 +
241 + char *
242 + tempbuf(len,resize)                     /* get a temporary buffer */
243 + unsigned  len;
244 + int resize;
245 + {
246 +  extern char  *malloc(), *realloc();
247 +  static char  *tempbuf = NULL;
248 +  static unsigned  tempbuflen = 0;
249 +
250 + #ifdef DEBUG
251 +        static int in_use=FALSE;
252 +
253 +        if(len == -1)
254 +          {
255 +            in_use = FALSE;
256 +            return(NULL);
257 +          }
258 +        if(!resize && in_use)
259 +        {
260 +            eputs("Buffer in use:cannot allocate:tempbuf()\n");
261 +            return(NULL);
262 +        }
263 + #endif
264 +        if (len > tempbuflen) {
265 +                if (tempbuflen > 0)
266 +                        tempbuf = realloc(tempbuf, len);
267 +                else
268 +                        tempbuf = malloc(len);
269 +                tempbuflen = tempbuf==NULL ? 0 : len;
270 +        }
271 + #ifdef DEBUG
272 +        in_use = TRUE;
273 + #endif
274 +        return(tempbuf);
275 + }
276 +
277   smDir(sm,ps,id)
278     SM *sm;
279     FVECT ps;
# Line 261 | Line 302 | smInit_mesh(sm)
302   {
303      /* Reset the triangle counters */
304      SM_NUM_TRI(sm) = 0;
264    SM_SAMPLE_TRIS(sm) = 0;
305      SM_FREE_TRIS(sm) = -1;
266    SM_AVAILABLE_TRIS(sm) = -1;
306      smClear_flags(sm,-1);
307   }
308  
# Line 274 | Line 313 | smInit_mesh(sm)
313   smClear(sm)
314   SM *sm;
315   {
316 <  smClear_samples(sm);
317 <  smClear_locator(sm);
316 >  smDist_sum = 0;
317 >  smInit_samples(sm);
318 >  smInit_locator(sm);
319    smInit_mesh(sm);
320   }
321  
282 static int realloc_cnt=0;
283
284 int
285 smRealloc_mesh(sm)
286 SM *sm;
287 {
288  int fbytes,i,max_tris,max_verts;
289  
290  if(realloc_cnt <=0)
291    realloc_cnt = SM_MAX_TRIS(sm);
292
293  max_tris = SM_MAX_TRIS(sm) + realloc_cnt;
294  fbytes = FLAG_BYTES(max_tris);
295
296  if(!(SM_TRIS(sm) = (TRI *)realloc(SM_TRIS(sm),max_tris*sizeof(TRI))))
297    goto memerr;
298
299  for(i=0; i< T_FLAGS; i++)
300   if(!(SM_NTH_FLAGS(sm,i)=(int4 *)realloc((char *)SM_NTH_FLAGS(sm,i),fbytes)))
301        goto memerr;
302
303  SM_MAX_TRIS(sm) = max_tris;
304  return(max_tris);
305
306 memerr:
307        error(SYSTEM, "out of memory in smRealloc_mesh()");
308 }
309
322   /* Allocate and initialize a new mesh with max_verts and max_tris */
323   int
324   smAlloc_mesh(sm,max_verts,max_tris)
# Line 317 | Line 329 | int max_verts,max_tris;
329  
330      fbytes = FLAG_BYTES(max_tris);
331  
332 <    if(!(SM_TRIS(sm) = (TRI *)realloc(NULL,max_tris*sizeof(TRI))))
332 >    if(!(SM_TRIS(sm) = (TRI *)malloc(max_tris*sizeof(TRI))))
333        goto memerr;
334  
323    if(!(SM_VERTS(sm) = (VERT *)realloc(NULL,max_verts*sizeof(VERT))))
324      goto memerr;
325
335      for(i=0; i< T_FLAGS; i++)
336 <      if(!(SM_NTH_FLAGS(sm,i)=(int4 *)realloc(NULL,fbytes)))
336 >      if(!(SM_NTH_FLAGS(sm,i)=(int4 *)malloc(fbytes)))
337          goto memerr;
338  
339      SM_MAX_VERTS(sm) = max_verts;
340      SM_MAX_TRIS(sm) = max_tris;
341  
333    realloc_cnt = max_verts >> 1;
334
342      smInit_mesh(sm);
343  
344      return(max_tris);
# Line 340 | Line 347 | memerr:
347   }
348  
349  
343 int
344 compress_set(os)
345 OBJECT *os;
346 {
347  int i,j;
348
349  for (i = 1, j = os[0]; i <= j; i++)
350  {
351    if(SM_T_ID_VALID(smMesh,os[i]))
352      continue;
353    if(i==j)
354      break;
355    while(!SM_T_ID_VALID(smMesh,os[j]) && (i < j))
356            j--;
357    if(i==j)
358      break;
359    os[i] = os[j--];
360  }
361  i--;
362        
363  os[0] = i;
364  return(i);
365
366 }
367
350   int
351   smAlloc_tri(sm)
352   SM *sm;
# Line 375 | Line 357 | SM *sm;
357    /* Otherwise, have we reached the end of the list yet?*/
358    if(SM_NUM_TRI(sm) < SM_MAX_TRIS(sm))
359      return(SM_NUM_TRI(sm)++);
378  if((id = SM_AVAILABLE_TRIS(sm)) != -1)
379  {
380    SM_AVAILABLE_TRIS(sm) =  T_NEXT_AVAILABLE(SM_NTH_TRI(sm,id));
381    return(id);
382  }
360    if((id = SM_FREE_TRIS(sm)) != -1)
361    {
362 <    dosets(compress_set);
386 <    SM_AVAILABLE_TRIS(sm) = T_NEXT_FREE(SM_NTH_TRI(sm,id));
387 <    SM_FREE_TRIS(sm) = -1;
362 >    SM_FREE_TRIS(sm) =  T_NEXT_FREE(SM_NTH_TRI(sm,id));
363      return(id);
364    }
365 <  /*Else: realloc */
366 <  smRealloc_mesh(sm);
367 <  return(SM_NUM_TRI(sm)++);
365 >
366 >  error(CONSISTENCY,"smAlloc_tri: no more available triangles\n");
367 >  return(INVALID);
368   }
369  
370   smFree_mesh(sm)
# Line 399 | Line 374 | SM *sm;
374  
375    if(SM_TRIS(sm))
376      free(SM_TRIS(sm));
402  if(SM_VERTS(sm))
403    free(SM_VERTS(sm));
377    for(i=0; i< T_FLAGS; i++)
378      if(SM_NTH_FLAGS(sm,i))
379        free(SM_NTH_FLAGS(sm,i));
# Line 434 | Line 407 | smAlloc(max_samples)
407    /* First allocate at least n samples + extra points:at least enough
408     necessary to form the BASE MESH- Default = 4;
409    */
410 <  SM_SAMP(smMesh) = sAlloc(&n,SM_EXTRA_POINTS);
410 >  SM_SAMP(smMesh) = sAlloc(&n,SM_BASE_POINTS);
411  
412 <  total_points = n + SM_EXTRA_POINTS;
412 >  total_points = n + SM_BASE_POINTS;
413  
414 <  max_tris = total_points*2;
414 >  /* Need enough tris for base mesh, + 2 for each sample, plus extra
415 >     since triangles are not deleted until added and edge flips (max 4)
416 >  */
417 >  max_tris = n*2 + SM_BASE_TRIS + 10;
418    /* Now allocate space for mesh vertices and triangles */
419    max_tris = smAlloc_mesh(smMesh, total_points, max_tris);
420  
# Line 454 | Line 430 | SM *sm;
430   FVECT vp;
431   {
432  
457  smDist_sum = 0;
458  smNew_tri_cnt = 0;
459
433    VCOPY(SM_VIEW_CENTER(sm),vp);
434 <  smInit_locator(sm,vp);
462 <  smInit_samples(sm);
463 <  smInit_mesh(sm);  
434 >  smClear(sm);
435    smCreate_base_mesh(sm,SM_DEFAULT);
436   }
437  
# Line 484 | Line 455 | smInit(n)
455    /* If n <=0, Just clear the existing structures */
456    if(n <= 0)
457    {
458 + #ifdef DEBUG
459 +  fprintf(stderr,"Tcnt=%d Wcnt = %d, avg = %f\n",Tcnt,Wcnt,(float)Wcnt/Tcnt);
460 + #endif
461      smClear(smMesh);
462      return(0);
463    }
# Line 491 | Line 465 | smInit(n)
465    /* Total mesh vertices includes the sample points and the extra vertices
466       to form the base mesh
467    */
468 <  max_vertices = n + SM_EXTRA_POINTS;
468 >  max_vertices = n + SM_BASE_POINTS;
469  
470    /* If the current mesh contains enough room, clear and return */
471    if(smMesh && (max_vertices <= SM_MAX_VERTS(smMesh)) && SM_MAX_SAMP(smMesh) <=
# Line 505 | Line 479 | smInit(n)
479    */
480    smAlloc(n);
481  
482 + #ifdef DEBUG
483 +  fprintf(stderr,"smInit: allocating room for %d samples\n",
484 +          SM_MAX_SAMP(smMesh));
485 + #endif
486    return(SM_MAX_SAMP(smMesh));
487   }
488  
# Line 528 | Line 506 | smLocator_apply(sm,v0,v1,v2,func,n)
506   }
507  
508   QUADTREE
509 < insert_tri(argptr,root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
532 <               s0,s1,s2,sq0,sq1,sq2,rev,f,n)
509 > insert_samp(argptr,root,qt,parent,q0,q1,q2,bc,scale,rev,f,n,doneptr)
510       int *argptr;
511       int root;
512 <     QUADTREE qt;
513 <     BCOORD q0[3],q1[3],q2[3];
514 <     BCOORD t0[3],t1[3],t2[3];
538 <     BCOORD dt10[3],dt21[3],dt02[3];
539 <     unsigned int scale,s0,s1,s2,sq0,sq1,sq2,rev;
512 >     QUADTREE qt,parent;
513 >     BCOORD q0[3],q1[3],q2[3],bc[3];
514 >     unsigned int scale,rev;
515       FUNC f;
516 <     int n;
516 >     int n,*doneptr;
517   {
518 <  OBJECT *optr,*tptr,t_set[QT_MAXSET+1];
519 <  int i,t_id;
520 <  TRI *t;
521 <  FVECT tri[3];
522 <  BCOORD b0[3],b1[3],b2[3];
523 <  BCOORD tb0[3],tb1[3],tb2[3];
549 <  BCOORD db10[3],db21[3],db02[3];
550 <  BCOORD a,b,c,qa,qb,qc;
551 <  FUNC tfunc;
518 >  OBJECT *optr,*sptr,s_set[QT_MAXSET+1];
519 >  int i,s_id;
520 >  FVECT p;
521 >  BCOORD bp[3];
522 >  FUNC sfunc;
523 >  S_ARGS args;
524  
525 <  t_id = *argptr;
554 <
525 >  s_id = ((S_ARGS *)argptr)->s_id;
526    /* If the set is empty - just add */
527    if(QT_IS_EMPTY(qt))
528 <    return(qtadduelem(qt,t_id));
529 <
528 >  {
529 >    qt = qtadduelem(qt,s_id);
530 >    SM_S_NTH_QT(smMesh,s_id) = qt;
531 >    if(((S_ARGS *)argptr)->n_id)
532 >      *doneptr = FALSE;
533 >    else
534 >      *doneptr = TRUE;
535 >    return(qt);
536 >  }
537    /* If the set size is below expansion threshold,or at maximum
538       number of quadtree levels : just add */
539    optr = qtqueryset(qt);
540    if(QT_SET_CNT(optr) < QT_SET_THRESHOLD || (n > (QT_MAX_LEVELS-2)))
541 <    return(qtadduelem(qt,t_id));
542 <  /* otherwise: expand node- and insert tri, and reinsert existing tris
541 >  {
542 >    qt = qtadduelem(qt,s_id);
543 >    
544 >    SM_S_NTH_QT(smMesh,s_id) = qt;
545 >    if(((S_ARGS *)argptr)->n_id)
546 >      if(QT_SET_CNT(qtqueryset(qt)) > 1)
547 >      {
548 >        ((S_ARGS *)argptr)->n_id = qtqueryset(qt)[1];
549 >        *doneptr = TRUE;
550 >      }
551 >      else
552 >        *doneptr = FALSE;
553 >    else
554 >      *doneptr = TRUE;
555 >    return(qt);
556 >  }
557 >  /* otherwise: expand node- and insert sample, and reinsert existing samples
558       in set to children of new node
559    */
560 <  /* First tri compressing set */
561 < #ifdef NEWSETS0
562 <  if(qtcompressuelem(qt,compress_set) < QT_SET_THRESHOLD)
563 <    /* Get set: If greater than standard size: allocate memory to hold */
564 <    return(qtadduelem(qt,t_id));
565 < #endif
566 <    if(QT_SET_CNT(optr) > QT_MAXSET)
567 <    {
575 <       if(!(tptr = (OBJECT *)malloc((QT_SET_CNT(optr)+1)*sizeof(OBJECT))))
576 <        goto memerr;
577 <    }
578 <    else
579 <     tptr = t_set;
580 <    qtgetset(tptr,qt);
560 >  if(QT_SET_CNT(optr) > QT_MAXSET)
561 >  {
562 >    if(!(sptr = (OBJECT *)malloc((QT_SET_CNT(optr)+1)*sizeof(OBJECT))))
563 >      goto memerr;
564 >  }
565 >  else
566 >    sptr = s_set;
567 >  qtgetset(sptr,qt);
568  
569    /* subdivide node */
570    qtfreeleaf(qt);
571    qtSubdivide(qt);
572  
586  a = q1[0];  b = q0[1]; c = q0[2];
587  qa = q0[0]; qb = q1[1];  qc = q2[2];
588  /* First add current tri: have all of the information */
589  if(rev)
590    qt = qtInsert_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
591               s0,s1,s2,sq0,sq1,sq2,f,n);
592  else
593    qt = qtInsert_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
594               s0,s1,s2,sq0,sq1,sq2,f,n);
595
573    /* Now add in all of the rest; */
574 <  F_FUNC(tfunc) = F_FUNC(f);
575 <  for(optr = QT_SET_PTR(tptr),i=QT_SET_CNT(tptr); i > 0; i--)
574 >  F_FUNC(sfunc) = F_FUNC(f);
575 >  F_ARGS(sfunc) = (int *) (&args);
576 >  args.n_id = 0;
577 >  for(optr = sptr,i=QT_SET_CNT(sptr); i > 0; i--)
578    {
579 <    t_id = QT_SET_NEXT_ELEM(optr);
580 <    t = SM_NTH_TRI(smMesh,t_id);
581 <    if(!T_IS_VALID(t))
582 <      continue;
583 <    F_ARGS(tfunc) = &t_id;
605 <    VSUB(tri[0],SM_T_NTH_WV(smMesh,t,0),SM_VIEW_CENTER(smMesh));
606 <    VSUB(tri[1],SM_T_NTH_WV(smMesh,t,1),SM_VIEW_CENTER(smMesh));
607 <    VSUB(tri[2],SM_T_NTH_WV(smMesh,t,2),SM_VIEW_CENTER(smMesh));
608 <    convert_tri_to_frame(root,tri,b0,b1,b2,db10,db21,db02);
609 <
610 <    /* Calculate appropriate sidedness values */
611 <    SIDES_GTR(b0,b1,b2,s0,s1,s2,a,b,c);
612 <    SIDES_GTR(b0,b1,b2,sq0,sq1,sq2,qa,qb,qc);
579 >    s_id = QT_SET_NEXT_ELEM(optr);
580 >    args.s_id = s_id;
581 >    VSUB(p,SM_NTH_WV(smMesh,s_id),SM_VIEW_CENTER(smMesh));
582 >    normalize(p);
583 >    vert_to_qt_frame(i,p,bp);    
584      if(rev)
585 <      qt = qtInsert_tri_rev(root,qt,q0,q1,q2,b0,b1,b2,db10,db21,db02,scale,
615 <               s0,s1,s2,sq0,sq1,sq2,tfunc,n);
585 >      qt= qtInsert_point_rev(root,qt,parent,q0,q1,q2,bp,scale,sfunc,n,doneptr);
586      else
587 <      qt = qtInsert_tri(root,qt,q0,q1,q2,b0,b1,b2,db10,db21,db02,scale,
618 <               s0,s1,s2,sq0,sq1,sq2,tfunc,n);
587 >      qt= qtInsert_point(root,qt,parent,q0,q1,q2,bp,scale,sfunc,n,doneptr);
588    }
589 +  /* Add current sample: have all of the information */
590 +  if(rev)
591 +    qt =qtInsert_point_rev(root,qt,parent,q0,q1,q2,bc,scale,f,n,doneptr);
592 +  else
593 +    qt = qtInsert_point(root,qt,parent,q0,q1,q2,bc,scale,f,n,doneptr);
594 +  
595    /* If we allocated memory: free it */
621  if( tptr != t_set)
622    free(tptr);
596  
597 +  if( sptr != s_set)
598 +    free(sptr);
599 +
600    return(qt);
601   memerr:
602      error(SYSTEM,"expand_node():Unable to allocate memory");
# Line 628 | Line 604 | memerr:
604   }
605  
606  
607 <
608 < smLocator_add_tri(sm,t_id,v0_id,v1_id,v2_id)
609 < SM *sm;
610 < int t_id;
635 < int v0_id,v1_id,v2_id;
607 > double
608 > triangle_normal(n,a,b,c)
609 > double n[3];
610 > double a[3],b[3],c[3];
611   {
612 <  FVECT tri[3];
638 <  FUNC f;
612 >  double ab[3],ac[3];
613  
614 < #ifdef DEBUG
615 < if(T_NTH_NBR(SM_NTH_TRI(sm,t_id),0)== -1 ||
616 <   T_NTH_NBR(SM_NTH_TRI(sm,t_id),1)== -1 ||
617 <   T_NTH_NBR(SM_NTH_TRI(sm,t_id),2)== -1)
618 <  error("Invalid tri: smLocator_add_tri()\n");
619 <
646 < if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,t_id),0))) ||
647 <   !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,t_id),1))) ||
648 <   !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,t_id),2))))
649 <  error("Invalid tri: smLocator_add_tri()\n");
650 < #endif
651 <
652 <  VSUB(tri[0],SM_NTH_WV(sm,v0_id),SM_VIEW_CENTER(sm));
653 <  VSUB(tri[1],SM_NTH_WV(sm,v1_id),SM_VIEW_CENTER(sm));
654 <  VSUB(tri[2],SM_NTH_WV(sm,v2_id),SM_VIEW_CENTER(sm));
655 <
656 <  F_FUNC(f) = insert_tri;
657 <  F_ARGS(f) = &t_id;
658 <  stInsert_tri(SM_LOCATOR(sm),tri,f);
614 >  VSUB(ab,b,a);
615 >  normalize(ab);
616 >  VSUB(ac,c,a);
617 >  normalize(ac);
618 >  VCROSS(n,ab,ac);
619 >  return(normalize(n));
620   }
621 <
621 > double on0,on1,on2;
622   /* Add a triangle to the base array with vertices v1-v2-v3 */
623   int
624 < smAdd_tri(sm, v0_id,v1_id,v2_id)
624 > smAdd_tri(sm, v0_id,v1_id,v2_id,tptr)
625   SM *sm;
626   int v0_id,v1_id,v2_id;
627 + TRI **tptr;
628   {
629      int t_id;
630      TRI *t;
631   #ifdef DEBUG
632      if(v0_id==v1_id || v0_id==v2_id || v1_id==v2_id)
633        error(CONSISTENCY,"smAdd_tri: invalid vertex ids\n");
672 #endif    
673    t_id = smAlloc_tri(sm);
634  
635 <    if(t_id == -1)
636 <      return(t_id);
635 > #endif
636 >    t_id = smAlloc_tri(sm);  
637 > #ifdef DEBUG
638 > #if DEBUG > 1
639 >    {
640 >      double v0[3],v1[3],v2[3],n[3];
641 >      double area,dp;
642  
643 +      VSUB(v0,SM_NTH_WV(sm,v0_id),SM_VIEW_CENTER(sm));
644 +      VSUB(v1,SM_NTH_WV(sm,v1_id),SM_VIEW_CENTER(sm));
645 +      VSUB(v2,SM_NTH_WV(sm,v2_id),SM_VIEW_CENTER(sm));
646 +      normalize(v0);
647 +      normalize(v1);
648 +      normalize(v2);
649 +      area = triangle_normal(n,v2,v1,v0);
650 +      if((dp=DOT(v0,n)) < 0.0)
651 +      {
652 +        fprintf(stderr,"dp = %.10f on0=%.10f on1=%.10f on2=%.10f\n", dp,
653 +                on0,on1,on2);
654 +        eputs("backwards tri\n");
655 +      }
656 +    }
657 + #endif
658 + #endif
659 +
660 +
661      t = SM_NTH_TRI(sm,t_id);
662  
663      T_CLEAR_NBRS(t);
# Line 689 | Line 672 | int v0_id,v1_id,v2_id;
672  
673      if(SM_BASE_ID(sm,v0_id) || SM_BASE_ID(sm,v1_id) || SM_BASE_ID(sm,v2_id))
674        SM_SET_NTH_T_BASE(sm,t_id);
675 <
675 >    else
676 >      SM_CLR_NTH_T_BASE(sm,t_id);
677      if(SM_DIR_ID(sm,v0_id) || SM_DIR_ID(sm,v1_id) || SM_DIR_ID(sm,v2_id))
678        SM_SET_NTH_T_BG(sm,t_id);
679 <
679 >    else
680 >      SM_CLR_NTH_T_BG(sm,t_id);
681      S_SET_FLAG(T_NTH_V(t,0));
682      S_SET_FLAG(T_NTH_V(t,1));
683      S_SET_FLAG(T_NTH_V(t,2));
# Line 700 | Line 685 | int v0_id,v1_id,v2_id;
685      SM_SET_NTH_T_ACTIVE(sm,t_id);
686      SM_SET_NTH_T_NEW(sm,t_id);
687  
703    SM_SAMPLE_TRIS(sm)++;
704    smNew_tri_cnt++;
688  
689 +    *tptr = t;
690      /* return initialized triangle */
691      return(t_id);
692   }
693  
694  
695 < void
696 < smTris_swap_edge(sm,t_id,t1_id,e,e1,tn_id,tn1_id,add_ptr)
697 <   SM *sm;
698 <   int t_id,t1_id;
699 <   int e,e1;
700 <   int *tn_id,*tn1_id;
717 <   LIST **add_ptr;
695 > /* pt_in_cone: assumed apex at origin, a,b,c are unit vectors defining the
696 >   triangle which the cone circumscribes. Assumed p is not normalized
697 > */
698 > int
699 > pt_in_cone(p,a,b,c)
700 > double p[3],a[3],b[3],c[3];
701   {
702 <    int verts[3],enext,eprev,e1next,e1prev;
703 <    TRI *n,*ta,*tb,*t,*t1;
704 <    FVECT p1,p2,p3;
705 <    int ta_id,tb_id;
706 <    /* form new diagonal (e relative to t, and e1 relative to t1)
724 <      defined by quadrilateral formed by t,t1- swap for the opposite diagonal
725 <   */
726 <    enext = (e+1)%3;
727 <    eprev = (e+2)%3;
728 <    e1next = (e1+1)%3;
729 <    e1prev = (e1+2)%3;
730 <    verts[e] = T_NTH_V(SM_NTH_TRI(sm,t_id),e);
731 <    verts[enext] = T_NTH_V(SM_NTH_TRI(sm,t_id),enext);
732 <    verts[eprev] = T_NTH_V(SM_NTH_TRI(sm,t1_id),e1);
733 <    ta_id = smAdd_tri(sm,verts[0],verts[1],verts[2]);
734 <    *add_ptr = push_data(*add_ptr,ta_id);
735 <    verts[e1] = T_NTH_V(SM_NTH_TRI(sm,t1_id),e1);
736 <    verts[e1next] = T_NTH_V(SM_NTH_TRI(sm,t1_id),e1next);
737 <    verts[e1prev] = T_NTH_V(SM_NTH_TRI(sm,t_id),e);
738 <    tb_id = smAdd_tri(sm,verts[0],verts[1],verts[2]);
702 >  double r[3];
703 >  double pr,ar;
704 >  double ab[3],ac[3];
705 >  /* r =  (B-A)X(C-A) */
706 >  /* in = (p.r) > (a.r) */
707  
740    *add_ptr = push_data(*add_ptr,tb_id);
741    ta = SM_NTH_TRI(sm,ta_id);
742    tb = SM_NTH_TRI(sm,tb_id);
743    t = SM_NTH_TRI(sm,t_id);
744    t1 = SM_NTH_TRI(sm,t1_id);
745    /* set the neighbors */
746    T_NTH_NBR(ta,e) = T_NTH_NBR(t1,e1next);
747    T_NTH_NBR(tb,e1) = T_NTH_NBR(t,enext);
748    T_NTH_NBR(ta,enext)= tb_id;
749    T_NTH_NBR(tb,e1next)= ta_id;
750    T_NTH_NBR(ta,eprev)=T_NTH_NBR(t,eprev);
751    T_NTH_NBR(tb,e1prev)=T_NTH_NBR(t1,e1prev);    
752
753  
708   #ifdef DEBUG
709 <        if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(ta,0))) ||
710 <                       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(ta,1))) ||
711 <                       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(ta,2))) ||
712 <                       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,0))) ||
713 <                       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,1))) ||
714 <                       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,2))))
715 <          goto Ltri_error;
716 <        /*
717 <        if(SM_NTH_TRI(sm,T_NTH_NBR(ta,0))==SM_NTH_TRI(sm,T_NTH_NBR(ta,1)) ||
718 <           SM_NTH_TRI(sm,T_NTH_NBR(ta,0))==SM_NTH_TRI(sm,T_NTH_NBR(ta,2)) ||
719 <           SM_NTH_TRI(sm,T_NTH_NBR(ta,1))==SM_NTH_TRI(sm,T_NTH_NBR(ta,2)) ||
766 <           SM_NTH_TRI(sm,T_NTH_NBR(tb,0))==SM_NTH_TRI(sm,T_NTH_NBR(tb,1)) ||
767 <           SM_NTH_TRI(sm,T_NTH_NBR(tb,0))==SM_NTH_TRI(sm,T_NTH_NBR(tb,2)) ||
768 <           SM_NTH_TRI(sm,T_NTH_NBR(tb,1))==SM_NTH_TRI(sm,T_NTH_NBR(tb,2)) )
769 <          goto Ltri_error;
770 <          */
709 > #if DEBUG > 1
710 > {
711 >  double l;
712 >  l = triangle_normal(r,a,b,c);
713 >  /* l = sin@ between ab,ac - if 0 vectors are colinear */
714 >  if( l <= COLINEAR_EPS)
715 >  {
716 >    eputs("pt in cone: null triangle:returning FALSE\n");
717 >    return(FALSE);
718 >  }
719 > }
720   #endif
772    /* Reset neighbor pointers of original neighbors */
773    n = SM_NTH_TRI(sm,T_NTH_NBR(t,enext));
774 #ifdef DEBUG
775        if(!T_IS_VALID(n))
776          goto Ltri_error;
721   #endif
778    T_NTH_NBR(n,T_NTH_NBR_PTR(t_id,n)) = tb_id;
779    n = SM_NTH_TRI(sm,T_NTH_NBR(t,eprev));
780 #ifdef DEBUG
781        if(!T_IS_VALID(n))
782          goto Ltri_error;
783 #endif
784    T_NTH_NBR(n,T_NTH_NBR_PTR(t_id,n)) = ta_id;
722  
723 <    n = SM_NTH_TRI(sm,T_NTH_NBR(t1,e1next));
724 < #ifdef DEBUG
725 <        if(!T_IS_VALID(n))
789 <          goto Ltri_error;
790 < #endif
791 <    T_NTH_NBR(n,T_NTH_NBR_PTR(t1_id,n)) = ta_id;
792 <    n = SM_NTH_TRI(sm,T_NTH_NBR(t1,e1prev));
793 < #ifdef DEBUG
794 <        if(!T_IS_VALID(n))
795 <          goto Ltri_error;
796 < #endif
797 <    T_NTH_NBR(n,T_NTH_NBR_PTR(t1_id,n)) = tb_id;
723 >  VSUB(ab,b,a);
724 >  VSUB(ac,c,a);
725 >  VCROSS(r,ab,ac);
726  
727 < #ifdef DEBUG
728 <    T_VALID_FLAG(SM_NTH_TRI(sm,t_id))=-1;
729 <    T_VALID_FLAG(SM_NTH_TRI(sm,t1_id))=-1;
730 < #endif
727 >  pr = DOT(p,r);        
728 >  ar = DOT(a,r);
729 >  /* Need to check for equality for degeneracy of 4 points on circle */
730 >  if( pr > ar *( 1.0 + EQUALITY_EPS))
731 >    return(TRUE);
732 >  else
733 >    return(FALSE);
734 > }
735  
736 <    remove_from_list(t_id,add_ptr);
737 <    remove_from_list(t1_id,add_ptr);
736 > smRestore_Delaunay(sm,a,b,c,t,t_id,a_id,b_id,c_id)
737 > SM *sm;
738 > FVECT a,b,c;
739 > TRI *t;
740 > int t_id,a_id,b_id,c_id;
741 > {
742 >  int e1,topp_id,p_id;
743 >  TRI *topp;
744 >  FVECT p;
745  
746 <    smDelete_tri(sm,t_id);
808 <    smDelete_tri(sm,t1_id);
809 <
810 <    *tn_id = ta_id;
811 <    *tn1_id = tb_id;
812 <    
746 >  topp_id = T_NTH_NBR(t,0);
747   #ifdef DEBUG
748 <    if(T_NTH_NBR(SM_NTH_TRI(sm,ta_id),0)== -1 ||
749 <       T_NTH_NBR(SM_NTH_TRI(sm,ta_id),1)== -1 ||
750 <       T_NTH_NBR(SM_NTH_TRI(sm,ta_id),2)== -1 ||
751 <       T_NTH_NBR(SM_NTH_TRI(sm,tb_id),0)== -1 ||
752 <       T_NTH_NBR(SM_NTH_TRI(sm,tb_id),1)== -1 ||
819 <       T_NTH_NBR(SM_NTH_TRI(sm,tb_id),2)== -1)
820 <      goto Ltri_error;
821 <  if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,ta_id),0))) ||
822 <     !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,ta_id),1))) ||
823 <     !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,ta_id),2))))
824 <      goto Ltri_error;
825 <  if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,tb_id),0))) ||
826 <     !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,tb_id),1))) ||
827 <     !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,tb_id),2))))
828 <      goto Ltri_error;
748 >  if(topp_id==INVALID)
749 >  {
750 >    eputs("Invalid tri id smRestore_delaunay()\n");
751 >    return;
752 >  }
753   #endif
754 +  topp = SM_NTH_TRI(sm,topp_id);
755 + #ifdef DEBUG
756 +  if(!T_IS_VALID(topp))
757 +  {
758 +    eputs("Invalid tri smRestore_delaunay()\n");
759      return;
760 < Ltri_error:
761 <    error(CONSISTENCY,"Invalid tri: smTris_swap_edge()\n");
762 < }
760 >  }
761 > #endif
762 >  e1 = T_NTH_NBR_PTR(t_id,topp);
763 >  p_id = T_NTH_V(topp,e1);
764  
765 < smUpdate_locator(sm,add_list)
766 < SM *sm;
767 < LIST *add_list;
838 < {
839 <  int t_id;
840 <  TRI *t;
841 <  
842 <  while(add_list)
765 >  VSUB(p,SM_NTH_WV(sm,p_id),SM_VIEW_CENTER(sm));
766 >  normalize(p);
767 >  if(pt_in_cone(p,c,b,a))
768    {
769 <    t_id = pop_list(&add_list);
770 <    t = SM_NTH_TRI(sm,t_id);
771 <    smLocator_add_tri(sm,t_id,T_NTH_V(t,0),T_NTH_V(t,1),T_NTH_V(t,2));
772 <  }
773 < }
769 >    int e1next,e1prev;
770 >    int ta_id,tb_id;
771 >    TRI *ta,*tb,*n;
772 >    e1next = (e1 + 1)%3;
773 >    e1prev = (e1 + 2)%3;
774 >    ta_id = smAdd_tri(sm,a_id,b_id,p_id,&ta);
775 >    tb_id = smAdd_tri(sm,a_id,p_id,c_id,&tb);
776  
777 < int
778 < smFix_tris(sm,id,tlist,add_list)
779 < SM *sm;
780 < int id;
781 < LIST *tlist,*add_list;
782 < {
783 <    TRI *t,*t_opp;
784 <    FVECT p,p0,p1,p2;
785 <    int e,e1,swapped = 0;
786 <    int t_id,t_opp_id;
787 <    LIST *del_list=NULL,*lptr;
777 >    T_NTH_NBR(ta,0) = T_NTH_NBR(topp,e1next);
778 >    T_NTH_NBR(ta,1) = tb_id;
779 >    T_NTH_NBR(ta,2) = T_NTH_NBR(t,2);
780 >  
781 >    T_NTH_NBR(tb,0) = T_NTH_NBR(topp,e1prev);
782 >    T_NTH_NBR(tb,1) = T_NTH_NBR(t,1);
783 >    T_NTH_NBR(tb,2) = ta_id;
784 >  
785 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t,1));
786 >    T_NTH_NBR(n,T_NTH_NBR_PTR(t_id,n)) = tb_id;
787 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t,2));
788 >    T_NTH_NBR(n,T_NTH_NBR_PTR(t_id,n)) = ta_id;
789 >    n = SM_NTH_TRI(sm,T_NTH_NBR(topp,e1next));
790 >    T_NTH_NBR(n,T_NTH_NBR_PTR(topp_id,n)) = ta_id;
791 >    n = SM_NTH_TRI(sm,T_NTH_NBR(topp,e1prev));
792 >    T_NTH_NBR(n,T_NTH_NBR_PTR(topp_id,n)) = tb_id;
793 >    
794 >    smDelete_tri(sm,t_id,t);
795 >    smDelete_tri(sm,topp_id,topp);
796  
862    VSUB(p,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm));
863    while(tlist)
864    {
865        t_id = pop_list(&tlist);
797   #ifdef DEBUG
798 <        if(t_id==INVALID || t_id > smMesh->num_tri)
799 <          error(CONSISTENCY,"Invalid tri id smFix_tris()\n");
800 < #endif
801 <        t = SM_NTH_TRI(sm,t_id);
802 <        e = T_WHICH_V(t,id);
803 <        t_opp_id = T_NTH_NBR(t,e);
804 < #ifdef DEBUG
805 <        if(t_opp_id==INVALID || t_opp_id > smMesh->num_tri)
806 <          error(CONSISTENCY,"Invalid tri id smFix_tris()\n");
807 < #endif
808 <        t_opp = SM_NTH_TRI(sm,t_opp_id);
809 < #ifdef DEBUG
810 <        if(!T_IS_VALID(t_opp))
811 <          error(CONSISTENCY,"Invalid trismFix_tris()\n");
812 < #endif
813 <        smDir(sm,p0,T_NTH_V(t_opp,0));
814 <        smDir(sm,p1,T_NTH_V(t_opp,1));
815 <        smDir(sm,p2,T_NTH_V(t_opp,2));
816 <        if(point_in_cone(p,p0,p1,p2))
817 <        {
818 <            swapped = 1;
819 <            e1 = T_NTH_NBR_PTR(t_id,t_opp);
820 <            /* check list for t_opp and Remove if there */
821 <            remove_from_list(t_opp_id,&tlist);
822 <            smTris_swap_edge(sm,t_id,t_opp_id,e,e1,&t_id,&t_opp_id,
823 <                             &add_list);
824 <            tlist = push_data(tlist,t_id);
825 <            tlist = push_data(tlist,t_opp_id);
826 <        }
827 <    }
798 > #if DEBUG > 1
799 >    if(T_NTH_NBR(ta,0) == T_NTH_NBR(ta,1)  ||
800 >       T_NTH_NBR(ta,1) == T_NTH_NBR(ta,2)  ||
801 >       T_NTH_NBR(ta,0) == T_NTH_NBR(ta,2))
802 >      error(CONSISTENCY,"Invalid topology\n");
803 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(ta,0))) ||
804 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(ta,1))) ||
805 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(ta,2))))
806 >      error(CONSISTENCY,"Invalid topology\n");
807 >    n = SM_NTH_TRI(sm,T_NTH_NBR(ta,0));
808 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
809 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
810 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
811 >      error(CONSISTENCY,"Invalid topology\n");
812 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
813 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
814 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
815 >      error(CONSISTENCY,"Invalid topology\n");
816 >    n = SM_NTH_TRI(sm,T_NTH_NBR(ta,1));
817 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
818 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
819 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
820 >      error(CONSISTENCY,"Invalid topology\n");
821 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
822 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
823 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
824 >      error(CONSISTENCY,"Invalid topology\n");
825 >    n = SM_NTH_TRI(sm,T_NTH_NBR(ta,2));
826 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
827 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
828 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
829 >      error(CONSISTENCY,"Invalid topology\n");
830 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
831 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
832 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
833 >      error(CONSISTENCY,"Invalid topology\n");
834 >    n = SM_NTH_TRI(sm,T_NTH_NBR(tb,0));
835 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
836 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
837 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
838 >      error(CONSISTENCY,"Invalid topology\n");
839 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
840 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
841 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
842 >      error(CONSISTENCY,"Invalid topology\n");
843 >    n = SM_NTH_TRI(sm,T_NTH_NBR(tb,1));
844 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
845 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
846 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
847 >      error(CONSISTENCY,"Invalid topology\n");
848 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
849 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
850 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
851 >      error(CONSISTENCY,"Invalid topology\n");
852 >    n = SM_NTH_TRI(sm,T_NTH_NBR(tb,2));
853 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
854 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
855 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
856 >      error(CONSISTENCY,"Invalid topology\n");
857 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
858 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
859 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
860 >      error(CONSISTENCY,"Invalid topology\n");
861  
862 <    smUpdate_locator(sm,add_list);
862 >    if(T_NTH_NBR(tb,0) == T_NTH_NBR(tb,1)  ||
863 >       T_NTH_NBR(tb,1) == T_NTH_NBR(tb,2)  ||
864 >       T_NTH_NBR(tb,0) == T_NTH_NBR(tb,2))
865 >      error(CONSISTENCY,"Invalid topology\n");
866 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,0))) ||
867 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,1))) ||
868 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,2))))
869 >      error(CONSISTENCY,"Invalid topology\n");
870  
871 <    return(swapped);
871 > #endif  
872 > #endif  
873 >    smRestore_Delaunay(sm,a,b,p,ta,ta_id,a_id,b_id,p_id);
874 >    smRestore_Delaunay(sm,a,p,c,tb,tb_id,a_id,p_id,c_id);
875 >  }
876   }
877  
878 +
879   /* Give the vertex "id" and a triangle "t" that it belongs to- return the
880     next nbr in a counter clockwise order about vertex "id"
881   */
# Line 934 | Line 910 | int id;
910  
911   /* Locate the point-id in the point location structure: */
912   int
913 < smInsert_samp(sm,s_id,tri_id,on,which)
913 > smInsert_samp_mesh(sm,s_id,tri_id,a,b,c,d,on,which)
914     SM *sm;
915     int s_id,tri_id;
916 +   FVECT a,b,c,d;
917     int on,which;
918   {
919      int v_id[3],topp_id,i;
920 <    int t0_id,t1_id,t2_id,t3_id,replaced;
921 <    int e0,e1,e2,opp0,opp1,opp2,opp_id;
922 <    LIST *tlist,*add_list;
923 <    FVECT npt;
947 <    TRI *tri,*nbr,*topp;
920 >    int t0_id,t1_id,t2_id,t3_id;
921 >    int e0,e1,e2,opp_id,opp0,opp1,opp2;
922 >    TRI *tri,*nbr,*topp,*t0,*t1,*t2,*t3;
923 >    FVECT e;
924  
949    add_list = NULL;
925      for(i=0; i<3;i++)
926        v_id[i] = T_NTH_V(SM_NTH_TRI(sm,tri_id),i);
927  
928      /* If falls on existing edge */
929      if(on == ON_E)
930      {
931 +      FVECT n,vopp;
932 +      double dp;
933 +
934        tri = SM_NTH_TRI(sm,tri_id);
935        topp_id = T_NTH_NBR(tri,which);
936        e0 = which;
# Line 960 | Line 938 | smInsert_samp(sm,s_id,tri_id,on,which)
938        e2 = (which+2)%3;
939        topp = SM_NTH_TRI(sm,topp_id);
940        opp0 = T_NTH_NBR_PTR(tri_id,topp);
963      opp_id = T_NTH_V(topp,opp0);
941        opp1 = (opp0+1)%3;
942        opp2 = (opp0+2)%3;
943 +
944 +      opp_id = T_NTH_V(topp,opp0);
945        
946        /* Create 4 triangles */
947        /*      /|\             /|\
# Line 972 | Line 951 | smInsert_samp(sm,s_id,tri_id,on,which)
951               \ | /           \ | /
952                \|/             \|/
953       */
954 <        t0_id = smAdd_tri(sm,s_id,v_id[e0],v_id[e1]);
955 <        add_list = push_data(add_list,t0_id);
956 <        t1_id = smAdd_tri(sm,s_id,v_id[e2],v_id[e0]);
957 <        add_list = push_data(add_list,t1_id);
979 <        t2_id = smAdd_tri(sm,s_id,v_id[e1],opp_id);
980 <        add_list = push_data(add_list,t2_id);
981 <        t3_id = smAdd_tri(sm,s_id,opp_id,v_id[e2]);
982 <        add_list = push_data(add_list,t3_id);
983 <        /* CAUTION: tri must be assigned after Add_tri: pointers may change*/
984 <        tri = SM_NTH_TRI(sm,tri_id);
985 <        topp =SM_NTH_TRI(sm,topp_id);
954 >      t0_id = smAdd_tri(sm,s_id,v_id[e0],v_id[e1],&t0);
955 >      t1_id = smAdd_tri(sm,s_id,v_id[e2],v_id[e0],&t1);
956 >      t2_id = smAdd_tri(sm,s_id,v_id[e1],opp_id,&t2);
957 >      t3_id = smAdd_tri(sm,s_id,opp_id,v_id[e2],&t3);
958  
959 <        /* Set the neighbor pointers for the new tris */
960 <        T_NTH_NBR(SM_NTH_TRI(sm,t0_id),0) = T_NTH_NBR(tri,e2);
961 <        T_NTH_NBR(SM_NTH_TRI(sm,t0_id),1) = t2_id;
962 <        T_NTH_NBR(SM_NTH_TRI(sm,t0_id),2) = t1_id;
963 <        T_NTH_NBR(SM_NTH_TRI(sm,t1_id),0) = T_NTH_NBR(tri,e1);
964 <        T_NTH_NBR(SM_NTH_TRI(sm,t1_id),1) = t0_id;
965 <        T_NTH_NBR(SM_NTH_TRI(sm,t1_id),2) = t3_id;
966 <        T_NTH_NBR(SM_NTH_TRI(sm,t2_id),0) = T_NTH_NBR(topp,opp1);
967 <        T_NTH_NBR(SM_NTH_TRI(sm,t2_id),1) = t3_id;
968 <        T_NTH_NBR(SM_NTH_TRI(sm,t2_id),2) = t0_id;
969 <        T_NTH_NBR(SM_NTH_TRI(sm,t3_id),0) = T_NTH_NBR(topp,opp2);
970 <        T_NTH_NBR(SM_NTH_TRI(sm,t3_id),1) = t1_id;
971 <        T_NTH_NBR(SM_NTH_TRI(sm,t3_id),2) = t2_id;
959 >      /* Set the neighbor pointers for the new tris */
960 >      T_NTH_NBR(t0,0) = T_NTH_NBR(tri,e2);
961 >      T_NTH_NBR(t0,1) = t2_id;
962 >      T_NTH_NBR(t0,2) = t1_id;
963 >      T_NTH_NBR(t1,0) = T_NTH_NBR(tri,e1);
964 >      T_NTH_NBR(t1,1) = t0_id;
965 >      T_NTH_NBR(t1,2) = t3_id;
966 >      T_NTH_NBR(t2,0) = T_NTH_NBR(topp,opp1);
967 >      T_NTH_NBR(t2,1) = t3_id;
968 >      T_NTH_NBR(t2,2) = t0_id;
969 >      T_NTH_NBR(t3,0) = T_NTH_NBR(topp,opp2);
970 >      T_NTH_NBR(t3,1) = t1_id;
971 >      T_NTH_NBR(t3,2) = t2_id;
972  
973          /* Reset the neigbor pointers for the neighbors of the original */
974          nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,e1));
# Line 1007 | Line 979 | smInsert_samp(sm,s_id,tri_id,on,which)
979          T_NTH_NBR(nbr,T_NTH_NBR_PTR(topp_id,nbr)) = t2_id;
980          nbr = SM_NTH_TRI(sm,T_NTH_NBR(topp,opp2));
981          T_NTH_NBR(nbr,T_NTH_NBR_PTR(topp_id,nbr)) = t3_id;
982 +
983   #ifdef DEBUG
984 <    T_VALID_FLAG(SM_NTH_TRI(sm,tri_id))=-1;
985 <    T_VALID_FLAG(SM_NTH_TRI(sm,topp_id))=-1;
986 < #endif
987 <        tlist = push_data(NULL,t0_id);
988 <        tlist = push_data(tlist,t1_id);
989 <        tlist = push_data(tlist,t2_id);
990 <        tlist = push_data(tlist,t3_id);
984 > #if DEBUG > 1
985 > {
986 >   TRI *n;
987 >
988 >    if(T_NTH_NBR(t0,0) == T_NTH_NBR(t0,1)  ||
989 >       T_NTH_NBR(t0,1) == T_NTH_NBR(t0,2)  ||
990 >       T_NTH_NBR(t0,0) == T_NTH_NBR(t0,2))
991 >      error(CONSISTENCY,"Invalid topology\n");
992 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t0,0))) ||
993 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t0,1))) ||
994 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t0,2))))
995 >      error(CONSISTENCY,"Invalid topology\n");
996 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t0,0));
997 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
998 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
999 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1000 >      error(CONSISTENCY,"Invalid topology\n");
1001 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1002 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1003 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1004 >      error(CONSISTENCY,"Invalid topology\n");
1005 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t0,1));
1006 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1007 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1008 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1009 >      error(CONSISTENCY,"Invalid topology\n");
1010 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1011 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1012 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1013 >      error(CONSISTENCY,"Invalid topology\n");
1014 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t0,2));
1015 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1016 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1017 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1018 >      error(CONSISTENCY,"Invalid topology\n");
1019 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1020 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1021 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1022 >      error(CONSISTENCY,"Invalid topology\n");
1023 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t1,0));
1024 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1025 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1026 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1027 >      error(CONSISTENCY,"Invalid topology\n");
1028 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1029 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1030 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1031 >      error(CONSISTENCY,"Invalid topology\n");
1032 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t1,1));
1033 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1034 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1035 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1036 >      error(CONSISTENCY,"Invalid topology\n");
1037 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1038 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1039 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1040 >      error(CONSISTENCY,"Invalid topology\n");
1041 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t1,2));
1042 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1043 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1044 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1045 >      error(CONSISTENCY,"Invalid topology\n");
1046 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1047 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1048 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1049 >      error(CONSISTENCY,"Invalid topology\n");
1050 >
1051 >    if(T_NTH_NBR(t1,0) == T_NTH_NBR(t1,1)  ||
1052 >       T_NTH_NBR(t1,1) == T_NTH_NBR(t1,2)  ||
1053 >       T_NTH_NBR(t1,0) == T_NTH_NBR(t1,2))
1054 >      error(CONSISTENCY,"Invalid topology\n");
1055 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t1,0))) ||
1056 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t1,1))) ||
1057 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t1,2))))
1058 >      error(CONSISTENCY,"Invalid topology\n");
1059 >
1060 >    if(T_NTH_NBR(t2,0) == T_NTH_NBR(t2,1)  ||
1061 >       T_NTH_NBR(t2,1) == T_NTH_NBR(t2,2)  ||
1062 >       T_NTH_NBR(t2,0) == T_NTH_NBR(t2,2))
1063 >      error(CONSISTENCY,"Invalid topology\n");
1064 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t2,0))) ||
1065 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t2,1))) ||
1066 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t2,2))))
1067 >      error(CONSISTENCY,"Invalid topology\n");
1068 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t2,0));
1069 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1070 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1071 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1072 >      error(CONSISTENCY,"Invalid topology\n");
1073 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1074 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1075 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1076 >      error(CONSISTENCY,"Invalid topology\n");
1077 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t2,1));
1078 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1079 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1080 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1081 >      error(CONSISTENCY,"Invalid topology\n");
1082 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1083 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1084 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1085 >      error(CONSISTENCY,"Invalid topology\n");
1086 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t2,2));
1087 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1088 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1089 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1090 >      error(CONSISTENCY,"Invalid topology\n");
1091 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1092 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1093 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1094 >      error(CONSISTENCY,"Invalid topology\n");
1095 >
1096 >    if(T_NTH_NBR(t3,0) == T_NTH_NBR(t3,1)  ||
1097 >       T_NTH_NBR(t3,1) == T_NTH_NBR(t3,2)  ||
1098 >       T_NTH_NBR(t3,0) == T_NTH_NBR(t3,2))
1099 >      error(CONSISTENCY,"Invalid topology\n");
1100 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t3,0))) ||
1101 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t3,1))) ||
1102 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t3,2))))
1103 >      error(CONSISTENCY,"Invalid topology\n");
1104 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t3,0));
1105 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1106 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1107 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1108 >      error(CONSISTENCY,"Invalid topology\n");
1109 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1110 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1111 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1112 >      error(CONSISTENCY,"Invalid topology\n");
1113 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t3,1));
1114 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1115 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1116 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1117 >      error(CONSISTENCY,"Invalid topology\n");
1118 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1119 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1120 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1121 >      error(CONSISTENCY,"Invalid topology\n");
1122 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t3,2));
1123 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1124 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1125 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1126 >      error(CONSISTENCY,"Invalid topology\n");
1127 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1128 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1129 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1130 >      error(CONSISTENCY,"Invalid topology\n");
1131 > }
1132 > #endif  
1133 > #endif  
1134 >        smDir(sm,e,opp_id);
1135 >        if(which == 0)
1136 >        {
1137 >          smRestore_Delaunay(sm,a,b,c,t0,t0_id,s_id,v_id[e0],v_id[e1]);
1138 >          smRestore_Delaunay(sm,a,d,b,t1,t1_id,s_id,v_id[e2],v_id[e0]);
1139 >          smRestore_Delaunay(sm,a,c,e,t2,t2_id,s_id,v_id[e1],opp_id);
1140 >          smRestore_Delaunay(sm,a,e,d,t3,t3_id,s_id,opp_id,v_id[e2]);
1141 >        }
1142 >        else
1143 >          if( which==1 )
1144 >          {
1145 >            smRestore_Delaunay(sm,a,c,d,t0,t0_id,s_id,v_id[e0],v_id[e1]);
1146 >            smRestore_Delaunay(sm,a,b,c,t1,t1_id,s_id,v_id[e2],v_id[e0]);
1147 >            smRestore_Delaunay(sm,a,d,e,t2,t2_id,s_id,v_id[e1],opp_id);
1148 >            smRestore_Delaunay(sm,a,e,b,t3,t3_id,s_id,opp_id,v_id[e2]);
1149 >          }
1150 >          else
1151 >          {
1152 >            smRestore_Delaunay(sm,a,d,b,t0,t0_id,s_id,v_id[e0],v_id[e1]);
1153 >            smRestore_Delaunay(sm,a,c,d,t1,t1_id,s_id,v_id[e2],v_id[e0]);
1154 >            smRestore_Delaunay(sm,a,b,e,t2,t2_id,s_id,v_id[e1],opp_id);
1155 >            smRestore_Delaunay(sm,a,e,c,t3,t3_id,s_id,opp_id,v_id[e2]);
1156 >          }
1157 >        smDelete_tri(sm,tri_id,tri);
1158 >        smDelete_tri(sm,topp_id,topp);
1159 >        return(TRUE);
1160      }
1161 <    else
1162 <      {
1163 <        /* Create 3 triangles */
1164 <      /*      / \             /|\
1165 <             /   \           / | \
1166 <            /  *  \  ---->  /  |  \
1167 <           /       \       /  / \  \
1168 <          /         \     / /     \ \
1169 <         /___________\   //_________\\
1170 <      */
1161 > Linsert_in_tri:
1162 >    /* Create 3 triangles */
1163 >    /*      / \             /|\
1164 >           /   \           / | \
1165 >          /  *  \  ---->  /  |  \
1166 >         /       \       /  / \  \
1167 >        /         \       / /     \ \
1168 >        ___________\   //_________\\
1169 >    */
1170 >    tri = SM_NTH_TRI(sm,tri_id);
1171  
1172 <        t0_id = smAdd_tri(sm,s_id,v_id[0],v_id[1]);
1173 <        add_list = push_data(add_list,t0_id);
1174 <        t1_id = smAdd_tri(sm,s_id,v_id[1],v_id[2]);
1033 <        add_list = push_data(add_list,t1_id);
1034 <        t2_id = smAdd_tri(sm,s_id,v_id[2],v_id[0]);
1035 <        add_list = push_data(add_list,t2_id);
1172 >    t0_id = smAdd_tri(sm,s_id,v_id[0],v_id[1],&t0);
1173 >    t1_id = smAdd_tri(sm,s_id,v_id[1],v_id[2],&t1);
1174 >    t2_id = smAdd_tri(sm,s_id,v_id[2],v_id[0],&t2);
1175  
1176 <        /* CAUTION: tri must be assigned after Add_tri: pointers may change*/
1177 <        tri = SM_NTH_TRI(sm,tri_id);
1178 <        /* Set the neighbor pointers for the new tris */
1179 <        T_NTH_NBR(SM_NTH_TRI(sm,t0_id),0) = T_NTH_NBR(tri,2);
1180 <        T_NTH_NBR(SM_NTH_TRI(sm,t0_id),1) = t1_id;
1181 <        T_NTH_NBR(SM_NTH_TRI(sm,t0_id),2) = t2_id;
1182 <        T_NTH_NBR(SM_NTH_TRI(sm,t1_id),0) = T_NTH_NBR(tri,0);
1183 <        T_NTH_NBR(SM_NTH_TRI(sm,t1_id),1) = t2_id;
1184 <        T_NTH_NBR(SM_NTH_TRI(sm,t1_id),2) = t0_id;
1185 <        T_NTH_NBR(SM_NTH_TRI(sm,t2_id),0) = T_NTH_NBR(tri,1);
1047 <        T_NTH_NBR(SM_NTH_TRI(sm,t2_id),1) = t0_id;
1048 <        T_NTH_NBR(SM_NTH_TRI(sm,t2_id),2) = t1_id;
1176 >    /* Set the neighbor pointers for the new tris */
1177 >    T_NTH_NBR(t0,0) = T_NTH_NBR(tri,2);
1178 >    T_NTH_NBR(t0,1) = t1_id;
1179 >    T_NTH_NBR(t0,2) = t2_id;
1180 >    T_NTH_NBR(t1,0) = T_NTH_NBR(tri,0);
1181 >    T_NTH_NBR(t1,1) = t2_id;
1182 >    T_NTH_NBR(t1,2) = t0_id;
1183 >    T_NTH_NBR(t2,0) = T_NTH_NBR(tri,1);
1184 >    T_NTH_NBR(t2,1) = t0_id;
1185 >    T_NTH_NBR(t2,2) = t1_id;
1186          
1187 <        /* Reset the neigbor pointers for the neighbors of the original */
1188 <        nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,0));
1189 <        T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t1_id;
1190 <        nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,1));
1191 <        T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t2_id;
1192 <        nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,2));
1193 <        T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t0_id;
1187 >    /* Reset the neigbor pointers for the neighbors of the original */
1188 >    nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,0));
1189 >    T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t1_id;
1190 >    nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,1));
1191 >    T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t2_id;
1192 >    nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,2));
1193 >    T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t0_id;
1194 > #ifdef DEBUG
1195 > #if DEBUG > 1
1196 > {
1197 >  TRI *n;
1198 >    if(T_NTH_NBR(t0,0) == T_NTH_NBR(t0,1)  ||
1199 >       T_NTH_NBR(t0,1) == T_NTH_NBR(t0,2)  ||
1200 >       T_NTH_NBR(t0,0) == T_NTH_NBR(t0,2))
1201 >      error(CONSISTENCY,"Invalid topology\n");
1202 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t0,0))) ||
1203 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t0,1))) ||
1204 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t0,2))))
1205 >      error(CONSISTENCY,"Invalid topology\n");
1206 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t0,0));
1207 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1208 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1209 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1210 >      error(CONSISTENCY,"Invalid topology\n");
1211 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1212 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1213 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1214 >      error(CONSISTENCY,"Invalid topology\n");
1215 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t0,1));
1216 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1217 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1218 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1219 >      error(CONSISTENCY,"Invalid topology\n");
1220 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1221 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1222 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1223 >      error(CONSISTENCY,"Invalid topology\n");
1224 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t0,2));
1225 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1226 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1227 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1228 >      error(CONSISTENCY,"Invalid topology\n");
1229 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1230 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1231 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1232 >      error(CONSISTENCY,"Invalid topology\n");
1233 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t1,0));
1234 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1235 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1236 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1237 >      error(CONSISTENCY,"Invalid topology\n");
1238 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1239 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1240 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1241 >      error(CONSISTENCY,"Invalid topology\n");
1242 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t1,1));
1243 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1244 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1245 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1246 >      error(CONSISTENCY,"Invalid topology\n");
1247 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1248 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1249 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1250 >      error(CONSISTENCY,"Invalid topology\n");
1251 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t1,2));
1252 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1253 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1254 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1255 >      error(CONSISTENCY,"Invalid topology\n");
1256 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1257 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1258 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1259 >      error(CONSISTENCY,"Invalid topology\n");
1260  
1261 <        tlist = push_data(NULL,t0_id);
1262 <        tlist = push_data(tlist,t1_id);
1263 <        tlist = push_data(tlist,t2_id);
1264 <      }
1265 <    /* Fix up the new triangles*/
1266 <    smFix_tris(sm,s_id,tlist,add_list);
1261 >    if(T_NTH_NBR(t1,0) == T_NTH_NBR(t1,1)  ||
1262 >       T_NTH_NBR(t1,1) == T_NTH_NBR(t1,2)  ||
1263 >       T_NTH_NBR(t1,0) == T_NTH_NBR(t1,2))
1264 >      error(CONSISTENCY,"Invalid topology\n");
1265 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t1,0))) ||
1266 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t1,1))) ||
1267 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t1,2))))
1268 >      error(CONSISTENCY,"Invalid topology\n");
1269  
1270 <    smDelete_tri(sm,tri_id);
1271 <    if(on==ON_E)
1272 <      smDelete_tri(sm,topp_id);
1270 >    if(T_NTH_NBR(t2,0) == T_NTH_NBR(t2,1)  ||
1271 >       T_NTH_NBR(t2,1) == T_NTH_NBR(t2,2)  ||
1272 >       T_NTH_NBR(t2,0) == T_NTH_NBR(t2,2))
1273 >      error(CONSISTENCY,"Invalid topology\n");
1274 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t2,0))) ||
1275 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t2,1))) ||
1276 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t2,2))))
1277 >      error(CONSISTENCY,"Invalid topology\n");
1278 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t2,0));
1279 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1280 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1281 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1282 >      error(CONSISTENCY,"Invalid topology\n");
1283 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1284 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1285 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1286 >      error(CONSISTENCY,"Invalid topology\n");
1287 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t2,1));
1288 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1289 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1290 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1291 >      error(CONSISTENCY,"Invalid topology\n");
1292 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1293 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1294 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1295 >      error(CONSISTENCY,"Invalid topology\n");
1296 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t2,2));
1297 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1298 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1299 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1300 >      error(CONSISTENCY,"Invalid topology\n");
1301 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1302 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1303 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1304 >      error(CONSISTENCY,"Invalid topology\n");
1305 > }
1306 > #endif
1307 > #endif
1308 >  smRestore_Delaunay(sm,a,b,c,t0,t0_id,s_id,v_id[0],v_id[1]);
1309 >  smRestore_Delaunay(sm,a,c,d,t1,t1_id,s_id,v_id[1],v_id[2]);
1310 >  smRestore_Delaunay(sm,a,d,b,t2,t2_id,s_id,v_id[2],v_id[0]);
1311 >  smDelete_tri(sm,tri_id,tri);
1312 >  return(TRUE);
1313  
1069    return(TRUE);
1070
1314   #ifdef DEBUG
1315   Ladderror:
1316 <        error(CONSISTENCY,"Invalid tri: smInsert_samp()\n");
1316 >        error(CONSISTENCY,"Invalid tri: smInsert_samp_mesh()\n");
1317   #endif
1318   }    
1319  
1320 +
1321   int
1322 < smTri_in_set(sm,p,optr,onptr,whichptr)
1322 > smWalk(sm,p,t_id,t,onptr,wptr,from,on_edge,a,b)
1323   SM *sm;
1324   FVECT p;
1325 < OBJECT *optr;
1326 < int *onptr,*whichptr;
1325 > int t_id;
1326 > TRI *t;
1327 > int *onptr,*wptr;
1328 > int from;
1329 > double on_edge;
1330 > FVECT a,b;
1331   {
1084  int i,t_id,on0,on1,on2;
1332    FVECT n,v0,v1,v2;
1333 <  TRI *t;
1087 <  double side;
1333 >  TRI *tn;
1334  
1335 <  for (i = QT_SET_CNT(optr),optr = QT_SET_PTR(optr);i > 0; i--)
1336 <  {
1337 <    /* Find the first triangle that pt falls */
1338 <    t_id = QT_SET_NEXT_ELEM(optr);
1339 <    t = SM_NTH_TRI(sm,t_id);
1340 <    if(!T_IS_VALID(t))
1341 <      continue;
1335 >  int tn_id;
1336 >
1337 > #ifdef DEBUG
1338 >  Wcnt++;
1339 >  on0 = on1 = on2 = 10;
1340 > #endif
1341 >  switch(from){
1342 >  case 0:
1343 >    on0 = on_edge;
1344 >    /* Havnt calculate v0 yet: check for equality first */
1345      VSUB(v0,SM_T_NTH_WV(sm,t,0),SM_VIEW_CENTER(sm));
1346 <    VSUB(v1,SM_T_NTH_WV(sm,t,1),SM_VIEW_CENTER(sm));
1347 <    VSUB(v2,SM_T_NTH_WV(sm,t,2),SM_VIEW_CENTER(sm));
1346 >    normalize(v0);
1347 >    if(EQUAL_VEC3(v0,p)){ *onptr = ON_V; *wptr = 0; return(t_id); }
1348 >    /* determine what side of edge v0v1 (v0a) point is on*/
1349 >    VCROSS(n,v0,a);
1350 >    normalize(n);
1351 >    on2 = DOT(n,p);
1352 >    if(on2 > 0.0)
1353 >      {
1354 >        tn_id = T_NTH_NBR(t,2);
1355 >        tn = SM_NTH_TRI(sm,tn_id);
1356 >        return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn),
1357 >                      -on2,a,v0));
1358 >      }
1359 >    else
1360 >      if(on2 >= -EDGE_EPS)
1361 >      {
1362 >        if(on0 >= -EDGE_EPS)
1363 >        {  
1364 >          /* Could either be epsilon of vertex 1*/
1365 >        /* dot(p,a) == cos angle between them. Want length of chord x to
1366 >           be <= EDGE_EPS for test. if the perpendicular bisector of pa
1367 >           is d, cos@/2 = d/1, with right triangle d^2 + (x/2)^2 = 1
1368 >           or x^2 = 4(1-cos^2@/2) = 4(1- (1 + cos@)/2) =  2 -2cos@,
1369 >            so test is if  x^2 <= VERT_EPS*VERT_EPS,
1370 >           2 - 2cos@ <= VERT_EPS*VERT_EPS, or... */
1371 >          if(DOT(p,a) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1372 >            {*onptr = ON_P; *wptr = 1;}
1373 >          else
1374 >            if(on2 > on0)
1375 >            {*onptr = ON_E; *wptr = 2;}
1376 >            else
1377 >            {*onptr = ON_E; *wptr = 0;}
1378 >          return(t_id);
1379 >        }
1380 >      }
1381  
1382 <    if(EQUAL_VEC3(v0,p))
1382 >    VCROSS(n,b,v0);
1383 >    normalize(n);
1384 >    on1 = DOT(n,p);
1385 >    if(on1 > 0.0)
1386      {
1387 <      *onptr = ON_V;
1388 <      *whichptr = 0;
1389 <      return(t_id);
1387 >      tn_id = T_NTH_NBR(t,1);
1388 >      tn = SM_NTH_TRI(sm,tn_id);
1389 >      return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn),
1390 >                   -on1,v0,b));
1391      }
1392 <    if(EQUAL_VEC3(v1,p))
1392 >    else
1393 >      if(on1 >= -EDGE_EPS)
1394 >      { /* Either on v0 or on edge 1 */
1395 >        if(on0 >= -EDGE_EPS)
1396 >        {
1397 >        if(DOT(p,b) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1398 >            {*onptr = ON_P; *wptr = 2;}
1399 >        else
1400 >          if(on1 > on0)
1401 >            {*onptr = ON_E; *wptr = 1;}
1402 >          else
1403 >            {*onptr = ON_E; *wptr = 0;}
1404 >          return(t_id);
1405 >        }
1406 >        if(on2 >= -EDGE_EPS)
1407 >        {
1408 >        if(DOT(p,v0) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1409 >            {*onptr = ON_P; *wptr = 0;}
1410 >        else
1411 >          if( on1 > on2)
1412 >            {*onptr = ON_E; *wptr = 1;}
1413 >          else
1414 >            {*onptr = ON_E; *wptr = 2;}
1415 >          return(t_id);
1416 >        }
1417 >        *onptr = ON_E; *wptr = 1;
1418 >        return(t_id);
1419 >      }
1420 >    else
1421 >      if(on2 >= -EDGE_EPS)
1422 >      {
1423 >        *onptr = ON_E; *wptr = 2;
1424 >        return(t_id);
1425 >      }
1426 >      if(on0 >= -EDGE_EPS)
1427 >      {
1428 >        *onptr = ON_E; *wptr = 0;
1429 >        return(t_id);
1430 >      }
1431 >    *onptr = IN_T;
1432 >    return(t_id);
1433 >  case 1:
1434 >    on1 = on_edge;
1435 >    /* Havnt calculate v1 yet: check for equality first */
1436 >    VSUB(v1,SM_T_NTH_WV(sm,t,1),SM_VIEW_CENTER(sm));
1437 >    normalize(v1);
1438 >    if(EQUAL_VEC3(v1,p)){ *onptr = ON_V; *wptr = 1; return(t_id); }
1439 >    /* determine what side of edge v0v1 (v0a) point is on*/
1440 >    VCROSS(n,b,v1);
1441 >    normalize(n);
1442 >    on2 = DOT(n,p);
1443 >    if(on2 > 0.0)
1444      {
1445 <      *onptr = ON_V;
1446 <      *whichptr = 1;
1447 <      return(t_id);
1445 >      tn_id = T_NTH_NBR(t,2);
1446 >      tn = SM_NTH_TRI(sm,tn_id);
1447 >      return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn),
1448 >                   -on2,v1,b));
1449      }
1450 <    if(EQUAL_VEC3(v2,p))
1450 >    if(on2 >= -EDGE_EPS)
1451      {
1452 <      *onptr = ON_V;
1453 <      *whichptr = 2;
1454 <      return(t_id);
1452 >      if(on1 >= -EDGE_EPS)
1453 >      {
1454 >        if(DOT(p,b) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1455 >          { *onptr = ON_P; *wptr = 0;}
1456 >        else
1457 >          if(on2 > on1)
1458 >          { *onptr = ON_E; *wptr = 2;}
1459 >        else
1460 >          { *onptr = ON_E; *wptr = 1;}
1461 >         return(t_id);
1462 >      }
1463      }
1118    
1119    on0 = on1 =on2 = 0;
1120    VCROSS(n,v0,v1);
1121    side = DOT(n,p);
1122    if(ZERO(side))
1123      on2 = TRUE;
1124    else
1125      if(side >0.0)
1126        continue;
1464  
1465 <    VCROSS(n,v1,v2);
1466 <    side = DOT(n,p);
1467 <    if(ZERO(side))
1468 <      on0 = TRUE;
1465 >    VCROSS(n,v1,a);
1466 >    normalize(n);
1467 >    on0 = DOT(n,p);
1468 >    if(on0 >0.0)
1469 >    {
1470 >      tn_id = T_NTH_NBR(t,0);
1471 >      tn = SM_NTH_TRI(sm,tn_id);
1472 >      return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn),
1473 >                 -on0,a,v1));
1474 >    }
1475 >    else
1476 >    if(on0 >= -EDGE_EPS)
1477 >      { /* Either on v0 or on edge 1 */
1478 >       if(on1 >= -EDGE_EPS)
1479 >       {
1480 >        if(DOT(p,a) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1481 >           {*onptr = ON_P; *wptr = 2;}
1482 >         else
1483 >          if(on0 > on1)
1484 >          { *onptr = ON_E; *wptr = 0;}
1485 >        else
1486 >          { *onptr = ON_E; *wptr = 1;}
1487 >         return(t_id);
1488 >       }
1489 >       if(on2 >= -EDGE_EPS)
1490 >       {
1491 >       if(DOT(p,v1) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1492 >           {*onptr = ON_P; *wptr = 1;}
1493 >         else
1494 >          if(on0 > on2)
1495 >          { *onptr = ON_E; *wptr = 0;}
1496 >        else
1497 >          { *onptr = ON_E; *wptr = 2;}
1498 >         return(t_id);
1499 >       }
1500 >       *onptr = ON_E; *wptr = 0;
1501 >       return(t_id);
1502 >     }
1503      else
1504 <      if(side >0.0)
1505 <        continue;
1504 >      if(on2 >= -EDGE_EPS)
1505 >      {
1506 >        *onptr = ON_E; *wptr = 2;
1507 >        return(t_id);
1508 >      }
1509 >      if(on1 >= -EDGE_EPS)
1510 >      {
1511 >        *onptr = ON_E; *wptr = 1;
1512 >        return(t_id);
1513 >      }
1514 >    *onptr = IN_T;
1515 >    return(t_id);
1516 >  case 2:
1517 >    on2 = on_edge;
1518 >    VSUB(v2,SM_T_NTH_WV(sm,t,2),SM_VIEW_CENTER(sm));
1519 >    normalize(v2);
1520 >    if(EQUAL_VEC3(v2,p)){ *onptr = ON_V; *wptr = 2; return(t_id); }
1521  
1522 <    VCROSS(n,v2,v0);
1523 <    side = DOT(n,p);
1524 <    if(ZERO(side))
1525 <      on1 = TRUE;
1526 <    else
1141 <      if(side >0.0)
1142 <        continue;
1143 <    if(on0)
1522 >    /* determine what side of edge v0v1 (v0a) point is on*/
1523 >    VCROSS(n,b,v2);
1524 >    normalize(n);
1525 >    on0 = DOT(n,p);
1526 >    if(on0 > 0.0)
1527      {
1528 <      if(on1)
1528 >      tn_id = T_NTH_NBR(t,0);
1529 >      tn = SM_NTH_TRI(sm,tn_id);
1530 >      return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn),
1531 >                    -on0,v2,b));
1532 >    }
1533 >    else
1534 >    if(on0 >= -EDGE_EPS)
1535        {
1536 <        *onptr = ON_P;
1537 <        *whichptr = 2;
1536 >        if(on2 >= - EDGE_EPS)
1537 >        {
1538 >        if(DOT(p,b) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1539 >           {*onptr = ON_P; *wptr = 1;}
1540 >         else
1541 >           if(on0 > on2)
1542 >             {*onptr = ON_E; *wptr = 0;}
1543 >           else
1544 >             {*onptr = ON_E; *wptr = 2;}
1545 >         return(t_id);
1546 >        }
1547        }
1548 <      else
1549 <        if(on2)
1548 >    VCROSS(n,v2,a);
1549 >    normalize(n);
1550 >    on1 = DOT(n,p);
1551 >    if(on1 >0.0)
1552 >    {
1553 >      tn_id = T_NTH_NBR(t,1);
1554 >      tn = SM_NTH_TRI(sm,tn_id);
1555 >      return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn),
1556 >                   -on1,a,v2));
1557 >    }
1558 >    else
1559 >    if(on1 >= -EDGE_EPS)
1560 >     { /* Either on v0 or on edge 1 */
1561 >       if(on0 >= - EDGE_EPS)
1562         {
1563 <         *onptr = ON_P;
1564 <         *whichptr = 1;
1563 >        if(DOT(p,v2) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1564 >          {*onptr = ON_P;*wptr = 2;}
1565 >        else
1566 >          if(on1 > on0)
1567 >            {*onptr = ON_E;*wptr = 1;}
1568 >          else
1569 >            {*onptr = ON_E;*wptr = 0;}
1570 >         return(t_id);
1571         }
1572 +       if(on2 >= -EDGE_EPS)
1573 +       {
1574 +        if(DOT(p,a) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1575 +          {*onptr = ON_P;*wptr = 0;}
1576          else
1577 <          {
1578 <            *onptr = ON_E;
1579 <            *whichptr = 0;
1580 <          }
1581 <      return(t_id);
1582 <    }
1583 <   if(on1)
1584 <    {
1585 <      if(on2)
1577 >          if(on1 > on2)
1578 >            {*onptr = ON_E;*wptr = 1;}
1579 >          else
1580 >            {*onptr = ON_E;*wptr = 2;}
1581 >         return(t_id);
1582 >       }
1583 >       *onptr = ON_E;*wptr = 1;
1584 >       return(t_id);
1585 >     }
1586 >    else
1587 >      if(on0 >= -EDGE_EPS)
1588        {
1589 <        *onptr = ON_P;
1590 <        *whichptr = 0;
1589 >        *onptr = ON_E;*wptr = 0;
1590 >        return(t_id);
1591        }
1592 <      else
1592 >      if(on2 >= -EDGE_EPS)
1593        {
1594 <        *onptr = ON_E;
1595 <        *whichptr = 1;
1594 >        *onptr = ON_E;*wptr = 2;
1595 >        return(t_id);
1596        }
1597 <      return(t_id);
1597 >    *onptr = IN_T;
1598 >    return(t_id);
1599 >  default:
1600 >    /* First time called: havnt tested anything */
1601 >    /* Check against vertices */
1602 >    VSUB(v0,SM_T_NTH_WV(sm,t,0),SM_VIEW_CENTER(sm));
1603 >    normalize(v0);
1604 >    if(EQUAL_VEC3(v0,p)){ *onptr = ON_V; *wptr = 0; return(t_id); }
1605 >    VSUB(v1,SM_T_NTH_WV(sm,t,1),SM_VIEW_CENTER(sm));
1606 >    normalize(v1);
1607 >    if(EQUAL_VEC3(v1,p)){ *onptr = ON_V; *wptr = 1; return(t_id); }
1608 >    VSUB(v2,SM_T_NTH_WV(sm,t,2),SM_VIEW_CENTER(sm));
1609 >    normalize(v2);
1610 >    if(EQUAL_VEC3(v2,p)){ *onptr = ON_V; *wptr = 2; return(t_id); }
1611 >    
1612 >    VCROSS(n,v0,v1);  /* Check against v0v1, or edge 2 */
1613 >    normalize(n);
1614 >    on2 = DOT(n,p);
1615 >    if(on2 > 0.0)
1616 >    {              /* Outside edge: traverse to nbr 2 */
1617 >      tn_id = T_NTH_NBR(t,2);
1618 >      tn = SM_NTH_TRI(sm,tn_id);
1619 >      return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn),
1620 >                 -on2,v1,v0));
1621      }
1622 <   if(on2)
1623 <   {
1624 <     *onptr = ON_E;
1625 <     *whichptr = 2;
1622 >    else
1623 >    VCROSS(n,v1,v2);  /* Check against v1v2 or edge 0 */
1624 >    normalize(n);
1625 >    on0 = DOT(n,p);
1626 >    if(on0 > 0.0)
1627 >    {                      /* Outside edge: traverse to nbr 0 */
1628 >      tn_id = T_NTH_NBR(t,0);
1629 >      tn = SM_NTH_TRI(sm,tn_id);
1630 >      return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn),
1631 >                    -on0,v2,v1));
1632 >    }
1633 >    else
1634 >      if(on0 >= -EDGE_EPS)
1635 >      {                /* On the line defining edge 0 */
1636 >      if(on2 >= -EDGE_EPS)
1637 >      {              
1638 >        if(DOT(p,v1) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1639 >          {*onptr = ON_P;*wptr = 1;}
1640 >        else
1641 >          if(on0 > on2)
1642 >          {*onptr = ON_E;*wptr = 0;}
1643 >        else
1644 >          {*onptr = ON_E;*wptr = 2;}
1645 >        return(t_id);
1646 >      }
1647 >    }
1648 >    VCROSS(n,v2,v0);  /* Check against v2v0 or edge 1 */
1649 >    normalize(n);
1650 >    on1 = DOT(n,p);
1651 >    if(on1 >0.0)
1652 >    {                            /* Outside edge: traverse to nbr 1 */
1653 >      tn_id = T_NTH_NBR(t,1);
1654 >      tn = SM_NTH_TRI(sm,tn_id);
1655 >      return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn),
1656 >                    -on1,v0,v2));
1657 >    }
1658 >    else
1659 >    if(on1  >= -EDGE_EPS)
1660 >      {               /* On the line defining edge 1 */
1661 >        if(on2 >= -EDGE_EPS)
1662 >        {              
1663 >        if(DOT(p,v0) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1664 >            {*onptr = ON_P;*wptr = 0;}
1665 >          else
1666 >            if(on1 > on2)
1667 >              {*onptr = ON_E;*wptr = 1;}
1668 >            else
1669 >              {*onptr = ON_E;*wptr = 2;}
1670 >          return(t_id);
1671 >        }
1672 >        if(on0 >= -EDGE_EPS)
1673 >        {              
1674 >        if(DOT(p,v2) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1675 >            {*onptr = ON_P;*wptr = 2;}
1676 >          else
1677 >            if(on1 > on0)
1678 >              {*onptr = ON_E;*wptr = 1;}
1679 >            else
1680 >              {*onptr = ON_E;*wptr = 0;}
1681 >          return(t_id);
1682 >       }
1683 >        *onptr = ON_E; /* Only on edge 1 */
1684 >        *wptr = 1;
1685 >        return(t_id);
1686 >      }
1687 >    else
1688 >      if(on2 >= -EDGE_EPS)           /* Is on edge 2 ? */
1689 >      {
1690 >        *onptr = ON_E; *wptr = 2;
1691 >        return(t_id);
1692 >      }
1693 >    if(on0 >= -EDGE_EPS)            /* Is on edge 0 ? */
1694 >    {
1695 >      *onptr = ON_E; *wptr = 0;
1696        return(t_id);
1697 <   }
1698 <    *onptr = IN_T;
1697 >    }
1698 >    *onptr = IN_T;   /* Must be interior to t */
1699      return(t_id);
1700    }
1186  return(INVALID);
1701   }
1702  
1703 + #define check_edges(on0,on1,on2,o,w,t_id) \
1704 +   if(on0){if(on1){*o = ON_P;*w = 2;} else if(on2){*o = ON_P;*w = 1;} \
1705 +                   else {*o = ON_E; *w = 0; } return(t_id); } \
1706 +   if(on1){if(on2){*o = ON_P;*w = 0;} else {*o = ON_E;*w = 1;}return(t_id);}\
1707 +   if(on2){*o = ON_E;*w = 2;return(t_id);}
1708 +
1709 + #define  check_verts(p,v0,v1,v2,o,w,t_id) \
1710 +    if(EQUAL_VEC3(v0,p)){ *o = ON_V; *w = 0; return(t_id); } \
1711 +    if(EQUAL_VEC3(v1,p)){ *o = ON_V; *w = 1; return(t_id); } \
1712 +    if(EQUAL_VEC3(v2,p)){ *o = ON_V; *w = 2; return(t_id);}
1713 +
1714 +
1715   int
1716 < smPointLocateTri(sm,p,onptr,whichptr)
1716 > find_neighbor(argptr,qt,f,doneptr)
1717 > int *argptr;
1718 > QUADTREE qt;
1719 > FUNC f;
1720 > int *doneptr;
1721 > {
1722 >  int s_id,i;
1723 >  OBJECT *optr;
1724 >  
1725 >  if(QT_IS_EMPTY(qt))
1726 >    return;
1727 >  else
1728 >    if(QT_IS_TREE(qt))
1729 >    {
1730 >      for(i=0;i < 4; i++)
1731 >      {
1732 >        find_neighbor(argptr,QT_NTH_CHILD(qt,i),f,doneptr);
1733 >        if(*doneptr)
1734 >          return;
1735 >      }
1736 >    }
1737 >    else
1738 >    {
1739 >      optr = qtqueryset(qt);
1740 >      for(i = QT_SET_CNT(optr); i > 0; i--)
1741 >      {
1742 >        s_id = QT_SET_NEXT_ELEM(optr);
1743 >        if(s_id != ((S_ARGS *)argptr)->s_id)
1744 >        {
1745 >          *doneptr = TRUE;
1746 >          ((S_ARGS *)argptr)->n_id = s_id;
1747 >          return;
1748 >        }
1749 >      }
1750 >    }
1751 > }
1752 >
1753 > smInsert_samp(sm,s_id,p,nptr)
1754   SM *sm;
1755 + int s_id;
1756   FVECT p;
1757 < int *onptr,*whichptr;
1757 > int *nptr;
1758   {
1195  QUADTREE qt,*optr;
1759    FVECT tpt;
1760 <  int tri_id;
1760 >  FUNC f;
1761 >  S_ARGS args;
1762  
1763 <  VSUB(tpt,p,SM_VIEW_CENTER(sm));
1764 <  qt = smPointLocateCell(sm,tpt);
1765 <  if(QT_IS_EMPTY(qt))
1766 <    return(INVALID);  
1767 <
1768 <  optr = qtqueryset(qt);
1769 <  tri_id = smTri_in_set(sm,tpt,optr,onptr,whichptr);
1763 >  F_FUNC(f) = insert_samp;
1764 >  args.s_id = s_id;
1765 >  if(nptr)
1766 >  {
1767 >    args.n_id = 1;
1768 >    F_FUNC2(f) = find_neighbor;
1769 >  }
1770 >  else
1771 >    args.n_id = 0;
1772 >  F_ARGS(f) = (int *)(&args);
1773 >  stInsert_samp(SM_LOCATOR(sm),p,f);
1774  
1775 <  return(tri_id);
1775 >  if(nptr)
1776 >    *nptr = args.n_id;
1777   }
1778  
1779 + /* Assumed p is normalized to view sphere */
1780 + int
1781 + smSample_locate_tri(sm,p,s_id,onptr,whichptr,nptr)
1782 + SM *sm;
1783 + FVECT p;
1784 + int s_id;
1785 + int *onptr,*whichptr,*nptr;
1786 + {
1787 +  int tri_id;
1788 +  FVECT tpt;
1789 +  TRI *tri;
1790  
1791 +  if(SM_S_NTH_QT(sm,s_id) == EMPTY)
1792 +    smInsert_samp(sm,s_id,p,nptr);
1793 + #ifdef DEBUG
1794 +  if(*nptr == INVALID)
1795 +    error(CONSISTENCY,"smSample_locate_tri: unable to find sample\n");
1796 + #endif
1797 +  
1798 +  /* Get the triangle adjacent to a sample in qt, or if there are no other
1799 +     samples in qt than the one just inserted, look at siblings-from parent
1800 +     node
1801 +  */
1802 +
1803 +  tri_id = SM_NTH_VERT(sm,*nptr);
1804 + #ifdef DEBUG
1805 +  if(tri_id == INVALID)
1806 +      error(CONSISTENCY,"smSample_locate_tri: Invalid tri_id\n");
1807 + #endif
1808 +
1809 +  tri = SM_NTH_TRI(sm,tri_id);
1810 + #ifdef DEBUG
1811 +  Tcnt++;
1812 +    if(!T_IS_VALID(tri))
1813 +      error(CONSISTENCY,"smSample_locate_tri: Invalid tri\n");
1814 + #endif
1815 +  tri_id = smWalk(sm,p,tri_id,tri,onptr,whichptr,-1,0.0,NULL,NULL);
1816 + #ifdef DEBUG
1817 +    if(tri_id == INVALID)
1818 +      error(CONSISTENCY,"smSample_locate_tri: unable to find tri on walk\n");
1819 + #endif
1820 +    return(tri_id);
1821 + }
1822 +
1823   /*
1824     Determine whether this sample should:
1825     a) be added to the mesh by subdividing the triangle
# Line 1237 | Line 1849 | int *onptr,*whichptr;
1849       This attempts to throw out points that should be occluded  
1850   */
1851   int
1852 < smTest_sample(sm,tri_id,dir,p,rptr)
1852 > smTest_samp(sm,tri_id,dir,p,rptr,ns,n0,n1,n2,ds,d0,on,which)
1853     SM *sm;
1854     int tri_id;
1855     FVECT dir,p;
1856     int *rptr;
1857 +   FVECT ns,n0,n1,n2;
1858 +   double ds,d0;
1859 +   int on,which;
1860   {
1861      TRI *tri;
1862 <    double d,d2,dnear,dspt,d01,d12,d20,s0,s1,s2,ds,dv;
1862 >    double d,d2,dnear,dspt,d01,d12,d20,s0,s1,s2;
1863 >    double dp,dp1;
1864      int vid[3],i,nearid,norm,dcnt,bcnt;
1865 <    FVECT diff[3],spt,npt;
1865 >    FVECT diff[3],spt,npt,n;
1866 >    FVECT nearpt;
1867  
1868      *rptr = INVALID;
1869      bcnt = dcnt = 0;
# Line 1259 | Line 1876 | smTest_sample(sm,tri_id,dir,p,rptr)
1876      {
1877        if(SM_BASE_ID(sm,vid[i]))
1878          bcnt++;
1879 <      if(SM_DIR_ID(sm,vid[i]))
1880 <        dcnt++;
1881 <      
1879 >      else
1880 >        if(SM_DIR_ID(sm,vid[i]))
1881 >          dcnt++;
1882      }
1883 <    /* TEST 1: If the new sample is close in ws, and close in the spherical
1884 <       projection to one of the triangle vertex samples
1885 <    */
1886 < #if 0
1887 <    norm = FALSE;
1888 <      VSUB(spt,p,SM_VIEW_CENTER(sm));
1889 <      ds = DOT(spt,spt);
1890 <      dnear = FHUGE;
1891 <      for(i=0; i<3; i++)
1892 <        {
1893 <          d = DOT(diff[i],diff[i])/ds;
1894 <          if(d < dnear)
1895 <            {
1896 <              dnear = d;
1897 <              nearid=vid[i];
1281 <            }
1282 <        }
1283 <
1284 <      if(dnear <=  SM_MIN_SAMP_DIFF*SM_MIN_SAMP_DIFF)
1285 <        {
1286 <          /* Pick the point with dir closest to that of the canonical view
1287 <             if it is the new sample: mark existing point for deletion
1288 <             */
1289 <          if(SM_BASE_ID(sm,nearid))
1290 <          {
1291 <            *rptr = nearid;
1292 <            return(TRUE);
1293 <          }
1294 <          if(SM_DIR_ID(sm,nearid))
1295 <            return(FALSE);
1296 <          if(!dir)
1297 <          {
1298 <            *rptr = nearid;
1299 <            return(TRUE);
1300 <          }
1301 <          normalize(spt);
1302 <          norm = TRUE;
1303 <          VSUB(npt,SM_NTH_WV(sm,nearid),SM_VIEW_CENTER(sm));
1304 <          normalize(npt);
1305 <          d = fdir2diff(SM_NTH_W_DIR(sm,nearid), npt);
1306 <          d2 = 2. - 2.*DOT(dir,spt);
1307 <          /* The existing sample is a better sample:punt */
1308 <         if(d2 > d)
1309 <            return(FALSE);
1310 <         else
1311 <         {
1312 <        /* The new sample is better: mark the existing one
1313 <                   for deletion after the new one is added*/
1314 <        *rptr = nearid;
1315 <        return(TRUE);
1316 <        }
1317 <     }  
1318 <    
1319 <  /* TEST 3: If the spherical projection of new is < S_REPLACE_EPS
1320 <     from a base point: Edge length is constrained to subtend <45 degrees:
1321 <     original base mesh edges are approx 32 degrees- so have about 13 degrees
1322 <     to work in: S_REPLACE_EPS is the square of the radian value
1323 <  */
1324 <
1325 <    if(bcnt)
1326 <    {  
1327 <        dnear = FHUGE;
1328 <        if(!norm)
1329 <          normalize(spt);
1330 <
1331 <        for(i=0; i<3; i++)
1332 <        {
1333 <            if(!SM_BASE_ID(sm,vid[i]))
1334 <               continue;
1335 <            VSUB(npt,SM_NTH_WV(sm,vid[i]),SM_VIEW_CENTER(sm));
1336 <            d = DIST_SQ(npt,spt);
1337 <            if(dnear <=  SM_MIN_SAMP_DIFF*SM_MIN_SAMP_DIFF && d< near)
1338 <               {
1339 <                   dnear = d;
1340 <                   nearid = vid[i];
1341 <               }
1342 <        }
1343 <        if(dnear != FHUGE)
1344 <        {
1345 <            /* add new and mark the base for deletion */
1346 <            *rptr = nearid;
1347 <            return(TRUE);
1348 <        }
1883 >    if( on == IN_T)
1884 >    {
1885 >      d = DIST_SQ(n0,ns);
1886 >      dnear = d;
1887 >      nearid = 0;
1888 >      d = DIST_SQ(n1,ns);
1889 >      if(d < dnear)
1890 >      {
1891 >        dnear = d; nearid = 1;
1892 >      }
1893 >      d = DIST_SQ(n2,ns);
1894 >      if(d < dnear)
1895 >      {
1896 >        dnear = d; nearid = 2;
1897 >      }
1898      }
1899 < #else
1899 >    if(on == ON_P)
1900 >      nearid = which;
1901 >    if(on == ON_P || dnear < VERT_EPS*VERT_EPS)
1902      {
1903 <      FVECT nearpt;
1904 <    dnear = FHUGE;
1905 <    VSUB(spt,p,SM_VIEW_CENTER(sm));
1906 <    ds = DOT(spt,spt);
1907 <    normalize(spt);
1903 >      FVECT edir;
1904 >      /* Pick the point with dir closest to that of the canonical view
1905 >         if it is the new sample: mark existing point for deletion
1906 >         */
1907 >      if(SM_BASE_ID(sm,vid[nearid]))
1908 >        return(FALSE);
1909 >      if(!dir)
1910 >        return(FALSE);
1911 >      if(SM_DIR_ID(sm,vid[nearid]))
1912 >      {
1913 >        *rptr = vid[nearid];
1914 >        return(TRUE);
1915 >      }
1916 >      decodedir(edir,SM_NTH_W_DIR(sm,vid[nearid]));
1917 >      if(nearid == 0)
1918 >        d = DOT(edir,n0);
1919 >      else
1920 >        if(nearid == 1)
1921 >          d = DOT(edir,n1);
1922 >        else
1923 >          d = DOT(edir,n2);
1924 >      d2 = DOT(dir,ns);
1925 >      /* The existing sample is a better sample:punt */
1926 >      if(d2 >= d)
1927 >        return(FALSE);
1928 >      else
1929 >      {
1930 >        /* The new sample is better: mark existing one for deletion*/
1931 >        *rptr = vid[nearid];
1932 >        return(TRUE);
1933 >      }
1934 >    }  
1935  
1936 <    for(i=0; i<3; i++)
1936 > /* Now test if sample epsilon is within circumcircle of enclosing tri
1937 >   if not punt:
1938 >   */
1939      {
1940 <        
1361 <      VSUB(npt,SM_NTH_WV(sm,vid[i]),SM_VIEW_CENTER(sm));
1362 <      
1363 <      if(!SM_BASE_ID(sm,vid[i]) && !SM_DIR_ID(sm,vid[i]))
1364 <        normalize(npt);
1940 >      double ab[3],ac[3],r[3];
1941  
1942 <      d = DIST_SQ(npt,spt);
1943 <      if(d < SM_MIN_SAMP_DIFF*SM_MIN_SAMP_DIFF && d < dnear)
1942 >      VSUB(ab,n2,n1);
1943 >      VSUB(ac,n0,n2);
1944 >      VCROSS(r,ab,ac);
1945 >      dp = DOT(r,n1);
1946 >      dp1 = DOT(r,ns);
1947 >      if(dp1*dp1 + COS_VERT_EPS*DOT(r,r) < dp*dp)
1948          {
1949 <          dnear = d;
1950 <          nearid = vid[i];
1951 <          VCOPY(nearpt,npt);
1949 > #ifdef DEBUG
1950 >          eputs("smTest_samp:rejecting samp,cant guarantee not within eps\n");
1951 > #endif
1952 >          return(FALSE);
1953          }
1373
1954      }
1955 <    if(dnear != FHUGE)
1955 > #ifdef DEBUG
1956 > #if DEBUG > 1
1957 >    if(on == ON_E)
1958      {
1959 <          /* Pick the point with dir closest to that of the canonical view
1960 <             if it is the new sample: mark existing point for deletion
1961 <             */
1962 <          if(SM_BASE_ID(sm,nearid))
1963 <          {
1964 <            *rptr = nearid;
1965 <            return(TRUE);
1966 <          }
1967 <          if(SM_DIR_ID(sm,nearid))
1968 <            return(FALSE);
1969 <          if(!dir)
1970 <          {
1971 <            *rptr = nearid;
1972 <            return(TRUE);
1973 <          }
1974 <          d = fdir2diff(SM_NTH_W_DIR(sm,nearid), nearpt);
1975 <          d2 = 2. - 2.*DOT(dir,spt);
1976 <          /* The existing sample is a better sample:punt */
1977 <         if(d2 > d)
1978 <            return(FALSE);
1979 <         else
1980 <         {
1981 <        /* The new sample is better: mark the existing one
1982 <                   for deletion after the new one is added*/
1401 <        *rptr = nearid;
1402 <        return(TRUE);
1403 <        }
1404 <    }  
1959 >      TRI *topp;
1960 >      int opp_id;
1961 >      FVECT vopp;
1962 >
1963 >      topp = SM_NTH_TRI(sm,T_NTH_NBR(tri,which));
1964 >      opp_id = T_NTH_V(topp, T_NTH_NBR_PTR(tri_id,topp));
1965 >      /* first check if valid tri created*/
1966 >      VSUB(vopp,SM_NTH_WV(sm,opp_id),SM_VIEW_CENTER(sm));
1967 >      normalize(vopp);
1968 >      VCROSS(n,ns,vopp);
1969 >      normalize(n);
1970 >      if(which==2)
1971 >        dp = DOT(n,n0) * DOT(n,n1);
1972 >      else
1973 >        if(which==0)
1974 >          dp = DOT(n,n1) * DOT(n,n2);
1975 >        else
1976 >          dp = DOT(n,n2) * DOT(n,n0);
1977 >      if(dp > 0.0)
1978 >      {
1979 >        eputs("smInsert_samp_mesh: couldn't split edge: rejecting\n");
1980 >        /* test epsilon for edge */
1981 >        return(FALSE);
1982 >      }
1983      }
1984 < #endif  
1984 > #endif
1985 > #endif
1986    /* TEST 4:
1987       If the addition of the new sample point would introduce a "puncture"
1988       or cause new triangles with large depth differences:dont add:    
# Line 1411 | Line 1990 | smTest_sample(sm,tri_id,dir,p,rptr)
1990      if(bcnt || dcnt)
1991         return(TRUE);
1992  
1993 <    /* If the new point is in front of the existing points- add */
1415 <    dv = DIST_SQ(SM_NTH_WV(sm,vid[0]),SM_VIEW_CENTER(sm));
1416 <    if(ds < dv)
1993 >    if(ds < d0)
1994        return(TRUE);
1995  
1996      d01 = DIST_SQ(SM_NTH_WV(sm,vid[1]),SM_NTH_WV(sm,vid[0]));
# Line 1441 | Line 2018 | smTest_sample(sm,tri_id,dir,p,rptr)
2018    /* TEST 5:
2019       Check to see if triangle is relatively large and should therefore
2020       be subdivided anyway.
2021 <     */
2022 <    dv *= DIST_SQ(SM_NTH_WV(sm,vid[1]),SM_VIEW_CENTER(sm));
2023 <    dv *= DIST_SQ(SM_NTH_WV(sm,vid[2]),SM_VIEW_CENTER(sm));
2024 <    if (d01*d12*d20/dv > S_REPLACE_TRI)
2021 >     */  
2022 >    d0 = d0*d0*DIST_SQ(SM_NTH_WV(sm,vid[1]),SM_VIEW_CENTER(sm));
2023 >    d0 *= DIST_SQ(SM_NTH_WV(sm,vid[2]),SM_VIEW_CENTER(sm));
2024 >    if (d01*d12*d20/d0 > S_REPLACE_TRI)
2025          return(TRUE);
2026              
2027      return(FALSE);
2028   }
1452
1453 smReplace_base_samp(sm,b_id,s_id,tri,t_id,which)
1454 SM *sm;
1455 int b_id,s_id;
1456 TRI *tri;
1457 int t_id,which;
1458 {
1459  TRI *t;
1460
1461  SM_NTH_VERT(sm,s_id) = t_id;
1462  T_NTH_V(tri,which) = s_id;
1463  if(!(SM_BASE_ID(sm,T_NTH_V(tri,(which+1)%3)) ||
1464       SM_BASE_ID(sm,T_NTH_V(tri,(which+2)%3))))
1465    SM_CLR_NTH_T_BASE(sm,t_id);
1466  if(!SM_IS_NTH_T_NEW(sm,t_id))
1467  {
1468    smNew_tri_cnt++;
1469    SM_SET_NTH_T_NEW(sm,t_id);
1470  }
1471  t_id = smTri_next_ccw_nbr(sm,tri,b_id);
1472  while(t_id != INVALID)
1473  {
1474    t = SM_NTH_TRI(sm,t_id);
1475    which = T_WHICH_V(t,b_id);
1476    T_NTH_V(t,which) = s_id;
1477    /* Check if still a base triangle */
1478    if(!(SM_BASE_ID(sm,T_NTH_V(t,(which+1)%3)) ||
1479         SM_BASE_ID(sm,T_NTH_V(t,(which+2)%3))))
1480      SM_CLR_NTH_T_BASE(sm,t_id);
1481     if(!SM_IS_NTH_T_NEW(sm,t_id))
1482        {
1483          smNew_tri_cnt++;
1484          SM_SET_NTH_T_NEW(sm,t_id);
1485        }
1486     t_id = smTri_next_ccw_nbr(sm,t,b_id);
1487    }
1488 }
1489
2029   int
2030 < smReplace_samp(sm,c,dir,p,s_id,t_id,o_id,on,which)
2030 > smReplace_samp(sm,c,dir,p,np,s_id,t_id,o_id,on,which)
2031       SM *sm;
2032       COLR c;
2033 <     FVECT dir,p;
2033 >     FVECT dir,p,np;
2034       int s_id,t_id,o_id,on,which;
2035   {
2036    int v_id,tri_id;
# Line 1502 | Line 2041 | smReplace_samp(sm,c,dir,p,s_id,t_id,o_id,on,which)
2041  
2042    /* If it is a base id, need new sample */
2043    if(SM_BASE_ID(sm,v_id))
2044 <  {
2045 <    sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id);
2046 <    smReplace_base_samp(sm,v_id,s_id,tri,t_id,which);
2047 <    return(s_id);
2048 <  }
2044 >    return(v_id);
2045 >
2046 >  if(EQUAL_VEC3(p,SM_NTH_WV(sm,v_id)))
2047 >    return(INVALID);
2048 >
2049    if(dir)
2050 <  {
2051 <    /* If world point */
2052 <    /* if existing point is a dir: leave */
2053 <    if(SM_DIR_ID(sm,v_id))
2054 <      return(INVALID);
2055 <    if(on == ON_V)
2050 >  {    /* If world point */
2051 >     FVECT odir,no;
2052 >     double d,d1;
2053 >     int dir_id;
2054 >    /* if existing point is a not a dir, compare directions */
2055 >    if(!(dir_id = SM_DIR_ID(sm,v_id)))
2056      {
2057 +      decodedir(odir, SM_NTH_W_DIR(sm,v_id));  
2058 +      VSUB(no,SM_NTH_WV(sm,v_id),SM_VIEW_CENTER(sm));
2059 +      d = DOT(dir,np);
2060 +      d1 = DOT(odir,np);
2061 +     /* The existing sample is a better sample:punt */
2062 +    }
2063 +    if(dir_id || (d*d*DOT(no,no) > d1*d1))
2064 +    {
2065 +      /* The new sample has better information- replace values */
2066        sInit_samp(SM_SAMP(sm),v_id,c,dir,p,o_id);
2067 <
2068 <     if(!SM_IS_NTH_T_NEW(sm,t_id))
1521 <        {
1522 <          smNew_tri_cnt++;
1523 <          SM_SET_NTH_T_NEW(sm,t_id);
1524 <        }
2067 >      if(!SM_IS_NTH_T_NEW(sm,t_id))
2068 >         SM_SET_NTH_T_NEW(sm,t_id);
2069        tri_id = smTri_next_ccw_nbr(sm,tri,v_id);
2070        while(tri_id != t_id)
2071        {
2072          t = SM_NTH_TRI(sm,tri_id);
2073 <     if(!SM_IS_NTH_T_NEW(sm,tri_id))
1530 <        {
1531 <          smNew_tri_cnt++;
2073 >        if(!SM_IS_NTH_T_NEW(sm,tri_id))
2074            SM_SET_NTH_T_NEW(sm,tri_id);
1533        }
1534
2075          tri_id = smTri_next_ccw_nbr(sm,t,v_id);
2076        }
1537      return(v_id);
2077      }
1539    /* on == ON_P */
1540    else
1541   {
1542     FVECT spt,npt;
1543     double d,d2;
1544
1545    /* Need to check which sample is preferable */
1546     VSUB(spt,p,SM_VIEW_CENTER(sm));
1547     normalize(spt);
1548        
1549     VSUB(npt,SM_NTH_WV(sm,v_id),SM_VIEW_CENTER(sm));
1550     normalize(npt);
1551     d = fdir2diff(SM_NTH_W_DIR(sm,v_id), npt);
1552     d2 = 2. - 2.*DOT(dir,spt);
1553      /* The existing sample is a better sample:punt */
1554     if(d2 < d)
1555       {
1556         /* The new sample has better information- replace values */
1557         sInit_samp(SM_SAMP(sm),v_id,c,dir,p,o_id);
1558         if(!SM_IS_NTH_T_NEW(sm,t_id))
1559            {
1560              smNew_tri_cnt++;
1561              SM_SET_NTH_T_NEW(sm,t_id);
1562            }
1563
1564         tri_id = smTri_next_ccw_nbr(sm,tri,v_id);
1565         while(tri_id != t_id)
1566           {
1567             t = SM_NTH_TRI(sm,tri_id);
1568             if(!SM_IS_NTH_T_NEW(sm,tri_id))
1569            {
1570              smNew_tri_cnt++;
1571              SM_SET_NTH_T_NEW(sm,tri_id);
1572            }
1573             tri_id = smTri_next_ccw_nbr(sm,t,v_id);
1574           }
1575       }
2078      return(v_id);
1577   }
2079    }
2080 <  else
2081 <    { /* New point is a dir */
2082 <      return(INVALID);
1582 <    }
2080 >  else  /* New point is a dir */
2081 >  return(INVALID);
2082 >
2083   }
2084  
2085   int
# Line 1592 | Line 2092 | SM *sm;
2092  
2093    s = SM_SAMP(sm);
2094    s_id = sAlloc_samp(s,&replaced);
1595
1596  cnt=0;
2095    while(replaced)
2096    {
2097 <    if(smRemoveVertex(sm,s_id))
1600 <      break;
2097 >    smRemoveVertex(sm,s_id);
2098      s_id = sAlloc_samp(s,&replaced);
1602    cnt++;
1603    if(cnt > S_MAX_SAMP(s))
1604      error(CONSISTENCY,"smAlloc_samp():unable to find free samp\n");
2099    }
2100    return(s_id);
2101   }
# Line 1627 | Line 2121 | smAdd_samp(sm,c,dir,p,o_id)
2121     FVECT dir,p;
2122     int o_id;
2123   {
2124 <  int t_id,s_id,r_id,on,which,n_id;
2125 <  double d;
2126 <  FVECT wpt;
2124 >  int t_id,s_id,r_id,on,which,n_id,nbr_id;
2125 >  double ds,d0;
2126 >  FVECT wpt,ns,n0,n1,n2;
2127 >  QUADTREE qt,parent;
2128 >  TRI *t;
2129  
2130    r_id = INVALID;
2131 <
2131 >  nbr_id = INVALID;
2132    /* Must do this first-as may change mesh */
2133    s_id = smAlloc_samp(sm);
2134 +
2135 +  SM_S_NTH_QT(sm,s_id)= EMPTY;
2136    /* If sample is a world space point */
2137    if(p)
2138    {
2139 +    VSUB(ns,p,SM_VIEW_CENTER(sm));
2140 +    ds = normalize(ns);
2141      while(1)
2142      {
2143 <      t_id = smPointLocateTri(sm,p,&on,&which);
2143 >      t_id = smSample_locate_tri(sm,ns,s_id,&on,&which,&nbr_id);
2144 >      qt = SM_S_NTH_QT(sm,s_id);
2145        if(t_id == INVALID)
2146        {
2147   #ifdef DEBUG
2148            eputs("smAddSamp(): unable to locate tri containing sample \n");
2149   #endif
2150            smUnalloc_samp(sm,s_id);
2151 +          qtremovelast(qt,s_id);
2152            return(INVALID);
2153          }
2154        /* If spherical projection coincides with existing sample: replace */
2155 <      if((on == ON_V || on == ON_P))
2155 >      if(on == ON_V)
2156        {
2157 <          n_id = smReplace_samp(sm,c,dir,p,s_id,t_id,o_id,on,which);
2158 <          if(n_id!= s_id)
2159 <             smUnalloc_samp(sm,s_id);
2157 >          n_id = smReplace_samp(sm,c,dir,p,ns,s_id,t_id,o_id,on,which);
2158 >          if(n_id != s_id)
2159 >          {
2160 >            smUnalloc_samp(sm,s_id);
2161 > #if 0
2162 >            fprintf(stderr,"Unallocating sample %d\n",s_id);
2163 > #endif
2164 >            qtremovelast(qt,s_id);
2165 >          }
2166            return(n_id);
2167        }
2168 <      if((!(smTest_sample(sm,t_id,dir,p,&r_id))))
2169 <     {
2168 >      t = SM_NTH_TRI(sm,t_id);
2169 >      VSUB(n0,SM_NTH_WV(sm,T_NTH_V(t,0)),SM_VIEW_CENTER(sm));
2170 >      d0 = normalize(n0);
2171 >      VSUB(n1,SM_NTH_WV(sm,T_NTH_V(t,1)),SM_VIEW_CENTER(sm));
2172 >      normalize(n1);
2173 >      VSUB(n2,SM_NTH_WV(sm,T_NTH_V(t,2)),SM_VIEW_CENTER(sm));
2174 >      normalize(n2);
2175 >      if((!(smTest_samp(sm,t_id,dir,p,&r_id,ns,n0,n1,n2,ds,d0,on,which))))
2176 >      {
2177          smUnalloc_samp(sm,s_id);
2178 + #if 0
2179 +            fprintf(stderr,"Unallocating sample %d\n",s_id);
2180 + #endif
2181 +        qtremovelast(qt,s_id);
2182          return(INVALID);
2183        }
2184        if(r_id != INVALID)
2185        {
2186          smRemoveVertex(sm,r_id);
2187 <        sDelete_samp(SM_SAMP(sm),r_id);
2187 >        if(nbr_id == r_id)
2188 >        {
2189 >          qtremovelast(qt,s_id);
2190 >          SM_S_NTH_QT(sm,s_id) = EMPTY;
2191 >        }
2192        }
2193        else
2194          break;
# Line 1675 | Line 2198 | smAdd_samp(sm,c,dir,p,o_id)
2198         */
2199      /* Initialize sample */
2200      sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id);
2201 <    
2201 >    /* If not base or sky point, add distance from center to average*/  
2202 >    smDist_sum += 1.0/ds;
2203 >    smInsert_samp_mesh(sm,s_id,t_id,ns,n0,n1,n2,on,which);
2204    }
2205      /* If sample is a direction vector */
2206      else
2207      {
2208        VADD(wpt,dir,SM_VIEW_CENTER(sm));
2209        while(1)
2210 <        {
2211 <            t_id = smPointLocateTri(sm,wpt,&on,&which);
2212 <            if(t_id == INVALID)
1688 <               {
2210 >      {
2211 >        t_id = smSample_locate_tri(sm,dir,s_id,&on,&which,&nbr_id);
2212 >        qt = SM_S_NTH_QT(sm,s_id);
2213   #ifdef DEBUG
2214 <                   eputs("smAddSamp(): can'tlocate tri containing samp\n");
2214 >        if(t_id == INVALID)
2215 >        {
2216 >          eputs("smAddSamp():can't locate tri containing samp\n");
2217 >          smUnalloc_samp(sm,s_id);
2218 >          qtremovelast(qt,s_id);
2219 >          return(INVALID);
2220 >        }
2221   #endif
2222 <                   smUnalloc_samp(sm,s_id);
2223 <                   return(INVALID);
2224 <               }
2225 <            if(on == ON_V || on == ON_P)
2226 <            {
2227 <                n_id=smReplace_samp(sm,c,NULL,wpt,s_id,t_id,o_id,on,which);
2228 <                if(n_id !=s_id)
2229 <                   smUnalloc_samp(sm,s_id);
2230 <                return(n_id);
2231 <            }
2232 <            if((!(smTest_sample(sm,t_id,NULL,wpt,&r_id))))
2222 >        if(on == ON_V)
2223 >        {
2224 >          smUnalloc_samp(sm,s_id);
2225 >          qtremovelast(qt,s_id);
2226 >          return(INVALID);
2227 >        }
2228 >        t = SM_NTH_TRI(sm,t_id);
2229 >        VSUB(n0,SM_NTH_WV(sm,T_NTH_V(t,0)),SM_VIEW_CENTER(sm));
2230 >        d0 = normalize(n0);
2231 >        VSUB(n1,SM_NTH_WV(sm,T_NTH_V(t,1)),SM_VIEW_CENTER(sm));
2232 >        normalize(n1);
2233 >        VSUB(n2,SM_NTH_WV(sm,T_NTH_V(t,2)),SM_VIEW_CENTER(sm));
2234 >        normalize(n2);
2235 >        if(!smTest_samp(sm,t_id,NULL,wpt,&r_id,dir,n0,n1,n2,1.0,d0,on,which))
2236 >        {
2237 >          smUnalloc_samp(sm,s_id);
2238 >          qtremovelast(qt,s_id);
2239 >          return(INVALID);
2240 >        }
2241 >        if(r_id != INVALID)
2242 >        {
2243 >          smRemoveVertex(sm,r_id);
2244 >          if(nbr_id == r_id)
2245              {
2246 <                smUnalloc_samp(sm,s_id);
2247 <                return(INVALID);
2246 >              qtremovelast(qt,s_id);
2247 >              SM_S_NTH_QT(sm,s_id) = EMPTY;
2248              }
1707            if(r_id != INVALID)
1708            {
1709                smRemoveVertex(sm,r_id);
1710                sDelete_samp(SM_SAMP(sm),r_id);
1711            }
1712            else
1713               break;
2249          }
2250 +        else
2251 +          break;
2252 +      }
2253        /* Allocate space for a sample and initialize */
2254        sInit_samp(SM_SAMP(sm),s_id,c,NULL,wpt,o_id);
2255 +      smInsert_samp_mesh(sm,s_id,t_id,dir,n0,n1,n2,on,which);
2256      }
1718  if(!SM_DIR_ID(sm,s_id))
1719    {
1720      /* If not a base or sky point, add distance from the
1721         viewcenter to average*/
1722      d = DIST(SM_NTH_WV(sm,s_id),SM_VIEW_CENTER(sm));
1723      smDist_sum += 1.0/d;
1724    }
1725    smInsert_samp(sm,s_id,t_id,on,which);
1726
2257      return(s_id);
2258   }
2259  
# Line 1745 | Line 2275 | FVECT dir;
2275   FVECT p;
2276   {
2277      int s_id;
1748
2278      /* First check if this the first sample: if so initialize mesh */
2279      if(SM_NUM_SAMP(smMesh) == 0)
2280      {
# Line 1755 | Line 2284 | FVECT p;
2284      /* Add the sample to the mesh */
2285      s_id = smAdd_samp(smMesh,c,dir,p,INVALID);
2286  
2287 + #if 0
2288 +    {
2289 +      int i;
2290 +      FILE *fp;
2291 +      if(s_id == 10000)
2292 +        {
2293 +          fp = fopen("test.xyz","w");
2294 +          for(i=0; i < s_id; i++)
2295 +            if(!SM_DIR_ID(smMesh,i))
2296 +              fprintf(fp,"%f %f %f %d %d %d \n",SM_NTH_WV(smMesh,i)[0],
2297 +                    SM_NTH_WV(smMesh,i)[1],SM_NTH_WV(smMesh,i)[2],
2298 +                    SM_NTH_RGB(smMesh,i)[0],SM_NTH_RGB(smMesh,i)[1],
2299 +                    SM_NTH_RGB(smMesh,i)[2]);
2300 +          fclose(fp);
2301 +        }
2302 +    }
2303 + #endif    
2304      return(s_id);
2305      
2306   }    
# Line 1787 | Line 2333 | SM *sm;
2333   int type;
2334   {
2335    int i,s_id,tri_id,nbr_id;
2336 <  int p[SM_EXTRA_POINTS],ids[SM_BASE_TRIS];
2336 >  int p[SM_BASE_POINTS],ids[SM_BASE_TRIS];
2337    int v0_id,v1_id,v2_id;
2338    FVECT d,pt,cntr,v0,v1,v2;
2339    TRI *t;
2340  
2341    /* First insert the base vertices into the sample point array */
2342  
2343 <  for(i=0; i < SM_EXTRA_POINTS; i++)
2343 >  for(i=0; i < SM_BASE_POINTS; i++)
2344    {
2345      VADD(cntr,icosa_verts[i],SM_VIEW_CENTER(sm));
2346      p[i]  = smAdd_base_vertex(sm,cntr);
2347 +    smInsert_samp(sm,p[i],icosa_verts[i],NULL);
2348    }
2349    /* Create the base triangles */
2350    for(i=0;i < SM_BASE_TRIS; i++)
# Line 1805 | Line 2352 | int type;
2352      v0_id = p[icosa_tris[i][0]];
2353      v1_id = p[icosa_tris[i][1]];
2354      v2_id = p[icosa_tris[i][2]];
2355 <    ids[i] = smAdd_tri(sm, v0_id,v1_id,v2_id);
2355 >    ids[i] = smAdd_tri(sm, v0_id,v1_id,v2_id,&t);
2356      /* Set neighbors */
2357      for(nbr_id=0; nbr_id < 3; nbr_id++)
2358        T_NTH_NBR(SM_NTH_TRI(sm,ids[i]),nbr_id) = icosa_nbrs[i][nbr_id];
2359  
2360    }
1814  for(i=0;i < SM_BASE_TRIS; i++)
1815  {
1816    t = SM_NTH_TRI(sm,ids[i]);
1817    smLocator_add_tri(sm,ids[i],T_NTH_V(t,0),T_NTH_V(t,1),T_NTH_V(t,2));
1818  }
2361   return(1);
2362  
2363   }
2364  
2365 < smRebuild_mesh(sm,v)
2365 > smRebuild(sm,v)
2366     SM *sm;
2367     VIEW *v;
2368   {
# Line 1829 | Line 2371 | smRebuild_mesh(sm,v)
2371      double d;
2372  
2373   #ifdef DEBUG
2374 <    fprintf(stderr,"smRebuild_mesh(): rebuilding....");
2374 >    fprintf(stderr,"smRebuild(): rebuilding....");
2375   #endif
2376      smCull(sm,v,SM_ALL_LEVELS);
2377      /* Clear the mesh- and rebuild using the current sample array */
# Line 1838 | Line 2380 | smRebuild_mesh(sm,v)
2380      /* Calculate the difference between the current and new viewpoint*/
2381      /* Will need to subtract this off of sky points */
2382      VCOPY(ov,SM_VIEW_CENTER(sm));
1841    /* Initialize the mesh to 0 samples and the base triangles */
2383  
2384 +    /* Initialize the mesh to 0 samples and the base triangles */
2385 +    smInit_sm(sm,v->vp);
2386      /* Go through all samples and add in if in the new view frustum, and
2387         the dir is <= 30 degrees from new view
2388       */
1846    smInit_sm(sm,v->vp);
2389      for(i=0; i < cnt; i++)
2390      {
2391        /* First check if sample visible(conservative approx: if one of tris
2392           attached to sample is in frustum)       */
2393        if(!S_IS_FLAG(i))
2394          continue;
2395 <
2396 <      /* Next test if direction > 30 from current direction */
2395 >      
2396 >      /* Next test if direction > 30 degrees from current direction */
2397          if(SM_NTH_W_DIR(sm,i)!=-1)
2398          {
2399              VSUB(p,SM_NTH_WV(sm,i),v->vp);
1858            normalize(p);
2400              decodedir(dir,SM_NTH_W_DIR(sm,i));
2401 <            d = 2. - 2.*DOT(dir,p);
2402 <            if (d > MAXDIFF2)
2401 >            d = DOT(dir,p);
2402 >            if (d*d < MAXDIFF2*DOT(p,p))
2403                continue;
2404              VCOPY(p,SM_NTH_WV(sm,i));
2405              smAdd_samp(sm,NULL,dir,p,i);
2406          }
2407          else
2408          {
2409 +          /* If the direction is > 45 degrees from current view direction:
2410 +             throw out
2411 +           */
2412            VSUB(dir,SM_NTH_WV(sm,i),ov);
2413 +          if(DOT(dir,v->vdir) < MAXDIR)
2414 +            continue;
2415 +
2416            VADD(SM_NTH_WV(sm,i),dir,SM_VIEW_CENTER(sm));
2417            smAdd_samp(sm,NULL,dir,NULL,i);
2418          }
2419  
2420      }
2421   #ifdef DEBUG
2422 <    fprintf(stderr,"smRebuild_mesh():done\n");
2422 >    fprintf(stderr,"smRebuild():done\n");
2423   #endif
2424   }
2425  
# Line 1888 | Line 2435 | intersect_tri_set(t_set,orig,dir,pt)
2435      TRI *t;
2436      double d,d1;
2437      
2438 <    optr = QT_SET_PTR(t_set);
2438 >    optr = t_set;
2439      for(i = QT_SET_CNT(t_set); i > 0; i--)
2440      {
2441          t_id = QT_SET_NEXT_ELEM(optr);
# Line 2037 | Line 2584 | FVECT orig,dir;
2584    /* orig will be updated-so preserve original value */
2585    if(!smMesh)
2586       return;
2040 #ifdef TEST_DRIVER
2041  Picking= TRUE;
2042 #endif  
2587  
2588    if(EQUAL_VEC3(orig,SM_VIEW_CENTER(smMesh)))
2589    {
2590 <    qt = smPointLocateCell(smMesh,dir);
2590 >    qt = smPoint_locate_cell(smMesh,dir);
2591      if(QT_IS_EMPTY(qt))
2592        goto Lerror;
2593      ts = qtqueryset(qt);
2594      s_id = intersect_tri_set(ts,orig,dir,p);
2051 #ifdef DEBUG_TEST_DRIVER
2052    VCOPY(Pick_point[0],p);
2053 #endif
2595      return(s_id);
2596    }
2597    d = point_on_sphere(b,orig,SM_VIEW_CENTER(smMesh));
2598    if(EQUAL_VEC3(b,dir))
2599    {
2600 <    qt = smPointLocateCell(smMesh,dir);
2600 >    qt = smPoint_locate_cell(smMesh,dir);
2601      if(QT_IS_EMPTY(qt))
2602        goto Lerror;
2603      ts = qtqueryset(qt);
2604      s_id = intersect_tri_set(ts,orig,dir,p);
2605 < #ifdef DEBUG_TEST_DRIVER
2065 <        VCOPY(Pick_point[0],p);
2066 < #endif
2067 <        return(s_id);
2605 >    return(s_id);
2606    }
2607    if(OPP_EQUAL_VEC3(b,dir))
2608    {
2609 <    qt = smPointLocateCell(smMesh,orig);
2609 >    qt = smPoint_locate_cell(smMesh,orig);
2610      if(QT_IS_EMPTY(qt))
2611        goto Lerror;
2612      ts = qtqueryset(qt);
2613      s_id = intersect_tri_set(ts,orig,dir,p);
2614 < #ifdef DEBUG_TEST_DRIVER
2615 <        VCOPY(Pick_point[0],p);
2078 < #endif
2079 <        if(s_id != INVALID)
2080 <        {
2614 >    if(s_id != INVALID)
2615 >     {
2616   #ifdef DEBUG
2617      fprintf(stderr,"Front pick returning %d\n",s_id);
2618   #endif
2619            return(s_id);
2620 <        }
2621 <        qt = smPointLocateCell(smMesh,dir);
2622 <        if(QT_IS_EMPTY(qt))
2623 <          goto Lerror;
2624 <        ts = qtqueryset(qt);
2625 <        s_id = intersect_tri_set(ts,orig,dir,p);
2091 < #ifdef DEBUG_TEST_DRIVER
2092 <        VCOPY(Pick_point[0],p);
2093 < #endif
2620 >     }
2621 >    qt = smPoint_locate_cell(smMesh,dir);
2622 >    if(QT_IS_EMPTY(qt))
2623 >      goto Lerror;
2624 >    ts = qtqueryset(qt);
2625 >    s_id = intersect_tri_set(ts,orig,dir,p);
2626   #ifdef DEBUG
2627      fprintf(stderr,"Back pick returning %d\n",s_id);
2628   #endif
2629 <        return(s_id);
2629 >    return(s_id);
2630    }
2631    {
2632      OBJECT t_set[QT_MAXCSET + 1];
# Line 2134 | Line 2666 | null_func(argptr,root,qt,n)
2666    /* do nothing */
2667   }
2668  
2669 < mark_active_tris(argptr,root,qt,n)
2669 > mark_active_samples(argptr,root,qt,n)
2670       int *argptr;
2671       int root;
2672       QUADTREE qt;
2673       int n;
2674   {
2675 <  OBJECT *os,*optr;
2676 <  register int i,t_id;
2675 >  OBJECT *os;
2676 >  register int i,s_id,t_id,tri_id;
2677    TRI *tri;
2678  
2679    if(QT_IS_EMPTY(qt) || QT_LEAF_IS_FLAG(qt))
# Line 2150 | Line 2682 | mark_active_tris(argptr,root,qt,n)
2682    /* For each triangle in the set, set the which flag*/
2683    os = qtqueryset(qt);
2684  
2685 <  for (i = QT_SET_CNT(os), optr = QT_SET_PTR(os); i > 0; i--)
2685 >  for (i = QT_SET_CNT(os); i > 0; i--)
2686    {
2687 <    t_id = QT_SET_NEXT_ELEM(optr);
2688 <    /* Set the render flag */
2689 <     tri = SM_NTH_TRI(smMesh,t_id);
2690 <     if(!T_IS_VALID(tri))
2691 <            continue;
2692 <     SM_SET_NTH_T_ACTIVE(smMesh,t_id);
2693 <     /* Set the Active bits of the Vertices */
2694 <     S_SET_FLAG(T_NTH_V(tri,0));
2695 <     S_SET_FLAG(T_NTH_V(tri,1));
2696 <     S_SET_FLAG(T_NTH_V(tri,2));
2687 >    s_id = QT_SET_NEXT_ELEM(os);
2688 >    S_SET_FLAG(s_id);
2689 >
2690 >    tri_id = SM_NTH_VERT(smMesh,s_id);
2691 >    /* Set the active flag for all adjacent triangles */
2692 >     tri = SM_NTH_TRI(smMesh,tri_id);
2693 >     SM_SET_NTH_T_ACTIVE(smMesh,tri_id);
2694 >     while((t_id = smTri_next_ccw_nbr(smMesh,tri,s_id)) != tri_id)
2695 >     {
2696 >       tri = SM_NTH_TRI(smMesh,t_id);
2697 >       SM_SET_NTH_T_ACTIVE(smMesh,t_id);
2698 >     }
2699    }
2700 < }
2700 > }
2701  
2168
2702   smCull(sm,view,n)
2703   SM *sm;
2704   VIEW *view;
# Line 2187 | Line 2720 | smCull(sm,view,n)
2720          LRU counter: for use in discarding samples when out
2721          of space
2722          */
2723 <       F_FUNC(f) = mark_active_tris;
2723 >       F_FUNC(f) = mark_active_samples;
2724         smClear_flags(sm,T_ACTIVE_FLAG);
2725         /* Clear all of the active sample flags*/
2726         sClear_all_flags(SM_SAMP(sm));
# Line 2297 | Line 2830 | smCull(sm,view,n)
2830       }
2831  
2832   }
2833 +
2834 +
2835 +
2836 +
2837 +
2838 +
2839 +
2840 +
2841 +
2842 +
2843  
2844  
2845  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines