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.4 by gwlarson, Tue Aug 25 11:03:27 1998 UTC vs.
Revision 3.19 by schorsch, Mon Jun 30 14:59:12 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1998 Silicon Graphics, Inc. */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ SGI";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   *  sm.c
6   */
10 #include "standard.h"
7  
8 < #include "object.h"
8 > #include <string.h>
9  
10 + #include "standard.h"
11 + #include "sm_flag.h"
12   #include "sm_list.h"
13   #include "sm_geom.h"
14   #include "sm.h"
15  
18
16   SM *smMesh = NULL;
17   double smDist_sum=0;
21 int smNew_tri_cnt=0;
18  
19 + #ifdef DEBUG
20 + int Tcnt=0,Wcnt=0;
21 + #endif
22 + /* Each edge extends .372 radians  */
23 + static FVECT icosa_verts[162] =
24 + {{-0.018096,0.495400,0.868477},{0.018614,-0.554780,0.831789},
25 + {0.850436,0.011329,0.525956},{0.850116,0.048016,-0.524402},
26 + {-0.850116,-0.048016,0.524402},{-0.850436,-0.011329,-0.525956},
27 + {0.495955,0.867825,0.030147},{-0.555329,0.831118,0.029186},
28 + {0.555329,-0.831118,-0.029186},{-0.495955,-0.867825,-0.030147},
29 + {-0.018614,0.554780,-0.831789},{0.018096,-0.495400,-0.868477},
30 + {0.000305,-0.034906,0.999391},{0.489330,0.297837,0.819664},
31 + {0.510900,-0.319418,0.798094},{-0.488835,-0.354308,0.797186},
32 + {-0.510409,0.262947,0.818744},{0.999391,0.034875,0.000914},
33 + {0.791335,0.516672,0.326862},{0.791142,0.538234,-0.290513},
34 + {0.826031,-0.460219,-0.325378},{0.826216,-0.481780,0.291985},
35 + {-0.999391,-0.034875,-0.000914},{-0.826216,0.481780,-0.291985},
36 + {-0.826031,0.460219,0.325378},{-0.791142,-0.538234,0.290513},
37 + {-0.791335,-0.516672,-0.326862},{-0.034911,0.998782,0.034881},
38 + {0.280899,0.801316,0.528194},{-0.337075,0.779739,0.527624},
39 + {-0.337377,0.814637,-0.471746},{0.280592,0.836213,-0.471186},
40 + {0.034911,-0.998782,-0.034881},{-0.280592,-0.836213,0.471186},
41 + {0.337377,-0.814637,0.471746},{0.337075,-0.779739,-0.527624},
42 + {-0.280899,-0.801316,-0.528194},{-0.000305,0.034906,-0.999391},
43 + {0.510409,-0.262947,-0.818744},{0.488835,0.354308,-0.797186},
44 + {-0.510900,0.319418,-0.798094},{-0.489330,-0.297837,-0.819664},
45 + {0.009834,-0.306509,0.951817},{0.268764,-0.186284,0.945021},
46 + {0.275239,-0.454405,0.847207},{-0.009247,0.239357,0.970888},
47 + {0.244947,0.412323,0.877491},{0.257423,0.138235,0.956360},
48 + {0.525850,-0.011345,0.850502},{0.696394,0.160701,0.699436},
49 + {0.707604,-0.160141,0.688223},{-0.268186,0.119892,0.955878},
50 + {-0.274715,0.394186,0.877011},{-0.244420,-0.472542,0.846737},
51 + {-0.256843,-0.204627,0.944542},{-0.525332,-0.048031,0.849541},
52 + {-0.695970,-0.209123,0.686945},{-0.707182,0.111718,0.698149},
53 + {0.961307,0.043084,-0.272090},{0.941300,0.301289,-0.152245},
54 + {0.853076,0.304715,-0.423568},{0.961473,0.024015,0.273848},
55 + {0.853344,0.274439,0.443269},{0.941400,0.289953,0.172315},
56 + {0.831918,0.554570,0.019109},{0.669103,0.719629,0.185565},
57 + {0.669003,0.730836,-0.135332},{0.959736,-0.234941,0.153979},
58 + {0.871472,-0.244526,0.425140},{0.871210,-0.214250,-0.441690},
59 + {0.959638,-0.223606,-0.170573},{0.868594,-0.495213,-0.017555},
60 + {0.717997,-0.671205,-0.184294},{0.718092,-0.682411,0.136596},
61 + {-0.961307,-0.043084,0.272090},{-0.959638,0.223606,0.170573},
62 + {-0.871210,0.214250,0.441690},{-0.961473,-0.024015,-0.273848},
63 + {-0.871472,0.244526,-0.425140},{-0.959736,0.234941,-0.153979},
64 + {-0.868594,0.495213,0.017555},{-0.718092,0.682411,-0.136596},
65 + {-0.717997,0.671205,0.184294},{-0.941400,-0.289953,-0.172315},
66 + {-0.853344,-0.274439,-0.443269},{-0.853076,-0.304715,0.423568},
67 + {-0.941300,-0.301289,0.152245},{-0.831918,-0.554570,-0.019109},
68 + {-0.669003,-0.730836,0.135332},{-0.669103,-0.719629,-0.185565},
69 + {-0.306809,0.951188,0.033302},{-0.195568,0.935038,0.295731},
70 + {-0.463858,0.837300,0.289421},{0.239653,0.970270,0.033802},
71 + {0.403798,0.867595,0.290218},{0.129326,0.946383,0.296031},
72 + {-0.029535,0.831255,0.555106},{0.136603,0.674019,0.725974},
73 + {-0.184614,0.662804,0.725678},{0.129164,0.964728,-0.229382},
74 + {0.403637,0.885733,-0.229245},{-0.464015,0.855438,-0.230036},
75 + {-0.195726,0.953383,-0.229677},{-0.029855,0.867949,-0.495755},
76 + {-0.185040,0.711807,-0.677562},{0.136173,0.723022,-0.677271},
77 + {0.306809,-0.951188,-0.033302},{0.195726,-0.953383,0.229677},
78 + {0.464015,-0.855438,0.230036},{-0.239653,-0.970270,-0.033802},
79 + {-0.403637,-0.885733,0.229245},{-0.129164,-0.964728,0.229382},
80 + {0.029855,-0.867949,0.495755},{-0.136173,-0.723022,0.677271},
81 + {0.185040,-0.711807,0.677562},{-0.129326,-0.946383,-0.296031},
82 + {-0.403798,-0.867595,-0.290218},{0.463858,-0.837300,-0.289421}
83 + ,{0.195568,-0.935038,-0.295731},{0.029535,-0.831255,-0.555106},
84 + {0.184614,-0.662804,-0.725678},{-0.136603,-0.674019,-0.725974},
85 + {-0.009834,0.306509,-0.951817},{0.256843,0.204627,-0.944542},
86 + {0.244420,0.472542,-0.846737},{0.009247,-0.239357,-0.970888},
87 + {0.274715,-0.394186,-0.877011},{0.268186,-0.119892,-0.955878},
88 + {0.525332,0.048031,-0.849541},{0.707182,-0.111718,-0.698149},
89 + {0.695970,0.209123,-0.686945},{-0.257423,-0.138235,-0.956360},
90 + {-0.244947,-0.412323,-0.877491},{-0.275239,0.454405,-0.847207},
91 + {-0.268764,0.186284,-0.945021},{-0.525850,0.011345,-0.850502},
92 + {-0.707604,0.160141,-0.688223},{-0.696394,-0.160701,-0.699436},
93 + {0.563717,0.692920,0.449538},{0.673284,0.428212,0.602763},
94 + {0.404929,0.577853,0.708603},{0.445959,-0.596198,0.667584},
95 + {0.702960,-0.421213,0.573086},{0.611746,-0.681577,0.401523},
96 + {-0.445543,0.548166,0.707818},{-0.702606,0.380190,0.601498},
97 + {-0.611490,0.651895,0.448456},{-0.563454,-0.722602,0.400456},
98 + {-0.672921,-0.469235,0.571835},{-0.404507,-0.625886,0.666814},
99 + {0.404507,0.625886,-0.666814},{0.672921,0.469235,-0.571835},
100 + {0.563454,0.722602,-0.400456},{0.611490,-0.651895,-0.448456},
101 + {0.702606,-0.380190,-0.601498},{0.445543,-0.548166,-0.707818},
102 + {-0.611746,0.681577,-0.401523},{-0.702960,0.421213,-0.573086},
103 + {-0.445959,0.596198,-0.667584},{-0.404929,-0.577853,-0.708603},
104 + {-0.673284,-0.428212,-0.602763},{-0.563717,-0.692920,-0.449538}};
105 + static int icosa_tris[320][3] =
106 + { {1,42,44},{42,12,43},{44,43,14},{42,43,44},{12,45,47},{45,0,46},{47,46,13},
107 + {45,46,47},{14,48,50},{48,13,49},{50,49,2},{48,49,50},{12,47,43},{47,13,48},
108 + {43,48,14},{47,48,43},{0,45,52},{45,12,51},{52,51,16},{45,51,52},{12,42,54},
109 + {42,1,53},{54,53,15},{42,53,54},{16,55,57},{55,15,56},{57,56,4},{55,56,57},
110 + {12,54,51},{54,15,55},{51,55,16},{54,55,51},{3,58,60},{58,17,59},{60,59,19},
111 + {58,59,60},{17,61,63},{61,2,62},{63,62,18},{61,62,63},{19,64,66},{64,18,65},
112 + {66,65,6},{64,65,66},{17,63,59},{63,18,64},{59,64,19},{63,64,59},{2,61,68},
113 + {61,17,67},{68,67,21},{61,67,68},{17,58,70},{58,3,69},{70,69,20},{58,69,70},
114 + {21,71,73},{71,20,72},{73,72,8},{71,72,73},{17,70,67},{70,20,71},{67,71,21},
115 + {70,71,67},{4,74,76},{74,22,75},{76,75,24},{74,75,76},{22,77,79},{77,5,78},
116 + {79,78,23},{77,78,79},{24,80,82},{80,23,81},{82,81,7},{80,81,82},{22,79,75},
117 + {79,23,80},{75,80,24},{79,80,75},{5,77,84},{77,22,83},{84,83,26},{77,83,84},
118 + {22,74,86},{74,4,85},{86,85,25},{74,85,86},{26,87,89},{87,25,88},{89,88,9},
119 + {87,88,89},{22,86,83},{86,25,87},{83,87,26},{86,87,83},{7,90,92},{90,27,91},
120 + {92,91,29},{90,91,92},{27,93,95},{93,6,94},{95,94,28},{93,94,95},{29,96,98},
121 + {96,28,97},{98,97,0},{96,97,98},{27,95,91},{95,28,96},{91,96,29},{95,96,91},
122 + {6,93,100},{93,27,99},{100,99,31},{93,99,100},{27,90,102},{90,7,101},
123 + {102,101,30},{90,101,102},{31,103,105},{103,30,104},{105,104,10},{103,104,105},
124 + {27,102,99},{102,30,103},{99,103,31},{102,103,99},{8,106,108},{106,32,107},
125 + {108,107,34},{106,107,108},{32,109,111},{109,9,110},{111,110,33},{109,110,111},
126 + {34,112,114},{112,33,113},{114,113,1},{112,113,114},{32,111,107},{111,33,112},
127 + {107,112,34},{111,112,107},{9,109,116},{109,32,115},{116,115,36},{109,115,116},
128 + {32,106,118},{106,8,117},{118,117,35},{106,117,118},{36,119,121},{119,35,120},
129 + {121,120,11},{119,120,121},{32,118,115},{118,35,119},{115,119,36},
130 + {118,119,115},{10,122,124},{122,37,123},{124,123,39},{122,123,124},
131 + {37,125,127},{125,11,126},{127,126,38},{125,126,127},{39,128,130},
132 + {128,38,129},{130,129,3},{128,129,130},
133 + {37,127,123},{127,38,128},{123,128,39},{127,128,123},{11,125,132},{125,37,131},
134 + {132,131,41},{125,131,132},{37,122,134},{122,10,133},{134,133,40},
135 + {122,133,134},{41,135,137},{135,40,136},{137,136,5},{135,136,137},
136 + {37,134,131},{134,40,135},
137 + {131,135,41},{134,135,131},{6,65,94},{65,18,138},{94,138,28},{65,138,94},
138 + {18,62,139},{62,2,49},{139,49,13},{62,49,139},{28,140,97},{140,13,46},
139 + {97,46,0},{140,46,97},{18,139,138},{139,13,140},{138,140,28},{139,140,138},
140 + {1,44,114},
141 + {44,14,141},{114,141,34},{44,141,114},{14,50,142},{50,2,68},{142,68,21},
142 + {50,68,142},{34,143,108},{143,21,73},{108,73,8},{143,73,108},{14,142,141},
143 + {142,21,143},{141,143,34},{142,143,141},{0,52,98},{52,16,144},{98,144,29},
144 + {52,144,98},{16,57,145},{57,4,76},{145,76,24},{57,76,145},{29,146,92},
145 + {146,24,82},{92,82,7},{146,82,92},{16,145,144},{145,24,146},{144,146,29},
146 + {145,146,144},{9,88,110},{88,25,147},{110,147,33},{88,147,110},{25,85,148},
147 + {85,4,56},{148,56,15},{85,56,148},{33,149,113},{149,15,53},{113,53,1},
148 + {149,53,113},{25,148,147},{148,15,149},{147,149,33},{148,149,147},{10,124,105},
149 + {124,39,150},{105,150,31},{124,150,105},{39,130,151},{130,3,60},{151,60,19},
150 + {130,60,151},{31,152,100},{152,19,66},{100,66,6},{152,66,100},{39,151,150},
151 + {151,19,152},{150,152,31},{151,152,150},{8,72,117},{72,20,153},{117,153,35},
152 + {72,153,117},{20,69,154},{69,3,129},{154,129,38},{69,129,154},{35,155,120},
153 + {155,38,126},{120,126,11},{155,126,120},{20,154,153},{154,38,155},{153,155,35},
154 + {154,155,153},{7,81,101},{81,23,156},{101,156,30},{81,156,101},{23,78,157},
155 + {78,5,136},{157,136,40},{78,136,157},{30,158,104},{158,40,133},{104,133,10},
156 + {158,133,104},{23,157,156},{157,40,158},{156,158,30},{157,158,156},{
157 + 11,132,121},
158 + {132,41,159},{121,159,36},{132,159,121},{41,137,160},{137,5,84},{160,84,26},
159 + {137,84,160},{36,161,116},{161,26,89},{116,89,9},{161,89,116},{41,160,159},
160 + {160,26,161},{159,161,36},{160,161,159}};
161 + static int icosa_nbrs[320][3] =
162 + {{3,208,21},{12,3,20},{14,209,3},{2,0,1},{7,12,17},{202,7,16},{201,13,7},
163 + {6,4,5},{11,212,14},{198,11,13},{197,213,11},{10,8,9},{15,1,4},{9,15,6},
164 + {8,2,15},{14,12,13},{19,224,5},{28,19,4},{30,225,19},{18,16,17},{23,28,1},
165 + {250,23,0},{249,29,23},{22,20,21},{27,228,30},{246,27,29},{245,229,27},
166 + {26,24,25},{31,17,20},{25,31,22},{24,18,31},{30,28,29},{35,261,53},{44,35,52},
167 + {46,262,35},{34,32,33},{39,44,49},{197,39,48},{196,45,39},{38,36,37},
168 + {43,265,46},{193,43,45},{192,266,43},{42,40,41},{47,33,36},{41,47,38},
169 + {40,34,47},{46,44,45},{51,213,37},{60,51,36},{62,214,51},{50,48,49},{55,60,33},
170 + {277,55,32},{276,61,55},{54,52,53},{59,217,62},{273,59,61},{272,218,59},
171 + {58,56,57},{63,49,52},{57,63,54},{56,50,63},{62,60,61},{67,229,85},{76,67,84},
172 + {78,230,67},{66,64,65},{71,76,81},{293,71,80},{292,77,71},{70,68,69},
173 + {75,233,78},{289,75,77},{288,234,75},{74,72,73},{79,65,68},{73,79,70},
174 + {72,66,79},{78,76,77},{83,309,69},{92,83,68},{94,310,83},{82,80,81},{87,92,65},
175 + {245,87,64},{244,93,87},{86,84,85},{91,313,94},{241,91,93},{240,314,91},
176 + {90,88,89},{95,81,84},{89,95,86},{88,82,95},{94,92,93},{99,234,117},
177 + {108,99,116},{110,232,99},{98,96,97},{103,108,113},{192,103,112},{194,109,103},
178 + {102,100,101},{107,226,110},{200,107,109},{202,224,107},{106,104,105},
179 + {111,97,100},{105,111,102},{104,98,111},{110,108,109},{115,266,101},
180 + {124,115,100},{126,264,115},{114,112,113},{119,124,97},{288,119,96},
181 + {290,125,119},{118,116,117},{123,258,126},{296,123,125},{298,256,123},
182 + {122,120,121},{127,113,116},{121,127,118},{120,114,127},{126,124,125},
183 + {131,218,149},{140,131,148},{142,216,131},{130,128,129},{135,140,145},
184 + {240,135,144},{242,141,135},{134,132,133},{139,210,142},{248,139,141},
185 + {250,208,139},{138,136,137},{143,129,132},{137,143,134},{136,130,143},
186 + {142,140,141},{147,314,133},{156,147,132},{158,312,147},{146,144,145},
187 + {151,156,129},{272,151,128},{274,157,151},{150,148,149},{155,306,158},
188 + {280,155,157},{282,304,155},{154,152,153},{159,145,148},{153,159,150},
189 + {152,146,159},{158,156,157},{163,256,181},{172,163,180},{174,257,163},
190 + {162,160,161},{167,172,177},{282,167,176},{281,173,167},{166,164,165},
191 + {171,260,174},{278,171,173},{277,261,171},{170,168,169},{175,161,164},
192 + {169,175,166},{168,162,175},{174,172,173},{179,304,165},{188,179,164},
193 + {190,305,179},{178,176,177},{183,188,161},{298,183,160},{297,189,183},
194 + {182,180,181},{187,308,190},{294,187,189},{293,309,187},{186,184,185},
195 + {191,177,180},{185,191,182},{184,178,191},{190,188,189},{195,101,42},
196 + {204,195,41},{206,102,195},{194,192,193},{199,204,38},{10,199,37},{9,205,199},
197 + {198,196,197},{203,105,206},{6,203,205},{5,106,203},{202,200,201},
198 + {207,193,196},{201,207,198},{200,194,207},{206,204,205},{211,138,0},
199 + {220,211,2}, {222,136,211},{210,208,209},{215,220,8},{48,215,10},{50,221,215},
200 + {214,212,213},{219,130,222},
201 + {56,219,221},{58,128,219},{218,216,217},{223,209,212},{217,223,214},
202 + {216,210,223},{222,220,221},{227,106,16},{236,227,18},{238,104,227},
203 + {226,224,225},{231,236,24},{64,231,26},{66,237,231},{230,228,229},
204 + {235,98,238},
205 + {72,235,237},{74,96,235},{234,232,233},{239,225,228},{233,239,230},
206 + {232,226,239},{238,236,237},{243,133,90},{252,243,89},{254,134,243},
207 + {242,240,241},{247,252,86},{26,247,85},{25,253,247},{246,244,245},
208 + {251,137,254},
209 + {22,251,253},{21,138,251},{250,248,249},{255,241,244},{249,255,246},
210 + {248,242,255},{254,252,253},{259,122,160},{268,259,162},{270,120,259},
211 + {258,256,257},{263,268,168},{32,263,170},{34,269,263},{262,260,261},
212 + {267,114,270},{40,267,269},{42,112,267},{266,264,265},{271,257,260},
213 + {265,271,262},{264,258,271},{270,268,269},{275,149,58},{284,275,57},
214 + {286,150,275},{274,272,273},{279,284,54},{170,279,53},{169,285,279},
215 + {278,276,277},{283,153,286},{166,283,285},{165,154,283},{282,280,281},
216 + {287,273,276},{281,287,278},{280,274,287},{286,284,285},{291,117,74},
217 + {300,291,73},{302,118,291},{290,288,289},{295,300,70},{186,295,69},
218 + {185,301,295},{294,292,293},{299,121,302},{182,299,301},{181,122,299},
219 + {298,296,297},{303,289,292},{297,303,294},{296,290,303},{302,300,301},
220 + {307,154,176},{316,307,178},{318,152,307},{306,304,305},{311,316,184},
221 + {80,311,186},{82,317,311},{310,308,309},{315,146,318},{88,315,317},
222 + {90,144,315},{314,312,313},{319,305,308},{313,319,310},{312,306,319},
223 + {318,316,317}};
224 +
225 +
226   #ifdef TEST_DRIVER
24 VIEW  View = {0,{0,0,0},{0,0,-1},{0,1,0},60,60,0};
227   VIEW  Current_View = {0,{0,0,0},{0,0,-1},{0,1,0},60,60,0};
228   int Pick_cnt =0;
229 < int Pick_tri = -1,Picking = FALSE;
229 > int Pick_tri = -1,Picking = FALSE,Pick_samp=-1;
230   FVECT Pick_point[500],Pick_origin,Pick_dir;
231   FVECT  Pick_v0[500], Pick_v1[500], Pick_v2[500];
232 + int    Pick_q[500];
233   FVECT P0,P1,P2;
234   FVECT FrustumNear[4],FrustumFar[4];
235   double dev_zmin=.01,dev_zmax=1000;
236   #endif
237  
238 +
239 + char *
240 + tempbuf(len,resize)                     /* get a temporary buffer */
241 + unsigned  len;
242 + int resize;
243 + {
244 +  static char  *tempbuf = NULL;
245 +  static unsigned  tempbuflen = 0;
246 +
247 + #ifdef DEBUG
248 +        static int in_use=FALSE;
249 +
250 +        if(len == -1)
251 +          {
252 +            in_use = FALSE;
253 +            return(NULL);
254 +          }
255 +        if(!resize && in_use)
256 +        {
257 +            eputs("Buffer in use:cannot allocate:tempbuf()\n");
258 +            return(NULL);
259 +        }
260 + #endif
261 +        if (len > tempbuflen) {
262 +                if (tempbuflen > 0)
263 +                        tempbuf = realloc((void *)tempbuf, len);
264 +                else
265 +                        tempbuf = malloc(len);
266 +                tempbuflen = tempbuf==NULL ? 0 : len;
267 +        }
268 + #ifdef DEBUG
269 +        in_use = TRUE;
270 + #endif
271 +        return(tempbuf);
272 + }
273 +
274   smDir(sm,ps,id)
275     SM *sm;
276     FVECT ps;
277 <   int id;
277 >   S_ID id;
278   {
279 <    FVECT p;
280 <    
42 <    VCOPY(p,SM_NTH_WV(sm,id));
43 <    point_on_sphere(ps,p,SM_VIEW_CENTER(sm));
279 >    VSUB(ps,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm));
280 >    normalize(ps);
281   }
282  
46 smClear_mesh(sm)
47    SM *sm;
48 {
49    /* Reset the triangle counters */
50    SM_TRI_CNT(sm) = 0;
51    SM_NUM_TRIS(sm) = 0;
52    SM_FREE_TRIS(sm) = -1;
53 }
54
283   smClear_flags(sm,which)
284   SM *sm;
285   int which;
# Line 60 | Line 288 | int which;
288  
289    if(which== -1)
290      for(i=0; i < T_FLAGS;i++)
291 <      bzero(SM_NTH_FLAGS(sm,i),T_TOTAL_FLAG_BYTES(SM_MAX_TRIS(sm)));
291 >      memset(SM_NTH_FLAGS(sm,i), '\0', FLAG_BYTES(SM_MAX_TRIS(sm)));
292    else
293 <    bzero(SM_NTH_FLAGS(sm,which),T_TOTAL_FLAG_BYTES(SM_MAX_TRIS(sm)));
293 >    memset(SM_NTH_FLAGS(sm,which), '\0', FLAG_BYTES(SM_MAX_TRIS(sm)));
294   }
295  
296 < smClear_locator(sm)
297 < SM *sm;
296 > /* Given an allocated mesh- initialize */
297 > smInit_mesh(sm)
298 >    SM *sm;
299   {
300 <  STREE  *st;
301 <  
302 <  st = SM_LOCATOR(sm);
303 <
75 <  stClear(st);
300 >    /* Reset the triangle counters */
301 >    SM_NUM_TRI(sm) = 0;
302 >    SM_FREE_TRIS(sm) = -1;
303 >    smClear_flags(sm,-1);
304   }
305  
78 smInit_locator(sm,center,base)
79 SM *sm;
80 FVECT  center,base[4];
81 {
82  STREE  *st;
83  
84  st = SM_LOCATOR(sm);
85
86  stInit(st,center,base);
306  
307 < }
308 <
307 > /* Clear the SM for reuse: free any extra allocated memory:does initialization
308 >   as well
309 > */
310   smClear(sm)
311   SM *sm;
312   {
313 <  smClear_samples(sm);
314 <  smClear_mesh(sm);
315 <  smClear_locator(sm);
313 >  smDist_sum = 0;
314 >  smInit_samples(sm);
315 >  smInit_locator(sm);
316 >  smInit_mesh(sm);
317   }
318  
319 + /* Allocate and initialize a new mesh with max_verts and max_tris */
320   int
321 < smAlloc_tris(sm,max_verts,max_tris)
321 > smAlloc_mesh(sm,max_verts,max_tris)
322   SM *sm;
323   int max_verts,max_tris;
324   {
325 <    int i,nbytes,vbytes,fbytes;
325 >    int fbytes,i;
326  
327 <    vbytes = max_verts*sizeof(VERT);
106 <    fbytes = T_TOTAL_FLAG_BYTES(max_tris);
107 <    nbytes = vbytes + max_tris*sizeof(TRI) +T_FLAGS*fbytes + 8;
108 <    for(i = 1024; nbytes > i; i <<= 1)
109 <                ;
110 <    /* check if casting works correctly */
111 <    max_tris = (i-vbytes-8)/(sizeof(TRI) + T_FLAG_BYTES);
112 <    fbytes = T_TOTAL_FLAG_BYTES(max_tris);
113 <    
114 <    SM_BASE(sm)=(char *)malloc(vbytes+max_tris*sizeof(TRI)+T_FLAGS*fbytes);
327 >    fbytes = FLAG_BYTES(max_tris);
328  
329 <    if (SM_BASE(sm) == NULL)
330 <       return(0);
329 >    if(!(SM_TRIS(sm) = (TRI *)malloc(max_tris*sizeof(TRI))))
330 >      goto memerr;
331  
332 <    SM_TRIS(sm) = (TRI *)SM_BASE(sm);
333 <    SM_VERTS(sm) = (VERT *)(SM_TRIS(sm) + max_tris);
332 >    for(i=0; i< T_FLAGS; i++)
333 >      if(!(SM_NTH_FLAGS(sm,i)=(int32 *)malloc(fbytes)))
334 >        goto memerr;
335  
122    SM_NTH_FLAGS(sm,0) = (int4 *)(SM_VERTS(sm) + max_verts);
123    for(i=1; i < T_FLAGS; i++)
124       SM_NTH_FLAGS(sm,i) = (int4 *)(SM_NTH_FLAGS(sm,i-1)+fbytes/sizeof(int4));
125    
336      SM_MAX_VERTS(sm) = max_verts;
337      SM_MAX_TRIS(sm) = max_tris;
338  
339 <    smClear_mesh(sm);
339 >    smInit_mesh(sm);
340  
341      return(max_tris);
342 + memerr:
343 +        error(SYSTEM, "out of memory in smAlloc_mesh()");
344   }
345  
346  
347 <
347 > /*
348 > * smAlloc_tri(sm) : Allocate a new mesh triangle
349 > * SM *sm;                    : mesh
350 > *
351 > *  Returns ptr to next available tri
352 > */
353   int
354 < smAlloc_locator(sm)
354 > smAlloc_tri(sm)
355   SM *sm;
356   {
357 <  STREE  *st;
358 <  
359 <  st = SM_LOCATOR(sm);
360 <
361 <  st = stAlloc(st);
362 <
363 <  if(st)
364 <    return(TRUE);
365 <  else
366 <    return(FALSE);
357 >  int id;
358 >
359 >  /* First check if there are any tris on the free list */
360 >  /* Otherwise, have we reached the end of the list yet?*/
361 >  if(SM_NUM_TRI(sm) < SM_MAX_TRIS(sm))
362 >    return(SM_NUM_TRI(sm)++);
363 >  if((id = SM_FREE_TRIS(sm)) != -1)
364 >  {
365 >    SM_FREE_TRIS(sm) =  T_NEXT_FREE(SM_NTH_TRI(sm,id));
366 >    return(id);
367 >  }
368 >
369 >  error(CONSISTENCY,"smAlloc_tri: no more available triangles\n");
370 >  return(INVALID);
371   }
372  
373 < /* Initialize/clear global smL sample list for at least n samples */
373 >
374 > smFree_mesh(sm)
375 > SM *sm;
376 > {
377 >  int i;
378 >
379 >  if(SM_TRIS(sm))
380 >    free(SM_TRIS(sm));
381 >  for(i=0; i< T_FLAGS; i++)
382 >    if(SM_NTH_FLAGS(sm,i))
383 >      free(SM_NTH_FLAGS(sm,i));
384 > }
385 >
386 >
387 > /*
388 > * smAlloc(max_samples) : Initialize/clear global sample list for at least
389 > *                       max_samples
390 > * int max_samples;    
391 > *
392 > */
393   smAlloc(max_samples)
394     register int max_samples;
395   {
396    unsigned nbytes;
397    register unsigned i;
398    int total_points;
399 <  int max_tris;
399 >  int max_tris,n;
400  
401 +  n = max_samples;
402    /* If this is the first call, allocate sample,vertex and triangle lists */
403    if(!smMesh)
404    {
405      if(!(smMesh = (SM *)malloc(sizeof(SM))))
406 <       error(SYSTEM,"smAlloc():Unable to allocate memory");
407 <    bzero(smMesh,sizeof(SM));
406 >       error(SYSTEM,"smAlloc():Unable to allocate memory\n");
407 >    memset(smMesh, '\0', sizeof(SM));
408    }
409    else
410    {   /* If existing structure: first deallocate */
411 <    if(SM_BASE(smMesh))
412 <      free(SM_BASE(smMesh));
413 <    if(SM_SAMP_BASE(smMesh))
414 <       free(SM_SAMP_BASE(smMesh));
174 <  }
411 >    smFree_mesh(smMesh);
412 >    smFree_samples(smMesh);
413 >    smFree_locator(smMesh);
414 > }
415  
416    /* First allocate at least n samples + extra points:at least enough
417     necessary to form the BASE MESH- Default = 4;
418    */
419 <  max_samples = smAlloc_samples(smMesh, max_samples,SM_EXTRA_POINTS);
419 >  SM_SAMP(smMesh) = sAlloc(&n,SM_BASE_POINTS);
420  
421 <  total_points = max_samples + SM_EXTRA_POINTS;
182 <  max_tris = total_points*2;
421 >  total_points = n + SM_BASE_POINTS;
422  
423 +  /* Need enough tris for base mesh, + 2 for each sample, plus extra
424 +     since triangles are not deleted until added and edge flips (max 4)
425 +  */
426 +  max_tris = n*2 + SM_BASE_TRIS + 10;
427    /* Now allocate space for mesh vertices and triangles */
428 <  max_tris = smAlloc_tris(smMesh, total_points, max_tris);
428 >  max_tris = smAlloc_mesh(smMesh, total_points, max_tris);
429  
430    /* Initialize the structure for point,triangle location.
431     */
432    smAlloc_locator(smMesh);
190
433   }
434  
435  
436  
437 < smInit_mesh(sm,vp)
437 > smInit_sm(sm,vp)
438   SM *sm;
439   FVECT vp;
440   {
441 <
442 <  /* NOTE: Should be elsewhere?*/
201 <  smDist_sum = 0;
202 <  smNew_tri_cnt = 0;
203 <
204 <  VCOPY(SM_VIEW_CENTER(smMesh),vp);
205 <  smClear_locator(sm);
206 <  smInit_locator(sm,vp,0);
207 <  smClear_aux_samples(sm);
208 <  smClear_mesh(sm);  
441 >  VCOPY(SM_VIEW_CENTER(sm),vp);
442 >  smClear(sm);
443    smCreate_base_mesh(sm,SM_DEFAULT);
444   }
445  
# Line 219 | Line 453 | FVECT vp;
453   * If n is <= 0, then clear data structures.  Returns number samples
454   * actually allocated.
455   */
222
456   int
457   smInit(n)
458     register int n;
459   {
460    int max_vertices;
461 <
229 <  sleep(10);
230 <  
461 >  sleep(5);
462    /* If n <=0, Just clear the existing structures */
463    if(n <= 0)
464    {
465 + #ifdef DEBUG
466 +  fprintf(stderr,"Tcnt=%d Wcnt = %d, avg = %f\n",Tcnt,Wcnt,(float)Wcnt/Tcnt);
467 + #endif
468      smClear(smMesh);
469      return(0);
470    }
# Line 238 | Line 472 | smInit(n)
472    /* Total mesh vertices includes the sample points and the extra vertices
473       to form the base mesh
474    */
475 <  max_vertices = n + SM_EXTRA_POINTS;
475 >  max_vertices = n + SM_BASE_POINTS;
476  
477    /* If the current mesh contains enough room, clear and return */
478 <  if(smMesh && max_vertices <= SM_MAX_VERTS(smMesh))
478 >  if(smMesh && (max_vertices <= SM_MAX_VERTS(smMesh)) && SM_MAX_SAMP(smMesh) <=
479 >     n && SM_MAX_POINTS(smMesh) <= max_vertices)
480    {
481      smClear(smMesh);
482      return(SM_MAX_SAMP(smMesh));
# Line 251 | Line 486 | smInit(n)
486    */
487    smAlloc(n);
488  
489 + #ifdef DEBUG
490 +  fprintf(stderr,"smInit: allocating room for %d samples\n",
491 +          SM_MAX_SAMP(smMesh));
492 + #endif
493    return(SM_MAX_SAMP(smMesh));
494   }
495  
496  
497 < int
498 < smLocator_apply_func(sm,v0,v1,v2,func,arg)
499 < SM *sm;
500 < FVECT v0,v1,v2;
501 < int (*func)();
263 < char *arg;
497 > smLocator_apply(sm,v0,v1,v2,func,n)
498 >   SM *sm;
499 >   FVECT v0,v1,v2;
500 >   FUNC func;
501 >   int n;
502   {
503    STREE *st;
504 <  char found;
267 <  FVECT p0,p1,p2;
504 >  FVECT tri[3];
505  
506    st = SM_LOCATOR(sm);
507  
508 <  point_on_sphere(p0,v0,SM_VIEW_CENTER(sm));
509 <  point_on_sphere(p1,v1,SM_VIEW_CENTER(sm));
510 <  point_on_sphere(p2,v2,SM_VIEW_CENTER(sm));
508 >  VSUB(tri[0],v0,SM_VIEW_CENTER(sm));
509 >  VSUB(tri[1],v1,SM_VIEW_CENTER(sm));
510 >  VSUB(tri[2],v2,SM_VIEW_CENTER(sm));
511 >  stVisit(st,tri,func,n);
512  
275  found = stApply_to_tri_cells(st,p0,p1,p2,func,arg);
276
277  return(found);
513   }
514  
515 <
516 < int
517 < smLocator_add_tri(sm,t_id,v0_id,v1_id,v2_id)
518 < SM *sm;
519 < int t_id;
520 < int v0_id,v1_id,v2_id;  
515 > /*
516 > * QUADTREE
517 > * insert_samp(argptr,root,qt,parent,q0,q1,q2,bc,scale,rev,f,n,doneptr)
518 > *     Callback function called from quadtree traversal when leaf is reached
519 > *   int *argptr;                 :ptr to sample id number
520 > *   int root;                    :quadtree root from which traversal started
521 > *   QUADTREE qt,parent;          :current quadtree node and its parent
522 > *   BCOORD q0[3],q1[3],q2[3],bc[3]; :barycentric coordinates of the current
523 > *                                 quadtree node (q0,q1,q2) and sample (bc)
524 > *   unsigned int scale,rev;      :scale factor relative to which level at in
525 > *                                 tree, rev indicates if traversed of child 3
526 > *   FUNC f;                      :function structure so can recurse
527 > *   int n,*doneptr;              :n indicates which level at in quadtree, and
528 > *                                 doneptr can be set to indicate whether nbr
529 > *                                 sample has been found
530 > */
531 > QUADTREE
532 > insert_samp(argptr,root,qt,parent,q0,q1,q2,bc,scale,rev,f,n,doneptr)
533 >     int *argptr;
534 >     int root;
535 >     QUADTREE qt,parent;
536 >     BCOORD q0[3],q1[3],q2[3],bc[3];
537 >     unsigned int scale,rev;
538 >     FUNC f;
539 >     int n,*doneptr;
540   {
541 <  STREE *st;
542 <  FVECT p0,p1,p2;
289 <  
290 <  st = SM_LOCATOR(sm);
541 >  S_ID s_id;
542 >  S_ID *optr;
543  
544 <  smDir(sm,p0,v0_id);
545 <  smDir(sm,p1,v1_id);
546 <  smDir(sm,p2,v2_id);
544 >  s_id = ((S_ARGS *)argptr)->s_id;
545 >  /* If the set is empty - just add */
546 >  if(QT_IS_EMPTY(qt))
547 >  {
548 >    qt = qtadduelem(qt,s_id);
549 >    SM_S_NTH_QT(smMesh,s_id) = qt;
550 >    if(((S_ARGS *)argptr)->n_id)
551 >      *doneptr = FALSE;
552 >    else
553 >      *doneptr = TRUE;
554 >    return(qt);
555 >  }
556 >  /* If the set size is below expansion threshold,or at maximum
557 >     number of quadtree levels : just add */
558 >  optr = qtqueryset(qt);
559 >  if(QT_SET_CNT(optr) < QT_SET_THRESHOLD || (n > (QT_MAX_LEVELS-2)))
560 >  {
561 >    qt = qtadduelem(qt,s_id);
562 >    
563 >    SM_S_NTH_QT(smMesh,s_id) = qt;
564 >    if(((S_ARGS *)argptr)->n_id)
565 >      if(QT_SET_CNT(qtqueryset(qt)) > 1)
566 >      {
567 >        ((S_ARGS *)argptr)->n_id = qtqueryset(qt)[1];
568 >        *doneptr = TRUE;
569 >      }
570 >      else
571 >        *doneptr = FALSE;
572 >    else
573 >      *doneptr = TRUE;
574 >    return(qt);
575 >  }
576 >  /* otherwise: expand node- and insert sample, and reinsert existing samples
577 >     in set to children of new node
578 >  */
579 >  {
580 >      OBJECT *sptr,s_set[QT_MAXSET+1];
581 >      FUNC sfunc;
582 >      S_ARGS args;
583 >      FVECT p;
584 >      BCOORD bp[3];
585 >      int i;
586 >      
587 >      if(QT_SET_CNT(optr) > QT_MAXSET)
588 >      {
589 >          if(!(sptr = (OBJECT *)malloc((QT_SET_CNT(optr)+1)*sizeof(OBJECT))))
590 >             goto memerr;
591 >      }
592 >      else
593 >         sptr = s_set;
594  
595 <  stAdd_tri(st,t_id,p0,p1,p2);
595 >      qtgetset(sptr,qt);
596 >      
597 >      /* subdivide node */
598 >      qtfreeleaf(qt);
599 >      qtSubdivide(qt);
600 >      
601 >      /* Now add in all of the rest; */
602 >      F_FUNC(sfunc) = F_FUNC(f);
603 >      F_ARGS(sfunc) = (int *) (&args);
604 >      args.n_id = 0;
605 >      for(optr = sptr,i=QT_SET_CNT(sptr); i > 0; i--)
606 >      {
607 >          s_id = QT_SET_NEXT_ELEM(optr);
608 >          args.s_id = s_id;
609 >          VSUB(p,SM_NTH_WV(smMesh,s_id),SM_VIEW_CENTER(smMesh));
610 >          normalize(p);
611 >          vert_to_qt_frame(i,p,bp);    
612 >          if(rev)
613 >             qt= qtInsert_point_rev(root,qt,parent,q0,q1,q2,bp,
614 >                                    scale,sfunc,n,doneptr);
615 >          else
616 >             qt= qtInsert_point(root,qt,parent,q0,q1,q2,bp,
617 >                                scale,sfunc,n,doneptr);
618 >      }
619 >      /* Add current sample: have all of the information */
620 >      if(rev)
621 >         qt =qtInsert_point_rev(root,qt,parent,q0,q1,q2,bc,scale,f,n,doneptr);
622 >      else
623 >         qt = qtInsert_point(root,qt,parent,q0,q1,q2,bc,scale,f,n,doneptr);
624 >      
625 >      /* If we allocated memory: free it */
626  
627 <  return(1);
627 >      if( sptr != s_set)
628 >         free(sptr);
629 >
630 >      return(qt);
631 >  }
632 > memerr:
633 >    error(SYSTEM,"expand_node():Unable to allocate memory");
634 >
635   }
636  
637 < /* Add a triangle to the base array with vertices v1-v2-v3 */
637 >
638 > /*
639 > * int
640 > * smAdd_tri(sm,v0_id,v1_id,v2_id,tptr)
641 > *             : Add a triangle to the base array with vertices v0-v1-v2,
642 > *               returns ptr to triangle in tptr
643 > * SM *sm;                   : mesh
644 > * S_ID v0_id,v1_id,v2_id;    : sample ids of triangle vertices
645 > * TRI **tptr;               : ptr to set to triangle
646 > *
647 > *  Allocates and initializes mesh triangle with vertices specified.
648 > */
649   int
650   smAdd_tri(sm, v0_id,v1_id,v2_id,tptr)
651   SM *sm;
652 < int v0_id,v1_id,v2_id;
652 > S_ID v0_id,v1_id,v2_id;
653   TRI **tptr;
654   {
655      int t_id;
656      TRI *t;
657  
658 + #ifdef DEBUG
659 +    if(v0_id==v1_id || v0_id==v2_id || v1_id==v2_id)
660 +      error(CONSISTENCY,"smAdd_tri: invalid vertex ids\n");
661  
662 <    if(SM_TRI_CNT(sm)+1 > SM_MAX_TRIS(sm))
663 <      error(SYSTEM,"smAdd_tri():Too many triangles");
662 > #endif
663 >    t_id = smAlloc_tri(sm);  
664 > #ifdef DEBUG
665 > #if DEBUG > 1
666 >    {
667 >      double v0[3],v1[3],v2[3],n[3];
668 >      double area,dp;
669 >      double ab[3],ac[3];
670 >      VSUB(v0,SM_NTH_WV(sm,v0_id),SM_VIEW_CENTER(sm));
671 >      VSUB(v1,SM_NTH_WV(sm,v1_id),SM_VIEW_CENTER(sm));
672 >      VSUB(v2,SM_NTH_WV(sm,v2_id),SM_VIEW_CENTER(sm));
673 >      normalize(v0);
674 >      normalize(v1);
675 >      normalize(v2);
676  
677 <    /* Get the id for the next available triangle */
678 <    SM_FREE_TRI_ID(sm,t_id);
679 <    if(t_id == -1)
680 <      return(t_id);
677 >      VSUB(ab,v1,v2);
678 >      normalize(ab);
679 >      VSUB(ac,v0,v2);
680 >      normalize(ac);
681 >      VCROSS(n,ab,ac);
682 >      area = normalize(n);
683 >      if((dp=DOT(v0,n)) < 0.0)
684 >      {
685 >        eputs("backwards tri\n");
686 >      }
687 >    }
688 > #endif
689 > #endif
690  
691      t = SM_NTH_TRI(sm,t_id);
692 + #ifdef DEBUG
693      T_CLEAR_NBRS(t);
694 <
323 <    if(SM_BASE_ID(sm,v0_id) || SM_BASE_ID(sm,v1_id) || SM_BASE_ID(sm,v2_id))
324 <    {
325 <      smClear_tri_flags(sm,t_id);
326 <      SM_SET_NTH_T_BASE(sm,t_id);
327 <    }
328 <    else
329 <    {
330 <      SM_CLEAR_NTH_T_BASE(sm,t_id);
331 <      SM_SET_NTH_T_ACTIVE(sm,t_id);
332 <      SM_SET_NTH_T_LRU(sm,t_id);
333 <      SM_SET_NTH_T_NEW(sm,t_id);
334 <      SM_NUM_TRIS(sm)++;
335 <      smNew_tri_cnt++;
336 <    }
694 > #endif
695      /* set the triangle vertex ids */
696      T_NTH_V(t,0) = v0_id;
697      T_NTH_V(t,1) = v1_id;
# Line 343 | Line 701 | TRI **tptr;
701      SM_NTH_VERT(sm,v1_id) = t_id;
702      SM_NTH_VERT(sm,v2_id) = t_id;
703  
704 <    if(t)
705 <       *tptr = t;
704 >    if(SM_BASE_ID(sm,v0_id) || SM_BASE_ID(sm,v1_id) || SM_BASE_ID(sm,v2_id))
705 >      SM_SET_NTH_T_BASE(sm,t_id);
706 >    else
707 >      SM_CLR_NTH_T_BASE(sm,t_id);
708 >    if(SM_DIR_ID(sm,v0_id) || SM_DIR_ID(sm,v1_id) || SM_DIR_ID(sm,v2_id))
709 >      SM_SET_NTH_T_BG(sm,t_id);
710 >    else
711 >      SM_CLR_NTH_T_BG(sm,t_id);
712 >    S_SET_FLAG(T_NTH_V(t,0));
713 >    S_SET_FLAG(T_NTH_V(t,1));
714 >    S_SET_FLAG(T_NTH_V(t,2));
715 >
716 >    SM_SET_NTH_T_ACTIVE(sm,t_id);
717 >    SM_SET_NTH_T_NEW(sm,t_id);
718 >
719 >    *tptr = t;
720      /* return initialized triangle */
721      return(t_id);
722   }
723  
724 < int
725 < smClosest_vertex_in_tri(sm,v0_id,v1_id,v2_id,p,eps)
724 >
725 >
726 > smRestore_Delaunay(sm,a,b,c,t,t_id,a_id,b_id,c_id)
727   SM *sm;
728 < int v0_id,v1_id,v2_id;
729 < FVECT p;
730 < double eps;
728 > FVECT a,b,c;
729 > TRI *t;
730 > int t_id,a_id,b_id,c_id;
731   {
732 <    FVECT v;
733 <    double d,d0,d1,d2;
734 <    int closest = -1;
732 >  int e1,topp_id;
733 >  S_ID p_id;
734 >  TRI *topp;
735 >  FVECT p;
736  
737 <    if(v0_id != -1)
738 <    {
739 <      smDir(sm,v,v0_id);
740 <      d0 = DIST(p,v);
741 <      if(eps < 0 || d0 < eps)
742 <      {
369 <        closest = v0_id;
370 <        d = d0;
371 <      }
372 <    }
373 <    if(v1_id != -1)
374 <    {
375 <      smDir(sm,v,v1_id);
376 <      d1 = DIST(p,v);
377 <      if(closest== -1)
378 <      {
379 <          if(eps < 0 || d1 < eps)
380 <           {
381 <               closest = v1_id;
382 <               d = d1;
383 <           }
384 <      }
385 <      else
386 <        if(d1 < d2)
387 <        {
388 <          if((eps < 0) ||  d1 < eps)
389 <          {
390 <            closest = v1_id;
391 <            d = d1;
392 <          }
393 <        }
394 <      else
395 <         if((eps < 0) ||  d2 < eps)
396 <          {
397 <            closest = v2_id;
398 <            d = d2;
399 <          }
737 >  topp_id = T_NTH_NBR(t,0);
738 > #ifdef DEBUG
739 >  if(topp_id==INVALID)
740 >  {
741 >    eputs("Invalid tri id smRestore_delaunay()\n");
742 >    return;
743    }
744 <    if(v2_id != -1)
745 <    {
746 <      smDir(sm,v,v2_id);
747 <      d2 = DIST(p,v);
748 <      if((eps < 0) ||  d2 < eps)
749 <         if(closest== -1 ||(d2 < d))
750 <             return(v2_id);
751 <    }
752 <    return(closest);
744 > #endif
745 >  topp = SM_NTH_TRI(sm,topp_id);
746 > #ifdef DEBUG
747 >  if(!T_IS_VALID(topp))
748 >  {
749 >    eputs("Invalid tri smRestore_delaunay()\n");
750 >    return;
751 >  }
752 > #endif
753 >  e1 = T_NTH_NBR_PTR(t_id,topp);
754 >  p_id = T_NTH_V(topp,e1);
755 >
756 >  VSUB(p,SM_NTH_WV(sm,p_id),SM_VIEW_CENTER(sm));
757 >  normalize(p);
758 >  if(pt_in_cone(p,c,b,a))
759 >  {
760 >    int e1next,e1prev;
761 >    int ta_id,tb_id;
762 >    TRI *ta,*tb,*n;
763 >    e1next = (e1 + 1)%3;
764 >    e1prev = (e1 + 2)%3;
765 >    ta_id = smAdd_tri(sm,a_id,b_id,p_id,&ta);
766 >    tb_id = smAdd_tri(sm,a_id,p_id,c_id,&tb);
767 >
768 >    T_NTH_NBR(ta,0) = T_NTH_NBR(topp,e1next);
769 >    T_NTH_NBR(ta,1) = tb_id;
770 >    T_NTH_NBR(ta,2) = T_NTH_NBR(t,2);
771 >  
772 >    T_NTH_NBR(tb,0) = T_NTH_NBR(topp,e1prev);
773 >    T_NTH_NBR(tb,1) = T_NTH_NBR(t,1);
774 >    T_NTH_NBR(tb,2) = ta_id;
775 >  
776 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t,1));
777 >    T_NTH_NBR(n,T_NTH_NBR_PTR(t_id,n)) = tb_id;
778 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t,2));
779 >    T_NTH_NBR(n,T_NTH_NBR_PTR(t_id,n)) = ta_id;
780 >    n = SM_NTH_TRI(sm,T_NTH_NBR(topp,e1next));
781 >    T_NTH_NBR(n,T_NTH_NBR_PTR(topp_id,n)) = ta_id;
782 >    n = SM_NTH_TRI(sm,T_NTH_NBR(topp,e1prev));
783 >    T_NTH_NBR(n,T_NTH_NBR_PTR(topp_id,n)) = tb_id;
784 >    
785 >    smDelete_tri(sm,t_id,t);
786 >    smDelete_tri(sm,topp_id,topp);
787 >
788 > #ifdef DEBUG
789 > #if DEBUG > 1
790 >    if(T_NTH_NBR(ta,0) == T_NTH_NBR(ta,1)  ||
791 >       T_NTH_NBR(ta,1) == T_NTH_NBR(ta,2)  ||
792 >       T_NTH_NBR(ta,0) == T_NTH_NBR(ta,2))
793 >      error(CONSISTENCY,"Invalid topology\n");
794 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(ta,0))) ||
795 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(ta,1))) ||
796 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(ta,2))))
797 >      error(CONSISTENCY,"Invalid topology\n");
798 >    n = SM_NTH_TRI(sm,T_NTH_NBR(ta,0));
799 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
800 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
801 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
802 >      error(CONSISTENCY,"Invalid topology\n");
803 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
804 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
805 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
806 >      error(CONSISTENCY,"Invalid topology\n");
807 >    n = SM_NTH_TRI(sm,T_NTH_NBR(ta,1));
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,2));
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(tb,0));
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,1));
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,2));
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 >
853 >    if(T_NTH_NBR(tb,0) == T_NTH_NBR(tb,1)  ||
854 >       T_NTH_NBR(tb,1) == T_NTH_NBR(tb,2)  ||
855 >       T_NTH_NBR(tb,0) == T_NTH_NBR(tb,2))
856 >      error(CONSISTENCY,"Invalid topology\n");
857 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,0))) ||
858 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,1))) ||
859 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,2))))
860 >      error(CONSISTENCY,"Invalid topology\n");
861 >
862 > #endif  
863 > #endif  
864 >    smRestore_Delaunay(sm,a,b,p,ta,ta_id,a_id,b_id,p_id);
865 >    smRestore_Delaunay(sm,a,p,c,tb,tb_id,a_id,p_id,c_id);
866 >  }
867   }
868  
869  
870 + /* Give the vertex "id" and a triangle "t" that it belongs to- return the
871 +   next nbr in a counter clockwise order about vertex "id"
872 + */
873   int
874 < smClosest_vertex_in_w_tri(sm,v0_id,v1_id,v2_id,p)
874 > smTri_next_ccw_nbr(sm,t,id)
875   SM *sm;
876 < int v0_id,v1_id,v2_id;
877 < FVECT p;
876 > TRI *t;
877 > S_ID id;
878   {
879 <    FVECT v;
880 <    double d,d0,d1,d2;
881 <    int closest;
879 >  int which;
880 >  int nbr_id;
881 >  
882 >  /* Want the edge for which "id" is the destination */
883 >  which = T_WHICH_V(t,id);
884 >  if(which== INVALID)
885 >    return(which);
886  
887 <    VCOPY(v,SM_NTH_WV(sm,v0_id));
888 <    d = d0 = DIST(p,v);
425 <    closest = v0_id;
426 <    
427 <    VCOPY(v,SM_NTH_WV(sm,v1_id));
428 <    d1 = DIST(p,v);
429 <    if(d1 < d2)
430 <    {
431 <      closest = v1_id;
432 <      d = d1;
433 <    }
434 <    VCOPY(v,SM_NTH_WV(sm,v2_id));
435 <    d2 = DIST(p,v);
436 <    if(d2 < d)
437 <      return(v2_id);
438 <    else
439 <      return(closest);
887 >  nbr_id = T_NTH_NBR(t,(which + 1)% 3);
888 >  return(nbr_id);
889   }
890  
891 < void
892 < smTris_swap_edge(sm,t_id,t1_id,e,e1,tn_id,tn1_id,add,del)
891 > smClear_tri_flags(sm,id)
892 > SM *sm;
893 > int id;
894 > {
895 >  int i;
896 >
897 >  for(i=0; i < T_FLAGS; i++)
898 >    SM_CLR_NTH_T_FLAG(sm,id,i);
899 >
900 > }
901 >
902 > /* Locate the point-id in the point location structure: */
903 > int
904 > smInsert_samp_mesh(sm,s_id,tri_id,a,b,c,d,on,which)
905     SM *sm;
906 <   int t_id,t1_id;
907 <   int e,e1;
908 <   int **tn_id,**tn1_id;
909 <   LIST **add,**del;
906 >   S_ID s_id;
907 >   int tri_id;
908 >   FVECT a,b,c,d;
909 >   int on,which;
910 > {
911 >    S_ID v_id[3],opp_id;
912 >    int topp_id,i;
913 >    int t0_id,t1_id,t2_id,t3_id;
914 >    int e0,e1,e2,opp0,opp1,opp2;
915 >    TRI *tri,*nbr,*topp,*t0,*t1,*t2,*t3;
916 >    FVECT e;
917  
918 +    for(i=0; i<3;i++)
919 +      v_id[i] = T_NTH_V(SM_NTH_TRI(sm,tri_id),i);
920 +
921 +    /* If falls on existing edge */
922 +    if(on == ON_E)
923 +    {
924 +      FVECT n,vopp;
925 +      double dp;
926 +
927 +      tri = SM_NTH_TRI(sm,tri_id);
928 +      topp_id = T_NTH_NBR(tri,which);
929 +      e0 = which;
930 +      e1 = (which+1)%3;
931 +      e2 = (which+2)%3;
932 +      topp = SM_NTH_TRI(sm,topp_id);
933 +      opp0 = T_NTH_NBR_PTR(tri_id,topp);
934 +      opp1 = (opp0+1)%3;
935 +      opp2 = (opp0+2)%3;
936 +
937 +      opp_id = T_NTH_V(topp,opp0);
938 +      
939 +      /* Create 4 triangles */
940 +      /*      /|\             /|\
941 +             / | \           / | \
942 +            /  *  \  ---->  /__|__\
943 +            \  |  /         \  |  /
944 +             \ | /           \ | /
945 +              \|/             \|/
946 +     */
947 +      t0_id = smAdd_tri(sm,s_id,v_id[e0],v_id[e1],&t0);
948 +      t1_id = smAdd_tri(sm,s_id,v_id[e2],v_id[e0],&t1);
949 +      t2_id = smAdd_tri(sm,s_id,v_id[e1],opp_id,&t2);
950 +      t3_id = smAdd_tri(sm,s_id,opp_id,v_id[e2],&t3);
951 +
952 +      /* Set the neighbor pointers for the new tris */
953 +      T_NTH_NBR(t0,0) = T_NTH_NBR(tri,e2);
954 +      T_NTH_NBR(t0,1) = t2_id;
955 +      T_NTH_NBR(t0,2) = t1_id;
956 +      T_NTH_NBR(t1,0) = T_NTH_NBR(tri,e1);
957 +      T_NTH_NBR(t1,1) = t0_id;
958 +      T_NTH_NBR(t1,2) = t3_id;
959 +      T_NTH_NBR(t2,0) = T_NTH_NBR(topp,opp1);
960 +      T_NTH_NBR(t2,1) = t3_id;
961 +      T_NTH_NBR(t2,2) = t0_id;
962 +      T_NTH_NBR(t3,0) = T_NTH_NBR(topp,opp2);
963 +      T_NTH_NBR(t3,1) = t1_id;
964 +      T_NTH_NBR(t3,2) = t2_id;
965 +
966 +        /* Reset the neigbor pointers for the neighbors of the original */
967 +        nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,e1));
968 +        T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t1_id;
969 +        nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,e2));
970 +        T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t0_id;
971 +        nbr = SM_NTH_TRI(sm,T_NTH_NBR(topp,opp1));
972 +        T_NTH_NBR(nbr,T_NTH_NBR_PTR(topp_id,nbr)) = t2_id;
973 +        nbr = SM_NTH_TRI(sm,T_NTH_NBR(topp,opp2));
974 +        T_NTH_NBR(nbr,T_NTH_NBR_PTR(topp_id,nbr)) = t3_id;
975 +
976 + #ifdef DEBUG
977 + #if DEBUG > 1
978   {
979 <    TRI *t,*t1;
452 <    TRI *ta,*tb;
453 <    int verts[3],enext,eprev,e1next,e1prev;
454 <    TRI *n;
455 <    FVECT p1,p2,p3;
456 <    int ta_id,tb_id;
457 <    /* swap diagonal (e relative to t, and e1 relative to t1)
458 <      defined by quadrilateral
459 <      formed by t,t1- swap for the opposite diagonal
460 <   */
461 <    t = SM_NTH_TRI(sm,t_id);
462 <    t1 = SM_NTH_TRI(sm,t1_id);
463 <    enext = (e+1)%3;
464 <    eprev = (e+2)%3;
465 <    e1next = (e1+1)%3;
466 <    e1prev = (e1+2)%3;
467 <    verts[e] = T_NTH_V(t,e);
468 <    verts[enext] = T_NTH_V(t1,e1prev);
469 <    verts[eprev] = T_NTH_V(t,eprev);
470 <    ta_id = smAdd_tri(sm,verts[0],verts[1],verts[2],&ta);
471 <    *add = push_data(*add,ta_id);
979 >   TRI *n;
980  
981 <    verts[e1] = T_NTH_V(t1,e1);
982 <    verts[e1next] = T_NTH_V(t,eprev);
983 <    verts[e1prev] = T_NTH_V(t1,e1prev);
984 <    tb_id = smAdd_tri(sm,verts[0],verts[1],verts[2],&tb);
985 <    *add = push_data(*add,tb_id);
981 >    if(T_NTH_NBR(t0,0) == T_NTH_NBR(t0,1)  ||
982 >       T_NTH_NBR(t0,1) == T_NTH_NBR(t0,2)  ||
983 >       T_NTH_NBR(t0,0) == T_NTH_NBR(t0,2))
984 >      error(CONSISTENCY,"Invalid topology\n");
985 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t0,0))) ||
986 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t0,1))) ||
987 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t0,2))))
988 >      error(CONSISTENCY,"Invalid topology\n");
989 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t0,0));
990 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
991 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
992 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
993 >      error(CONSISTENCY,"Invalid topology\n");
994 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
995 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
996 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
997 >      error(CONSISTENCY,"Invalid topology\n");
998 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t0,1));
999 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1000 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1001 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1002 >      error(CONSISTENCY,"Invalid topology\n");
1003 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1004 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1005 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1006 >      error(CONSISTENCY,"Invalid topology\n");
1007 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t0,2));
1008 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1009 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1010 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1011 >      error(CONSISTENCY,"Invalid topology\n");
1012 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1013 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1014 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1015 >      error(CONSISTENCY,"Invalid topology\n");
1016 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t1,0));
1017 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1018 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1019 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1020 >      error(CONSISTENCY,"Invalid topology\n");
1021 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1022 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1023 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1024 >      error(CONSISTENCY,"Invalid topology\n");
1025 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t1,1));
1026 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1027 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1028 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1029 >      error(CONSISTENCY,"Invalid topology\n");
1030 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1031 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1032 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1033 >      error(CONSISTENCY,"Invalid topology\n");
1034 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t1,2));
1035 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1036 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1037 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1038 >      error(CONSISTENCY,"Invalid topology\n");
1039 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1040 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1041 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1042 >      error(CONSISTENCY,"Invalid topology\n");
1043  
1044 <    /* set the neighbors */
1045 <    T_NTH_NBR(ta,e) = T_NTH_NBR(t1,e1next);
1046 <    T_NTH_NBR(tb,e1) = T_NTH_NBR(t,enext);
1047 <    T_NTH_NBR(ta,enext) = tb_id;
1048 <    T_NTH_NBR(tb,e1next) = ta_id;
1049 <    T_NTH_NBR(ta,eprev) = T_NTH_NBR(t,eprev);
1050 <    T_NTH_NBR(tb,e1prev) = T_NTH_NBR(t1,e1prev);    
1044 >    if(T_NTH_NBR(t1,0) == T_NTH_NBR(t1,1)  ||
1045 >       T_NTH_NBR(t1,1) == T_NTH_NBR(t1,2)  ||
1046 >       T_NTH_NBR(t1,0) == T_NTH_NBR(t1,2))
1047 >      error(CONSISTENCY,"Invalid topology\n");
1048 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t1,0))) ||
1049 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t1,1))) ||
1050 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t1,2))))
1051 >      error(CONSISTENCY,"Invalid topology\n");
1052  
1053 <    /* Reset neighbor pointers of original neighbors */
1054 <    n = SM_NTH_TRI(sm,T_NTH_NBR(t,enext));
1055 <    T_NTH_NBR(n,T_NTH_NBR_PTR(t_id,n)) = tb_id;
1056 <    n = SM_NTH_TRI(sm,T_NTH_NBR(t,eprev));
1057 <    T_NTH_NBR(n,T_NTH_NBR_PTR(t_id,n)) = ta_id;
1053 >    if(T_NTH_NBR(t2,0) == T_NTH_NBR(t2,1)  ||
1054 >       T_NTH_NBR(t2,1) == T_NTH_NBR(t2,2)  ||
1055 >       T_NTH_NBR(t2,0) == T_NTH_NBR(t2,2))
1056 >      error(CONSISTENCY,"Invalid topology\n");
1057 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t2,0))) ||
1058 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t2,1))) ||
1059 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t2,2))))
1060 >      error(CONSISTENCY,"Invalid topology\n");
1061 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t2,0));
1062 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1063 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1064 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1065 >      error(CONSISTENCY,"Invalid topology\n");
1066 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1067 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1068 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1069 >      error(CONSISTENCY,"Invalid topology\n");
1070 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t2,1));
1071 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1072 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1073 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1074 >      error(CONSISTENCY,"Invalid topology\n");
1075 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1076 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1077 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1078 >      error(CONSISTENCY,"Invalid topology\n");
1079 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t2,2));
1080 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1081 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1082 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1083 >      error(CONSISTENCY,"Invalid topology\n");
1084 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1085 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1086 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1087 >      error(CONSISTENCY,"Invalid topology\n");
1088  
1089 <    n = SM_NTH_TRI(sm,T_NTH_NBR(t1,e1next));
1090 <    T_NTH_NBR(n,T_NTH_NBR_PTR(t1_id,n)) = ta_id;
1091 <    n = SM_NTH_TRI(sm,T_NTH_NBR(t1,e1prev));
1092 <    T_NTH_NBR(n,T_NTH_NBR_PTR(t1_id,n)) = tb_id;
1089 >    if(T_NTH_NBR(t3,0) == T_NTH_NBR(t3,1)  ||
1090 >       T_NTH_NBR(t3,1) == T_NTH_NBR(t3,2)  ||
1091 >       T_NTH_NBR(t3,0) == T_NTH_NBR(t3,2))
1092 >      error(CONSISTENCY,"Invalid topology\n");
1093 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t3,0))) ||
1094 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t3,1))) ||
1095 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t3,2))))
1096 >      error(CONSISTENCY,"Invalid topology\n");
1097 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t3,0));
1098 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1099 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1100 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1101 >      error(CONSISTENCY,"Invalid topology\n");
1102 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1103 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1104 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1105 >      error(CONSISTENCY,"Invalid topology\n");
1106 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t3,1));
1107 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1108 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1109 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1110 >      error(CONSISTENCY,"Invalid topology\n");
1111 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1112 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1113 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1114 >      error(CONSISTENCY,"Invalid topology\n");
1115 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t3,2));
1116 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1117 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1118 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1119 >      error(CONSISTENCY,"Invalid topology\n");
1120 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1121 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1122 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1123 >      error(CONSISTENCY,"Invalid topology\n");
1124 > }
1125 > #endif  
1126 > #endif  
1127 >        smDir(sm,e,opp_id);
1128 >        if(which == 0)
1129 >        {
1130 >          smRestore_Delaunay(sm,a,b,c,t0,t0_id,s_id,v_id[e0],v_id[e1]);
1131 >          smRestore_Delaunay(sm,a,d,b,t1,t1_id,s_id,v_id[e2],v_id[e0]);
1132 >          smRestore_Delaunay(sm,a,c,e,t2,t2_id,s_id,v_id[e1],opp_id);
1133 >          smRestore_Delaunay(sm,a,e,d,t3,t3_id,s_id,opp_id,v_id[e2]);
1134 >        }
1135 >        else
1136 >          if( which==1 )
1137 >          {
1138 >            smRestore_Delaunay(sm,a,c,d,t0,t0_id,s_id,v_id[e0],v_id[e1]);
1139 >            smRestore_Delaunay(sm,a,b,c,t1,t1_id,s_id,v_id[e2],v_id[e0]);
1140 >            smRestore_Delaunay(sm,a,d,e,t2,t2_id,s_id,v_id[e1],opp_id);
1141 >            smRestore_Delaunay(sm,a,e,b,t3,t3_id,s_id,opp_id,v_id[e2]);
1142 >          }
1143 >          else
1144 >          {
1145 >            smRestore_Delaunay(sm,a,d,b,t0,t0_id,s_id,v_id[e0],v_id[e1]);
1146 >            smRestore_Delaunay(sm,a,c,d,t1,t1_id,s_id,v_id[e2],v_id[e0]);
1147 >            smRestore_Delaunay(sm,a,b,e,t2,t2_id,s_id,v_id[e1],opp_id);
1148 >            smRestore_Delaunay(sm,a,e,c,t3,t3_id,s_id,opp_id,v_id[e2]);
1149 >          }
1150 >        smDelete_tri(sm,tri_id,tri);
1151 >        smDelete_tri(sm,topp_id,topp);
1152 >        return(TRUE);
1153 >    }
1154 > Linsert_in_tri:
1155 >    /* Create 3 triangles */
1156 >    /*      / \             /|\
1157 >           /   \           / | \
1158 >          /  *  \  ---->  /  |  \
1159 >         /       \       /  / \  \
1160 >        /         \       / /     \ \
1161 >        ___________\   //_________\\
1162 >    */
1163 >    tri = SM_NTH_TRI(sm,tri_id);
1164  
1165 <    /* Delete two parent triangles */
1166 <    *del = push_data(*del,t_id);
1167 <    if(SM_IS_NTH_T_NEW(sm,t_id))
1168 <      SM_CLEAR_NTH_T_NEW(sm,t_id);
1169 <    else
1170 <      SM_CLEAR_NTH_T_BASE(sm,t_id);
1171 <    *del = push_data(*del,t1_id);
1172 <    if(SM_IS_NTH_T_NEW(sm,t1_id))
1173 <      SM_CLEAR_NTH_T_NEW(sm,t1_id);
1174 <    else
1175 <      SM_CLEAR_NTH_T_BASE(sm,t1_id);
1176 <    *tn_id = ta_id;
1177 <    *tn1_id = tb_id;
1165 >    t0_id = smAdd_tri(sm,s_id,v_id[0],v_id[1],&t0);
1166 >    t1_id = smAdd_tri(sm,s_id,v_id[1],v_id[2],&t1);
1167 >    t2_id = smAdd_tri(sm,s_id,v_id[2],v_id[0],&t2);
1168 >
1169 >    /* Set the neighbor pointers for the new tris */
1170 >    T_NTH_NBR(t0,0) = T_NTH_NBR(tri,2);
1171 >    T_NTH_NBR(t0,1) = t1_id;
1172 >    T_NTH_NBR(t0,2) = t2_id;
1173 >    T_NTH_NBR(t1,0) = T_NTH_NBR(tri,0);
1174 >    T_NTH_NBR(t1,1) = t2_id;
1175 >    T_NTH_NBR(t1,2) = t0_id;
1176 >    T_NTH_NBR(t2,0) = T_NTH_NBR(tri,1);
1177 >    T_NTH_NBR(t2,1) = t0_id;
1178 >    T_NTH_NBR(t2,2) = t1_id;
1179 >        
1180 >    /* Reset the neigbor pointers for the neighbors of the original */
1181 >    nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,0));
1182 >    T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t1_id;
1183 >    nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,1));
1184 >    T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t2_id;
1185 >    nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,2));
1186 >    T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t0_id;
1187 > #ifdef DEBUG
1188 > #if DEBUG > 1
1189 > {
1190 >  TRI *n;
1191 >    if(T_NTH_NBR(t0,0) == T_NTH_NBR(t0,1)  ||
1192 >       T_NTH_NBR(t0,1) == T_NTH_NBR(t0,2)  ||
1193 >       T_NTH_NBR(t0,0) == T_NTH_NBR(t0,2))
1194 >      error(CONSISTENCY,"Invalid topology\n");
1195 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t0,0))) ||
1196 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t0,1))) ||
1197 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t0,2))))
1198 >      error(CONSISTENCY,"Invalid topology\n");
1199 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t0,0));
1200 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1201 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1202 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1203 >      error(CONSISTENCY,"Invalid topology\n");
1204 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1205 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1206 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1207 >      error(CONSISTENCY,"Invalid topology\n");
1208 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t0,1));
1209 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1210 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1211 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1212 >      error(CONSISTENCY,"Invalid topology\n");
1213 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1214 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1215 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1216 >      error(CONSISTENCY,"Invalid topology\n");
1217 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t0,2));
1218 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1219 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1220 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1221 >      error(CONSISTENCY,"Invalid topology\n");
1222 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1223 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1224 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1225 >      error(CONSISTENCY,"Invalid topology\n");
1226 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t1,0));
1227 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1228 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1229 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1230 >      error(CONSISTENCY,"Invalid topology\n");
1231 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1232 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1233 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1234 >      error(CONSISTENCY,"Invalid topology\n");
1235 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t1,1));
1236 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1237 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1238 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1239 >      error(CONSISTENCY,"Invalid topology\n");
1240 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1241 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1242 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1243 >      error(CONSISTENCY,"Invalid topology\n");
1244 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t1,2));
1245 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1246 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1247 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1248 >      error(CONSISTENCY,"Invalid topology\n");
1249 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1250 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1251 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1252 >      error(CONSISTENCY,"Invalid topology\n");
1253 >
1254 >    if(T_NTH_NBR(t1,0) == T_NTH_NBR(t1,1)  ||
1255 >       T_NTH_NBR(t1,1) == T_NTH_NBR(t1,2)  ||
1256 >       T_NTH_NBR(t1,0) == T_NTH_NBR(t1,2))
1257 >      error(CONSISTENCY,"Invalid topology\n");
1258 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t1,0))) ||
1259 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t1,1))) ||
1260 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t1,2))))
1261 >      error(CONSISTENCY,"Invalid topology\n");
1262 >
1263 >    if(T_NTH_NBR(t2,0) == T_NTH_NBR(t2,1)  ||
1264 >       T_NTH_NBR(t2,1) == T_NTH_NBR(t2,2)  ||
1265 >       T_NTH_NBR(t2,0) == T_NTH_NBR(t2,2))
1266 >      error(CONSISTENCY,"Invalid topology\n");
1267 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t2,0))) ||
1268 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t2,1))) ||
1269 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t2,2))))
1270 >      error(CONSISTENCY,"Invalid topology\n");
1271 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t2,0));
1272 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1273 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1274 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1275 >      error(CONSISTENCY,"Invalid topology\n");
1276 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1277 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1278 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1279 >      error(CONSISTENCY,"Invalid topology\n");
1280 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t2,1));
1281 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1282 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1283 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1284 >      error(CONSISTENCY,"Invalid topology\n");
1285 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1286 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1287 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1288 >      error(CONSISTENCY,"Invalid topology\n");
1289 >    n = SM_NTH_TRI(sm,T_NTH_NBR(t2,2));
1290 >    if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1)  ||
1291 >       T_NTH_NBR(n,1) == T_NTH_NBR(n,2)  ||
1292 >       T_NTH_NBR(n,0) == T_NTH_NBR(n,2))
1293 >      error(CONSISTENCY,"Invalid topology\n");
1294 >    if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) ||
1295 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) ||
1296 >       !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2))))
1297 >      error(CONSISTENCY,"Invalid topology\n");
1298   }
1299 + #endif
1300 + #endif
1301 +  smRestore_Delaunay(sm,a,b,c,t0,t0_id,s_id,v_id[0],v_id[1]);
1302 +  smRestore_Delaunay(sm,a,c,d,t1,t1_id,s_id,v_id[1],v_id[2]);
1303 +  smRestore_Delaunay(sm,a,d,b,t2,t2_id,s_id,v_id[2],v_id[0]);
1304 +  smDelete_tri(sm,tri_id,tri);
1305 +  return(TRUE);
1306  
1307 < smUpdate_locator(sm,add_list,del_list)
1307 > #ifdef DEBUG
1308 > Ladderror:
1309 >        error(CONSISTENCY,"Invalid tri: smInsert_samp_mesh()\n");
1310 > #endif
1311 > }    
1312 >
1313 >
1314 > int
1315 > smWalk(sm,p,t_id,t,onptr,wptr,from,on_edge,a,b)
1316   SM *sm;
1317 < LIST *add_list,*del_list;
1317 > FVECT p;
1318 > int t_id;
1319 > TRI *t;
1320 > int *onptr,*wptr;
1321 > int from;
1322 > double on_edge;
1323 > FVECT a,b;
1324   {
1325 <  int t_id;
1326 <  TRI *t;
1327 <  while(add_list)
1328 <  {
1329 <    t_id = pop_list(&add_list);
1330 <    if(!SM_IS_NTH_T_NEW(sm,t_id) && !SM_IS_NTH_T_BASE(sm,t_id))
1325 >  FVECT n,v0,v1,v2;
1326 >  TRI *tn;
1327 >  double on0,on1,on2;
1328 >  int tn_id;
1329 >
1330 > #ifdef DEBUG
1331 >  Wcnt++;
1332 >  on0 = on1 = on2 = 10;
1333 > #endif
1334 >  switch(from){
1335 >  case 0:
1336 >    on0 = on_edge;
1337 >    /* Havnt calculate v0 yet: check for equality first */
1338 >    VSUB(v0,SM_T_NTH_WV(sm,t,0),SM_VIEW_CENTER(sm));
1339 >    normalize(v0);
1340 >    if(EQUAL_VEC3(v0,p)){ *onptr = ON_V; *wptr = 0; return(t_id); }
1341 >    /* determine what side of edge v0v1 (v0a) point is on*/
1342 >    VCROSS(n,v0,a);
1343 >    normalize(n);
1344 >    on2 = DOT(n,p);
1345 >    if(on2 > 0.0)
1346 >      {
1347 >        tn_id = T_NTH_NBR(t,2);
1348 >        tn = SM_NTH_TRI(sm,tn_id);
1349 >        return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn),
1350 >                      -on2,a,v0));
1351 >      }
1352 >    else
1353 >      if(on2 >= -EDGE_EPS)
1354 >      {
1355 >        if(on0 >= -EDGE_EPS)
1356 >        {  
1357 >          /* Could either be epsilon of vertex 1*/
1358 >        /* dot(p,a) == cos angle between them. Want length of chord x to
1359 >           be <= EDGE_EPS for test. if the perpendicular bisector of pa
1360 >           is d, cos@/2 = d/1, with right triangle d^2 + (x/2)^2 = 1
1361 >           or x^2 = 4(1-cos^2@/2) = 4(1- (1 + cos@)/2) =  2 -2cos@,
1362 >            so test is if  x^2 <= VERT_EPS*VERT_EPS,
1363 >           2 - 2cos@ <= VERT_EPS*VERT_EPS, or... */
1364 >          if(DOT(p,a) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1365 >            {*onptr = ON_P; *wptr = 1;}
1366 >          else
1367 >            if(on2 > on0)
1368 >            {*onptr = ON_E; *wptr = 2;}
1369 >            else
1370 >            {*onptr = ON_E; *wptr = 0;}
1371 >          return(t_id);
1372 >        }
1373 >      }
1374 >
1375 >    VCROSS(n,b,v0);
1376 >    normalize(n);
1377 >    on1 = DOT(n,p);
1378 >    if(on1 > 0.0)
1379      {
1380 <      SM_SET_NTH_T_NEW(sm,t_id);
1381 <      smNew_tri_cnt--;
1382 <      continue;
1380 >      tn_id = T_NTH_NBR(t,1);
1381 >      tn = SM_NTH_TRI(sm,tn_id);
1382 >      return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn),
1383 >                   -on1,v0,b));
1384      }
1385 <    t = SM_NTH_TRI(sm,t_id);
1386 <    smLocator_add_tri(sm,t_id,T_NTH_V(t,0),T_NTH_V(t,1),T_NTH_V(t,2));
1387 <  }
1388 <  
1389 <  while(del_list)
1390 <  {
1391 <    t_id = pop_list(&del_list);
1392 <    if(SM_IS_NTH_T_NEW(sm,t_id))
1385 >    else
1386 >      if(on1 >= -EDGE_EPS)
1387 >      { /* Either on v0 or on edge 1 */
1388 >        if(on0 >= -EDGE_EPS)
1389 >        {
1390 >        if(DOT(p,b) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1391 >            {*onptr = ON_P; *wptr = 2;}
1392 >        else
1393 >          if(on1 > on0)
1394 >            {*onptr = ON_E; *wptr = 1;}
1395 >          else
1396 >            {*onptr = ON_E; *wptr = 0;}
1397 >          return(t_id);
1398 >        }
1399 >        if(on2 >= -EDGE_EPS)
1400 >        {
1401 >        if(DOT(p,v0) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1402 >            {*onptr = ON_P; *wptr = 0;}
1403 >        else
1404 >          if( on1 > on2)
1405 >            {*onptr = ON_E; *wptr = 1;}
1406 >          else
1407 >            {*onptr = ON_E; *wptr = 2;}
1408 >          return(t_id);
1409 >        }
1410 >        *onptr = ON_E; *wptr = 1;
1411 >        return(t_id);
1412 >      }
1413 >    else
1414 >      if(on2 >= -EDGE_EPS)
1415 >      {
1416 >        *onptr = ON_E; *wptr = 2;
1417 >        return(t_id);
1418 >      }
1419 >      if(on0 >= -EDGE_EPS)
1420 >      {
1421 >        *onptr = ON_E; *wptr = 0;
1422 >        return(t_id);
1423 >      }
1424 >    *onptr = IN_T;
1425 >    return(t_id);
1426 >  case 1:
1427 >    on1 = on_edge;
1428 >    /* Havnt calculate v1 yet: check for equality first */
1429 >    VSUB(v1,SM_T_NTH_WV(sm,t,1),SM_VIEW_CENTER(sm));
1430 >    normalize(v1);
1431 >    if(EQUAL_VEC3(v1,p)){ *onptr = ON_V; *wptr = 1; return(t_id); }
1432 >    /* determine what side of edge v0v1 (v0a) point is on*/
1433 >    VCROSS(n,b,v1);
1434 >    normalize(n);
1435 >    on2 = DOT(n,p);
1436 >    if(on2 > 0.0)
1437      {
1438 <      smDelete_tri(sm,t_id);
1439 <      continue;
1438 >      tn_id = T_NTH_NBR(t,2);
1439 >      tn = SM_NTH_TRI(sm,tn_id);
1440 >      return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn),
1441 >                   -on2,v1,b));
1442      }
1443 <    smLocator_remove_tri(sm,t_id);
1444 <    smDelete_tri(sm,t_id);
1443 >    if(on2 >= -EDGE_EPS)
1444 >    {
1445 >      if(on1 >= -EDGE_EPS)
1446 >      {
1447 >        if(DOT(p,b) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1448 >          { *onptr = ON_P; *wptr = 0;}
1449 >        else
1450 >          if(on2 > on1)
1451 >          { *onptr = ON_E; *wptr = 2;}
1452 >        else
1453 >          { *onptr = ON_E; *wptr = 1;}
1454 >         return(t_id);
1455 >      }
1456 >    }
1457 >
1458 >    VCROSS(n,v1,a);
1459 >    normalize(n);
1460 >    on0 = DOT(n,p);
1461 >    if(on0 >0.0)
1462 >    {
1463 >      tn_id = T_NTH_NBR(t,0);
1464 >      tn = SM_NTH_TRI(sm,tn_id);
1465 >      return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn),
1466 >                 -on0,a,v1));
1467 >    }
1468 >    else
1469 >    if(on0 >= -EDGE_EPS)
1470 >      { /* Either on v0 or on edge 1 */
1471 >       if(on1 >= -EDGE_EPS)
1472 >       {
1473 >        if(DOT(p,a) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1474 >           {*onptr = ON_P; *wptr = 2;}
1475 >         else
1476 >          if(on0 > on1)
1477 >          { *onptr = ON_E; *wptr = 0;}
1478 >        else
1479 >          { *onptr = ON_E; *wptr = 1;}
1480 >         return(t_id);
1481 >       }
1482 >       if(on2 >= -EDGE_EPS)
1483 >       {
1484 >       if(DOT(p,v1) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1485 >           {*onptr = ON_P; *wptr = 1;}
1486 >         else
1487 >          if(on0 > on2)
1488 >          { *onptr = ON_E; *wptr = 0;}
1489 >        else
1490 >          { *onptr = ON_E; *wptr = 2;}
1491 >         return(t_id);
1492 >       }
1493 >       *onptr = ON_E; *wptr = 0;
1494 >       return(t_id);
1495 >     }
1496 >    else
1497 >      if(on2 >= -EDGE_EPS)
1498 >      {
1499 >        *onptr = ON_E; *wptr = 2;
1500 >        return(t_id);
1501 >      }
1502 >      if(on1 >= -EDGE_EPS)
1503 >      {
1504 >        *onptr = ON_E; *wptr = 1;
1505 >        return(t_id);
1506 >      }
1507 >    *onptr = IN_T;
1508 >    return(t_id);
1509 >  case 2:
1510 >    on2 = on_edge;
1511 >    VSUB(v2,SM_T_NTH_WV(sm,t,2),SM_VIEW_CENTER(sm));
1512 >    normalize(v2);
1513 >    if(EQUAL_VEC3(v2,p)){ *onptr = ON_V; *wptr = 2; return(t_id); }
1514 >
1515 >    /* determine what side of edge v0v1 (v0a) point is on*/
1516 >    VCROSS(n,b,v2);
1517 >    normalize(n);
1518 >    on0 = DOT(n,p);
1519 >    if(on0 > 0.0)
1520 >    {
1521 >      tn_id = T_NTH_NBR(t,0);
1522 >      tn = SM_NTH_TRI(sm,tn_id);
1523 >      return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn),
1524 >                    -on0,v2,b));
1525 >    }
1526 >    else
1527 >    if(on0 >= -EDGE_EPS)
1528 >      {
1529 >        if(on2 >= - EDGE_EPS)
1530 >        {
1531 >        if(DOT(p,b) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1532 >           {*onptr = ON_P; *wptr = 1;}
1533 >         else
1534 >           if(on0 > on2)
1535 >             {*onptr = ON_E; *wptr = 0;}
1536 >           else
1537 >             {*onptr = ON_E; *wptr = 2;}
1538 >         return(t_id);
1539 >        }
1540 >      }
1541 >    VCROSS(n,v2,a);
1542 >    normalize(n);
1543 >    on1 = DOT(n,p);
1544 >    if(on1 >0.0)
1545 >    {
1546 >      tn_id = T_NTH_NBR(t,1);
1547 >      tn = SM_NTH_TRI(sm,tn_id);
1548 >      return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn),
1549 >                   -on1,a,v2));
1550 >    }
1551 >    else
1552 >    if(on1 >= -EDGE_EPS)
1553 >     { /* Either on v0 or on edge 1 */
1554 >       if(on0 >= - EDGE_EPS)
1555 >       {
1556 >        if(DOT(p,v2) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1557 >          {*onptr = ON_P;*wptr = 2;}
1558 >        else
1559 >          if(on1 > on0)
1560 >            {*onptr = ON_E;*wptr = 1;}
1561 >          else
1562 >            {*onptr = ON_E;*wptr = 0;}
1563 >         return(t_id);
1564 >       }
1565 >       if(on2 >= -EDGE_EPS)
1566 >       {
1567 >        if(DOT(p,a) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1568 >          {*onptr = ON_P;*wptr = 0;}
1569 >        else
1570 >          if(on1 > on2)
1571 >            {*onptr = ON_E;*wptr = 1;}
1572 >          else
1573 >            {*onptr = ON_E;*wptr = 2;}
1574 >         return(t_id);
1575 >       }
1576 >       *onptr = ON_E;*wptr = 1;
1577 >       return(t_id);
1578 >     }
1579 >    else
1580 >      if(on0 >= -EDGE_EPS)
1581 >      {
1582 >        *onptr = ON_E;*wptr = 0;
1583 >        return(t_id);
1584 >      }
1585 >      if(on2 >= -EDGE_EPS)
1586 >      {
1587 >        *onptr = ON_E;*wptr = 2;
1588 >        return(t_id);
1589 >      }
1590 >    *onptr = IN_T;
1591 >    return(t_id);
1592 >  default:
1593 >    /* First time called: havnt tested anything */
1594 >    /* Check against vertices */
1595 >    VSUB(v0,SM_T_NTH_WV(sm,t,0),SM_VIEW_CENTER(sm));
1596 >    normalize(v0);
1597 >    if(EQUAL_VEC3(v0,p)){ *onptr = ON_V; *wptr = 0; return(t_id); }
1598 >    VSUB(v1,SM_T_NTH_WV(sm,t,1),SM_VIEW_CENTER(sm));
1599 >    normalize(v1);
1600 >    if(EQUAL_VEC3(v1,p)){ *onptr = ON_V; *wptr = 1; return(t_id); }
1601 >    VSUB(v2,SM_T_NTH_WV(sm,t,2),SM_VIEW_CENTER(sm));
1602 >    normalize(v2);
1603 >    if(EQUAL_VEC3(v2,p)){ *onptr = ON_V; *wptr = 2; return(t_id); }
1604 >    
1605 >    VCROSS(n,v0,v1);  /* Check against v0v1, or edge 2 */
1606 >    normalize(n);
1607 >    on2 = DOT(n,p);
1608 >    if(on2 > 0.0)
1609 >    {              /* Outside edge: traverse to nbr 2 */
1610 >      tn_id = T_NTH_NBR(t,2);
1611 >      tn = SM_NTH_TRI(sm,tn_id);
1612 >      return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn),
1613 >                 -on2,v1,v0));
1614 >    }
1615 >    else
1616 >    VCROSS(n,v1,v2);  /* Check against v1v2 or edge 0 */
1617 >    normalize(n);
1618 >    on0 = DOT(n,p);
1619 >    if(on0 > 0.0)
1620 >    {                      /* Outside edge: traverse to nbr 0 */
1621 >      tn_id = T_NTH_NBR(t,0);
1622 >      tn = SM_NTH_TRI(sm,tn_id);
1623 >      return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn),
1624 >                    -on0,v2,v1));
1625 >    }
1626 >    else
1627 >      if(on0 >= -EDGE_EPS)
1628 >      {                /* On the line defining edge 0 */
1629 >      if(on2 >= -EDGE_EPS)
1630 >      {              
1631 >        if(DOT(p,v1) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1632 >          {*onptr = ON_P;*wptr = 1;}
1633 >        else
1634 >          if(on0 > on2)
1635 >          {*onptr = ON_E;*wptr = 0;}
1636 >        else
1637 >          {*onptr = ON_E;*wptr = 2;}
1638 >        return(t_id);
1639 >      }
1640 >    }
1641 >    VCROSS(n,v2,v0);  /* Check against v2v0 or edge 1 */
1642 >    normalize(n);
1643 >    on1 = DOT(n,p);
1644 >    if(on1 >0.0)
1645 >    {                            /* Outside edge: traverse to nbr 1 */
1646 >      tn_id = T_NTH_NBR(t,1);
1647 >      tn = SM_NTH_TRI(sm,tn_id);
1648 >      return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn),
1649 >                    -on1,v0,v2));
1650 >    }
1651 >    else
1652 >    if(on1  >= -EDGE_EPS)
1653 >      {               /* On the line defining edge 1 */
1654 >        if(on2 >= -EDGE_EPS)
1655 >        {              
1656 >        if(DOT(p,v0) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1657 >            {*onptr = ON_P;*wptr = 0;}
1658 >          else
1659 >            if(on1 > on2)
1660 >              {*onptr = ON_E;*wptr = 1;}
1661 >            else
1662 >              {*onptr = ON_E;*wptr = 2;}
1663 >          return(t_id);
1664 >        }
1665 >        if(on0 >= -EDGE_EPS)
1666 >        {              
1667 >        if(DOT(p,v2) >= 1.0-VERT_EPS*VERT_EPS/2.0)
1668 >            {*onptr = ON_P;*wptr = 2;}
1669 >          else
1670 >            if(on1 > on0)
1671 >              {*onptr = ON_E;*wptr = 1;}
1672 >            else
1673 >              {*onptr = ON_E;*wptr = 0;}
1674 >          return(t_id);
1675 >       }
1676 >        *onptr = ON_E; /* Only on edge 1 */
1677 >        *wptr = 1;
1678 >        return(t_id);
1679 >      }
1680 >    else
1681 >      if(on2 >= -EDGE_EPS)           /* Is on edge 2 ? */
1682 >      {
1683 >        *onptr = ON_E; *wptr = 2;
1684 >        return(t_id);
1685 >      }
1686 >    if(on0 >= -EDGE_EPS)            /* Is on edge 0 ? */
1687 >    {
1688 >      *onptr = ON_E; *wptr = 0;
1689 >      return(t_id);
1690 >    }
1691 >    *onptr = IN_T;   /* Must be interior to t */
1692 >    return(t_id);
1693    }
1694   }
544 /* MUST add check for constrained edges */
545 int
546 smFix_tris(sm,id,tlist)
547 SM *sm;
548 int id;
549 LIST *tlist;
550 {
551    TRI *t,*t_opp;
552    FVECT p,p1,p2,p3;
553    int e,e1,swapped = 0;
554    int t_id,t_opp_id;
555    LIST *add_list,*del_list;
1695  
1696 + #define check_edges(on0,on1,on2,o,w,t_id) \
1697 +   if(on0){if(on1){*o = ON_P;*w = 2;} else if(on2){*o = ON_P;*w = 1;} \
1698 +                   else {*o = ON_E; *w = 0; } return(t_id); } \
1699 +   if(on1){if(on2){*o = ON_P;*w = 0;} else {*o = ON_E;*w = 1;}return(t_id);}\
1700 +   if(on2){*o = ON_E;*w = 2;return(t_id);}
1701  
1702 <    add_list = del_list = NULL;
1703 <    VSUB(p,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm));
1704 <    while(tlist)
1705 <    {
562 <        t_id = pop_list(&tlist);
563 <        t = SM_NTH_TRI(sm,t_id);
564 <        e = (T_WHICH_V(t,id)+1)%3;
565 <        t_opp_id = T_NTH_NBR(t,e);
566 <        t_opp = SM_NTH_TRI(sm,t_opp_id);
1702 > #define  check_verts(p,v0,v1,v2,o,w,t_id) \
1703 >    if(EQUAL_VEC3(v0,p)){ *o = ON_V; *w = 0; return(t_id); } \
1704 >    if(EQUAL_VEC3(v1,p)){ *o = ON_V; *w = 1; return(t_id); } \
1705 >    if(EQUAL_VEC3(v2,p)){ *o = ON_V; *w = 2; return(t_id);}
1706  
1707 <        smDir(sm,p1,T_NTH_V(t_opp,0));
1708 <        smDir(sm,p2,T_NTH_V(t_opp,1));
1709 <        smDir(sm,p3,T_NTH_V(t_opp,2));
1710 <        if(point_in_cone(p,p1,p2,p3))
1707 >
1708 >
1709 > find_neighbor(argptr,qt,f,doneptr)
1710 > int *argptr;
1711 > QUADTREE qt;
1712 > FUNC f;
1713 > int *doneptr;
1714 > {
1715 >  S_ID s_id;
1716 >  int i;
1717 >  S_ID *optr;
1718 >  
1719 >  if(QT_IS_EMPTY(qt))
1720 >    return;
1721 >  else
1722 >    if(QT_IS_TREE(qt))
1723 >    {
1724 >      for(i=0;i < 4; i++)
1725 >      {
1726 >        find_neighbor(argptr,QT_NTH_CHILD(qt,i),f,doneptr);
1727 >        if(*doneptr)
1728 >          return;
1729 >      }
1730 >    }
1731 >    else
1732 >    {
1733 >      optr = qtqueryset(qt);
1734 >      for(i = QT_SET_CNT(optr); i > 0; i--)
1735 >      {
1736 >        s_id = QT_SET_NEXT_ELEM(optr);
1737 >        if(s_id != ((S_ARGS *)argptr)->s_id)
1738          {
1739 <            swapped = 1;
1740 <            e1 = T_NTH_NBR_PTR(t_id,t_opp);
1741 <            /* check list for t_opp and Remove if there */
576 <            remove_from_list(t_opp_id,&tlist);
577 <            smTris_swap_edge(sm,t_id,t_opp_id,e,e1,&t_id,&t_opp_id,
578 <                             &add_list,&del_list);
579 <            tlist = push_data(tlist,t_id);
580 <            tlist = push_data(tlist,t_opp_id);
1739 >          *doneptr = TRUE;
1740 >          ((S_ARGS *)argptr)->n_id = s_id;
1741 >          return;
1742          }
1743 +      }
1744      }
583    smUpdate_locator(sm,add_list,del_list);
584
585    return(swapped);
1745   }
1746  
1747 < /* Give the vertex "id" and a triangle "t" that it belongs to- return the
589 <   next nbr in a counter clockwise order about vertex "id"
590 < */
591 < int
592 < smTri_next_ccw_nbr(sm,t,id)
1747 > smInsert_samp(sm,s_id,p,nptr)
1748   SM *sm;
1749 < TRI *t;
1750 < int id;
1749 > S_ID s_id;
1750 > FVECT p;
1751 > S_ID *nptr;
1752   {
1753 <  int t_id;
1754 <  int tri;
1753 >  FVECT tpt;
1754 >  FUNC f;
1755 >  S_ARGS args;
1756  
1757 <  /* Want the edge for which "id" is the destination */
1758 <  t_id = (T_WHICH_V(t,id)+ 2)% 3;
1759 <  tri = T_NTH_NBR(t,t_id);
603 <  return(tri);
604 < }
605 <
606 < void
607 < smReplace_point(sm,tri,id,nid)
608 < SM *sm;
609 < TRI *tri;
610 < int id,nid;
611 < {
612 <  TRI *t;
613 <  int t_id;
614 <  
615 <  T_NTH_V(tri,T_WHICH_V(tri,id)) = nid;
616 <
617 <  t_id = smTri_next_ccw_nbr(sm,t,nid);
618 <  while((t= SM_NTH_TRI(sm,t_id)) != tri)
1757 >  F_FUNC(f) = insert_samp;
1758 >  args.s_id = s_id;
1759 >  if(nptr)
1760    {
1761 <      T_NTH_V(t,T_WHICH_V(t,id)) = nid;
1762 <      t_id = smTri_next_ccw_nbr(sm,t,nid);
1761 >    args.n_id = 1;
1762 >    F_FUNC2(f) = find_neighbor;
1763    }
1764 < }
1764 >  else
1765 >    args.n_id = 0;
1766 >  F_ARGS(f) = (int *)(&args);
1767 >  stInsert_samp(SM_LOCATOR(sm),p,f);
1768  
1769 +  if(nptr)
1770 +    *nptr = args.n_id;
1771 + }
1772  
1773 < smClear_tri_flags(sm,id)
1773 > /* Assumed p is normalized to view sphere */
1774 > int
1775 > smSample_locate_tri(sm,p,s_id,onptr,whichptr,nptr)
1776   SM *sm;
1777 < int id;
1777 > FVECT p;
1778 > S_ID s_id;
1779 > int *onptr,*whichptr;
1780 > S_ID *nptr;
1781   {
1782 <  int i;
1782 >  int tri_id;
1783 >  FVECT tpt;
1784 >  TRI *tri;
1785  
1786 <  for(i=0; i < T_FLAGS; i++)
1787 <    SM_CLEAR_NTH_T_FLAG(sm,id,i);
1786 >  if(SM_S_NTH_QT(sm,s_id) == EMPTY)
1787 >    smInsert_samp(sm,s_id,p,nptr);
1788 > #ifdef DEBUG
1789 >  if(*nptr == INVALID)
1790 >    error(CONSISTENCY,"smSample_locate_tri: unable to find sample\n");
1791 > #endif
1792 >  
1793 >  /* Get the triangle adjacent to a sample in qt, or if there are no other
1794 >     samples in qt than the one just inserted, look at siblings-from parent
1795 >     node
1796 >  */
1797  
1798 +  tri_id = SM_NTH_VERT(sm,*nptr);
1799 + #ifdef DEBUG
1800 +  if(tri_id == INVALID)
1801 +      error(CONSISTENCY,"smSample_locate_tri: Invalid tri_id\n");
1802 + #endif
1803 +
1804 +  tri = SM_NTH_TRI(sm,tri_id);
1805 + #ifdef DEBUG
1806 +  Tcnt++;
1807 +    if(!T_IS_VALID(tri))
1808 +      error(CONSISTENCY,"smSample_locate_tri: Invalid tri\n");
1809 + #endif
1810 +  tri_id = smWalk(sm,p,tri_id,tri,onptr,whichptr,-1,0.0,NULL,NULL);
1811 + #ifdef DEBUG
1812 +    if(tri_id == INVALID)
1813 +      error(CONSISTENCY,"smSample_locate_tri: unable to find tri on walk\n");
1814 + #endif
1815 +    return(tri_id);
1816   }
1817  
1818 < /* Locate the point-id in the point location structure: */
1819 < int
1820 < smReplace_vertex(sm,c,dir,p,tri_id,snew_id,type,which)
1821 <   SM *sm;
1822 <   COLR c;
642 <   FVECT dir,p;
643 <   int tri_id,snew_id;
644 <   char type,which;
645 < {
646 <    int n_id,s_id;
647 <    TRI *tri;
1818 > /*
1819 >   Determine whether this sample should:
1820 >   a) be added to the mesh by subdividing the triangle
1821 >   b) ignored
1822 >   c) replace values of an existing mesh vertex
1823  
1824 <    tri = SM_NTH_TRI(sm,tri_id);
1825 <    /* Get the sample that corresponds to the "which" vertex of "tri" */
1826 <    /* NEED: have re-init that sets clock flag */
1827 <    /* If this is a base-sample: create a new sample and replace
653 <       all references to the base sample with references to the
654 <       new sample
655 <       */
656 <    s_id = T_NTH_V(tri,which);
657 <    if(SM_BASE_ID(sm,s_id))
658 <     {
659 <         if(snew_id != -1)
660 <           n_id = smAdd_sample_point(sm,c,dir,p);
661 <         else
662 <           n_id = snew_id;
663 <         smReplace_point(sm,tri,s_id,n_id);
664 <         s_id = n_id;
665 <     }
666 <    else /* If the sample exists, reset the values */
667 <       /* NOTE: This test was based on the SPHERICAL coordinates
668 <               of the point: If we are doing a multiple-sample-per
669 <               SPHERICAL pixel: we will want to test for equality-
670 <               and do other processing: for now: SINGLE SAMPLE PER
671 <               PIXEL
672 <               */
673 <      /* NOTE: snew_id needs to be marked as invalid?*/
674 <      if(snew_id == -1)
675 <        smInit_sample(sm,s_id,c,dir,p);
676 <    else
677 <      smReset_sample(sm,s_id,snew_id);
678 <    return(s_id);
679 < }
1824 >   In case a, the routine will return TRUE, for b,c will return FALSE
1825 >   In case a, also determine if this sample should cause the deletion of
1826 >   an existing vertex. If so *rptr will contain the id of the sample to delete
1827 >   after the new sample has been added.
1828  
1829 +   ASSUMPTION: this will not be called with a new sample that is
1830 +               a BASE point.
1831  
1832 < /* Locate the point-id in the point location structure: */
1832 >   The following tests are performed (in order) to determine the fate
1833 >   of the sample:
1834 >
1835 >   1) If the new sample is close in ws, and close in the spherical projection
1836 >      to one of the triangle vertex samples:
1837 >         pick the point with dir closest to that of the canonical view
1838 >         If it is the new point: mark existing point for deletion,and return
1839 >         TRUE,else return FALSE
1840 >   2) If the spherical projection of new is < REPLACE_EPS from a base point:
1841 >      add new and mark the base for deletion: return TRUE
1842 >   3) If the addition of the new sample point would introduce a "puncture"
1843 >      or cause new triangles with large depth differences:return FALSE
1844 >     This attempts to throw out points that should be occluded  
1845 > */
1846   int
1847 < smInsert_point_in_tri(sm,c,dir,p,s_id,tri_id)
1847 > smTest_samp(sm,tri_id,dir,p,rptr,ns,n0,n1,n2,ds,d0,on,which)
1848     SM *sm;
1849 <   COLR c;
1849 >   int tri_id;
1850     FVECT dir,p;
1851 <   int s_id,tri_id;
1851 >   S_ID *rptr;
1852 >   FVECT ns,n0,n1,n2;
1853 >   double ds,d0;
1854 >   int on,which;
1855   {
1856 <    TRI *tri,*t0,*t1,*t2,*nbr;
1857 <    int v0_id,v1_id,v2_id,n_id;
1858 <    int t0_id,t1_id,t2_id;
1859 <    LIST *tlist;
1860 <    FVECT npt;
1856 >    TRI *tri;
1857 >    double d,d2,dnear,dspt,d01,d12,d20,s0,s1,s2;
1858 >    double dp,dp1;
1859 >    S_ID vid[3];
1860 >    int i,norm,dcnt,bcnt;
1861 >    FVECT diff[3],spt,npt,n;
1862 >    FVECT nearpt;
1863  
1864 <    if(s_id == SM_INVALID)
1865 <       s_id = smAdd_sample_point(sm,c,dir,p);
698 <    
1864 >    *rptr = INVALID;
1865 >    bcnt = dcnt = 0;
1866      tri = SM_NTH_TRI(sm,tri_id);
1867 <    v0_id = T_NTH_V(tri,0);
1868 <    v1_id = T_NTH_V(tri,1);
1869 <    v2_id = T_NTH_V(tri,2);
1867 >    vid[0] = T_NTH_V(tri,0);
1868 >    vid[1] = T_NTH_V(tri,1);
1869 >    vid[2] = T_NTH_V(tri,2);
1870  
1871 <    n_id = -1;
705 <    if(SM_BASE_ID(sm,v0_id)||SM_BASE_ID(sm,v1_id)||SM_BASE_ID(sm,v2_id))
1871 >    for(i=0; i<3; i++)
1872      {
1873 <      smDir(sm,npt,s_id);
1874 <            /* Change to an add and delete */
1875 <      t0_id = (SM_BASE_ID(sm,v0_id))?v0_id:-1;
1876 <      t1_id = (SM_BASE_ID(sm,v1_id))?v1_id:-1;
1877 <      t2_id = (SM_BASE_ID(sm,v2_id))?v2_id:-1;  
712 <      n_id = smClosest_vertex_in_tri(sm,t0_id,t1_id,t2_id,npt,P_REPLACE_EPS);
1873 >      if(SM_BASE_ID(sm,vid[i]))
1874 >        bcnt++;
1875 >      else
1876 >        if(SM_DIR_ID(sm,vid[i]))
1877 >          dcnt++;
1878      }
1879 <    t0_id = smAdd_tri(sm,s_id,v0_id,v1_id,&t0);
1880 <    /* Add triangle to the locator */
1881 <    smLocator_add_tri(sm,t0_id,s_id,v0_id,v1_id);
1879 >    if(on == ON_P)
1880 >    {
1881 >      FVECT edir;
1882 >     /* Pick the point with dir closest to that of the canonical view
1883 >         if it is the new sample: mark existing point for deletion
1884 >         */
1885 >      if(!dir)
1886 >        return(FALSE);
1887 >      if(SM_BASE_ID(sm,vid[which]))
1888 >        return(FALSE);
1889 >      if(SM_DIR_ID(sm,vid[which]))
1890 >      {
1891 >        *rptr = vid[which];
1892 >        return(TRUE);
1893 >      }
1894 >  decodedir(edir,SM_NTH_W_DIR(sm,vid[which]));
1895 >      if(which == 0)
1896 >        d = DOT(edir,n0);
1897 >      else
1898 >        if(which == 1)
1899 >          d = DOT(edir,n1);
1900 >        else
1901 >          d = DOT(edir,n2);
1902 >      d2 = DOT(dir,ns);
1903 >      /* The existing sample is a better sample:punt */
1904 >      if(d2 >= d)
1905 >        return(FALSE);
1906 >      else
1907 >      {
1908 >        /* The new sample is better: mark existing one for deletion*/
1909 >        *rptr = vid[which];
1910 >        return(TRUE);
1911 >      }
1912 >    }  
1913  
1914 <    t1_id = smAdd_tri(sm,s_id,v1_id,v2_id,&t1);
1915 <    smLocator_add_tri(sm,t1_id,s_id,v1_id,v2_id);
1916 <    t2_id = smAdd_tri(sm,s_id,v2_id,v0_id,&t2);
1917 <    smLocator_add_tri(sm,t2_id,s_id,v2_id,v0_id);      
1914 > /* Now test if sample epsilon is within circumcircle of enclosing tri
1915 >   if not punt:
1916 >   */
1917 >    {
1918 >      double ab[3],ac[3],r[3];
1919  
1920 <    /* Set the neighbor pointers for the new tris */
1921 <    T_NTH_NBR(t0,0) = t2_id;
1922 <    T_NTH_NBR(t0,1) = T_NTH_NBR(tri,0);
1923 <    T_NTH_NBR(t0,2) = t1_id;
1924 <    T_NTH_NBR(t1,0) = t0_id;
1925 <    T_NTH_NBR(t1,1) = T_NTH_NBR(tri,1);
1926 <    T_NTH_NBR(t1,2) = t2_id;
1927 <    T_NTH_NBR(t2,0) = t1_id;
1928 <    T_NTH_NBR(t2,1) = T_NTH_NBR(tri,2);
1929 <    T_NTH_NBR(t2,2) = t0_id;
1920 >      VSUB(ab,n2,n1);
1921 >      VSUB(ac,n0,n2);
1922 >      VCROSS(r,ab,ac);
1923 >      dp = DOT(r,n1);
1924 >      dp1 = DOT(r,ns);
1925 >      if(dp1*dp1 + COS_VERT_EPS*DOT(r,r) < dp*dp)
1926 >        {
1927 > #ifdef DEBUG
1928 >          eputs("smTest_samp:rejecting samp,cant guarantee not within eps\n");
1929 > #endif
1930 >          return(FALSE);
1931 >        }
1932 >    }
1933 > #ifdef DEBUG
1934 > #if DEBUG > 1
1935 >    if(on == ON_E)
1936 >    {
1937 >      TRI *topp;
1938 >      int opp_id;
1939 >      FVECT vopp;
1940  
1941 <    /* Reset the neigbor pointers for the neighbors of the original */
1942 <    nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,0));
1943 <    T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t0_id;
1944 <    nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,1));
1945 <    T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t1_id;
1946 <    nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,2));
1947 <    T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t2_id;
1948 <        
1949 <    smLocator_remove_tri(sm,tri_id);
1950 <    smDelete_tri(sm,tri_id);
1951 <        
1952 <    /* Fix up the new triangles*/
1953 <    tlist = push_data(NULL,t0_id);
1954 <    tlist = push_data(tlist,t1_id);
1955 <    tlist = push_data(tlist,t2_id);
1941 >      topp = SM_NTH_TRI(sm,T_NTH_NBR(tri,which));
1942 >      opp_id = T_NTH_V(topp, T_NTH_NBR_PTR(tri_id,topp));
1943 >      /* first check if valid tri created*/
1944 >      VSUB(vopp,SM_NTH_WV(sm,opp_id),SM_VIEW_CENTER(sm));
1945 >      normalize(vopp);
1946 >      VCROSS(n,ns,vopp);
1947 >      normalize(n);
1948 >      if(which==2)
1949 >        dp = DOT(n,n0) * DOT(n,n1);
1950 >      else
1951 >        if(which==0)
1952 >          dp = DOT(n,n1) * DOT(n,n2);
1953 >        else
1954 >          dp = DOT(n,n2) * DOT(n,n0);
1955 >      if(dp > 0.0)
1956 >      {
1957 >        eputs("smInsert_samp_mesh: couldn't split edge: rejecting\n");
1958 >        /* test epsilon for edge */
1959 >        return(FALSE);
1960 >      }
1961 >    }
1962 > #endif
1963 > #endif
1964 >  /* TEST 4:
1965 >     If the addition of the new sample point would introduce a "puncture"
1966 >     or cause new triangles with large depth differences:dont add:    
1967 >     */
1968 >    if(bcnt || dcnt)
1969 >       return(TRUE);
1970  
1971 <    smFix_tris(sm,s_id,tlist);
1971 >    if(ds < d0)
1972 >      return(TRUE);
1973  
1974 <    if(n_id != -1)
1975 <       smDelete_point(sm,n_id);
1974 >    d01 = DIST_SQ(SM_NTH_WV(sm,vid[1]),SM_NTH_WV(sm,vid[0]));
1975 >    VSUB(diff[0],SM_NTH_WV(sm,vid[0]),p);
1976 >    s0 = DOT(diff[0],diff[0]);
1977 >    if(s0 < S_REPLACE_SCALE*d01)
1978 >       return(TRUE);
1979  
1980 <    return(s_id);
1981 < }
1982 <    
1980 >    d12 = DIST_SQ(SM_NTH_WV(sm,vid[2]),SM_NTH_WV(sm,vid[1]));
1981 >    if(s0 < S_REPLACE_SCALE*d12)
1982 >       return(TRUE);    
1983 >    d20 = DIST_SQ(SM_NTH_WV(sm,vid[0]),SM_NTH_WV(sm,vid[2]));
1984 >    if(s0 < S_REPLACE_SCALE*d20)
1985 >       return(TRUE);    
1986 >    d = MIN3(d01,d12,d20);
1987 >    VSUB(diff[1],SM_NTH_WV(sm,vid[1]),p);
1988 >   s1 = DOT(diff[1],diff[1]);
1989 >    if(s1 < S_REPLACE_SCALE*d)
1990 >       return(TRUE);
1991 >    VSUB(diff[2],SM_NTH_WV(sm,vid[2]),p);
1992 >    s2 = DOT(diff[2],diff[2]);
1993 >    if(s2 < S_REPLACE_SCALE*d)
1994 >       return(TRUE);    
1995  
1996 < int
1997 < smPointLocate(sm,pt,type,which,norm)
1998 < SM *sm;
1999 < FVECT pt;
2000 < char *type,*which;
2001 < char norm;
1996 >  /* TEST 5:
1997 >     Check to see if triangle is relatively large and should therefore
1998 >     be subdivided anyway.
1999 >     */  
2000 >    d0 = d0*d0*DIST_SQ(SM_NTH_WV(sm,vid[1]),SM_VIEW_CENTER(sm));
2001 >    d0 *= DIST_SQ(SM_NTH_WV(sm,vid[2]),SM_VIEW_CENTER(sm));
2002 >    if (d01*d12*d20/d0 > S_REPLACE_TRI)
2003 >        return(TRUE);
2004 >            
2005 >    return(FALSE);
2006 > }
2007 > S_ID
2008 > smReplace_samp(sm,c,dir,p,np,s_id,t_id,o_id,on,which)
2009 >     SM *sm;
2010 >     COLR c;
2011 >     FVECT dir,p,np;
2012 >     S_ID s_id;
2013 >     int t_id;
2014 >     S_ID o_id;
2015 >     int on,which;
2016   {
2017 <  STREE *st;
2018 <  int tri;
2019 <  FVECT npt;
2020 <  
2021 <  st = SM_LOCATOR(sm);
2022 <  if(norm)
2023 <  {
2024 <      point_on_sphere(npt,pt,SM_VIEW_CENTER(sm));
2025 <      tri = stPoint_locate(st,npt,type,which);
2017 >  S_ID v_id;
2018 >  int tri_id;
2019 >  TRI *t,*tri;
2020 >
2021 >  tri = SM_NTH_TRI(sm,t_id);
2022 >  v_id = T_NTH_V(tri,which);
2023 >
2024 >  /* If it is a base id, need new sample */
2025 >  if(SM_BASE_ID(sm,v_id))
2026 >    return(v_id);
2027 >
2028 >  if(EQUAL_VEC3(p,SM_NTH_WV(sm,v_id)))
2029 >    return(INVALID);
2030 >
2031 >  if(dir)
2032 >  {    /* If world point */
2033 >     FVECT odir,no;
2034 >     double d,d1;
2035 >     int dir_id;
2036 >    /* if existing point is a not a dir, compare directions */
2037 >    if(!(dir_id = SM_DIR_ID(sm,v_id)))
2038 >    {
2039 >      decodedir(odir, SM_NTH_W_DIR(sm,v_id));  
2040 >      VSUB(no,SM_NTH_WV(sm,v_id),SM_VIEW_CENTER(sm));
2041 >      d = DOT(dir,np);
2042 >      d1 = DOT(odir,np);
2043 >     /* The existing sample is a better sample:punt */
2044 >    }
2045 >    if(dir_id || (d*d*DOT(no,no) > d1*d1))
2046 >    {
2047 >      /* The new sample has better information- replace values */
2048 >      sInit_samp(SM_SAMP(sm),v_id,c,dir,p,o_id);
2049 >      if(!SM_IS_NTH_T_NEW(sm,t_id))
2050 >         SM_SET_NTH_T_NEW(sm,t_id);
2051 >      tri_id = smTri_next_ccw_nbr(sm,tri,v_id);
2052 >      while(tri_id != t_id)
2053 >      {
2054 >        t = SM_NTH_TRI(sm,tri_id);
2055 >        if(!SM_IS_NTH_T_NEW(sm,tri_id))
2056 >          SM_SET_NTH_T_NEW(sm,tri_id);
2057 >        tri_id = smTri_next_ccw_nbr(sm,t,v_id);
2058 >      }
2059 >    }
2060 >    return(v_id);
2061    }
2062 <  else
2063 <     tri = stPoint_locate(st,pt,type,which);
2064 <  return(tri);
2062 >  else  /* New point is a dir */
2063 >  return(INVALID);
2064 >
2065   }
2066  
2067 < QUADTREE
2068 < smPointLocateCell(sm,pt,norm,v0,v1,v2)
2067 > S_ID
2068 > smAlloc_samp(sm)
2069   SM *sm;
784 FVECT pt;
785 char norm;
786 FVECT v0,v1,v2;
2070   {
2071 <  STREE *st;
2072 <  QUADTREE *qtptr;
2073 <  FVECT npt;
2071 >  S_ID s_id;
2072 >  int replaced,cnt;
2073 >  SAMP *s;
2074 >  FVECT p;
2075  
2076 <  st = SM_LOCATOR(sm);
2077 <  if(norm)
2076 >  s = SM_SAMP(sm);
2077 >  s_id = sAlloc_samp(s,&replaced);
2078 >  while(replaced)
2079    {
2080 <      point_on_sphere(npt,pt,SM_VIEW_CENTER(sm));
2081 <  
797 <      qtptr = stPoint_locate_cell(st,npt,v0,v1,v2);
2080 >    smRemoveVertex(sm,s_id);
2081 >    s_id = sAlloc_samp(s,&replaced);
2082    }
2083 <  else
800 <     qtptr = stPoint_locate_cell(st,pt,v0,v1,v2);
801 <
802 <  if(qtptr)
803 <    return(*qtptr);
804 <  else
805 <    return(EMPTY);
2083 >  return(s_id);
2084   }
2085  
2086 < int
2087 < smAdd_sample_to_mesh(sm,c,dir,pt,s_id)
2086 >
2087 > /* Add sample to the mesh:
2088 >
2089 >   the sample can be a world space or directional point. If o_id !=INVALID,
2090 >   then we have an existing sample containing the appropriate information
2091 >   already converted into storage format.
2092 >   The spherical projection of the point/ray can:
2093 >        a) coincide with existing vertex
2094 >                i) conincides with existing sample
2095 >               ii) projects same as existing sample
2096 >              iii) hits a base vertex
2097 >        b) coincide with existing edge
2098 >        c) Fall in existing triangle
2099 > */
2100 > S_ID
2101 > smAdd_samp(sm,c,dir,p,o_id)
2102     SM *sm;
2103     COLR c;
2104 <   FVECT dir,pt;
2105 <   int s_id;
2104 >   FVECT dir,p;
2105 >   S_ID o_id;
2106   {
2107 <    int t_id;
2108 <    char type,which;
2109 <    double d;
2110 <    FVECT p;
2111 <    
2112 <    /* If new, foreground pt */
2113 <    if(pt)
2107 >  int t_id,on,which,n_id;
2108 >  S_ID s_id,r_id,nbr_id;
2109 >  double ds,d0;
2110 >  FVECT wpt,ns,n0,n1,n2;
2111 >  QUADTREE qt,parent;
2112 >  TRI *t;
2113 >
2114 >  r_id = INVALID;
2115 >  nbr_id = INVALID;
2116 >  /* Must do this first-as may change mesh */
2117 >  s_id = smAlloc_samp(sm);
2118 >  SM_S_NTH_QT(sm,s_id)= EMPTY;
2119 >  /* If sample is a world space point */
2120 >  if(p)
2121 >  {
2122 >    VSUB(ns,p,SM_VIEW_CENTER(sm));
2123 >    ds = normalize(ns);
2124 >    while(1)
2125      {
2126 <        /* NOTE: This should be elsewhere! */
2127 <        d = DIST(pt,SM_VIEW_CENTER(smMesh));
2128 <        smDist_sum += 1.0/d;
2129 <        /************************************/
827 <        t_id = smPointLocate(smMesh,pt,&type,&which,TRUE);
828 <        if(type==GT_FACE)
829 <           s_id = smInsert_point_in_tri(smMesh,c,dir,pt,s_id,t_id);
830 <        else
831 <           if(type==GT_VERTEX)
832 <              s_id = smReplace_vertex(smMesh,c,dir,pt,t_id,s_id,type,which);
2126 >      t_id = smSample_locate_tri(sm,ns,s_id,&on,&which,&nbr_id);
2127 >      qt = SM_S_NTH_QT(sm,s_id);
2128 >      if(t_id == INVALID)
2129 >      {
2130   #ifdef DEBUG
2131 <           else
835 <              eputs("smAdd_sample_to_mesh(): unrecognized type\n");
2131 >          eputs("smAddSamp(): unable to locate tri containing sample \n");
2132   #endif
2133 <    }
2134 <    else if(s_id != -1)
2135 <    {
840 <        VCOPY(p,SM_NTH_WV(sm,s_id));
841 <        if(SM_NTH_W_DIR(sm,s_id) != -1)
842 <        {
843 <            /* NOTE: This should be elsewhere! */
844 <            d = DIST(p,SM_VIEW_CENTER(smMesh));
845 <            smDist_sum += 1.0/d;
846 <            /************************************/
2133 >          smUnalloc_samp(sm,s_id);
2134 >          qtremovelast(qt,s_id);
2135 >          return(INVALID);
2136          }
2137 <        t_id = smPointLocate(smMesh,p,&type,&which,TRUE);
2138 <        if(type==GT_FACE)
2139 <           s_id = smInsert_point_in_tri(smMesh,c,dir,p,s_id,t_id);
2140 <        else
2141 <           if(type==GT_VERTEX)
2142 <              s_id = smReplace_vertex(smMesh,c,dir,p,t_id,s_id,type,which);
2143 < #ifdef DEBUG
2144 <           else
2145 <              eputs("smAdd_sample_to_mesh(): unrecognized type\n");
2137 >      /* If spherical projection coincides with existing sample: replace */
2138 >      if(on == ON_V)
2139 >      {
2140 >          n_id = smReplace_samp(sm,c,dir,p,ns,s_id,t_id,o_id,on,which);
2141 >          if(n_id != s_id)
2142 >          {
2143 >            smUnalloc_samp(sm,s_id);
2144 > #if 0
2145 >            fprintf(stderr,"Unallocating sample %d\n",s_id);
2146   #endif
2147 +            qtremovelast(qt,s_id);
2148 +          }
2149 +          return(n_id);
2150 +      }
2151 +      t = SM_NTH_TRI(sm,t_id);
2152 +      VSUB(n0,SM_NTH_WV(sm,T_NTH_V(t,0)),SM_VIEW_CENTER(sm));
2153 +      d0 = normalize(n0);
2154 +      VSUB(n1,SM_NTH_WV(sm,T_NTH_V(t,1)),SM_VIEW_CENTER(sm));
2155 +      normalize(n1);
2156 +      VSUB(n2,SM_NTH_WV(sm,T_NTH_V(t,2)),SM_VIEW_CENTER(sm));
2157 +      normalize(n2);
2158 +      if((!(smTest_samp(sm,t_id,dir,p,&r_id,ns,n0,n1,n2,ds,d0,on,which))))
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 +        return(INVALID);
2166 +      }
2167 +      if(r_id != INVALID)
2168 +      {
2169 +        smRemoveVertex(sm,r_id);
2170 +        if(nbr_id == r_id)
2171 +        {
2172 +          qtremovelast(qt,s_id);
2173 +          SM_S_NTH_QT(sm,s_id) = EMPTY;
2174 +        }
2175 +      }
2176 +      else
2177 +        break;
2178      }
2179 <    /* Is a BG(sky point) */
2179 >    /* If sample is being added in the middle of the sample array: tone
2180 >       map individually
2181 >       */
2182 >    /* If not base or sky point, add distance from center to average*/  
2183 >    smDist_sum += 1.0/ds;
2184 >    /* Initialize sample */
2185 >    sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id);
2186 >    smInsert_samp_mesh(sm,s_id,t_id,ns,n0,n1,n2,on,which);
2187 >  }
2188 >    /* If sample is a direction vector */
2189      else
2190 <       {
2191 <           t_id = smPointLocate(smMesh,dir,&type,&which,FALSE);
2192 <           if(type==GT_FACE)
2193 <              s_id = smInsert_point_in_tri(smMesh,c,dir,NULL,s_id,t_id);
2194 <           else
2195 <              if(type==GT_VERTEX)
2196 <                 s_id = smReplace_vertex(smMesh,c,dir,NULL,t_id,s_id,type,which);
2190 >    {
2191 >      VADD(wpt,dir,SM_VIEW_CENTER(sm));
2192 >      /* Allocate space for a sample and initialize */
2193 >      while(1)
2194 >      {
2195 >        t_id = smSample_locate_tri(sm,dir,s_id,&on,&which,&nbr_id);
2196 >        qt = SM_S_NTH_QT(sm,s_id);
2197   #ifdef DEBUG
2198 <              else
2199 <                 eputs("smAdd_sample_to_mesh(): unrecognized type\n");
2198 >        if(t_id == INVALID)
2199 >        {
2200 >          eputs("smAddSamp():can't locate tri containing samp\n");
2201 >          smUnalloc_samp(sm,s_id);
2202 >          qtremovelast(qt,s_id);
2203 >          return(INVALID);
2204 >        }
2205   #endif
2206 <       }
2206 >        if(on == ON_V)
2207 >        {
2208 >          smUnalloc_samp(sm,s_id);
2209 >          qtremovelast(qt,s_id);
2210 >          return(INVALID);
2211 >        }
2212 >        t = SM_NTH_TRI(sm,t_id);
2213 >        VSUB(n0,SM_NTH_WV(sm,T_NTH_V(t,0)),SM_VIEW_CENTER(sm));
2214 >        d0 = normalize(n0);
2215 >        VSUB(n1,SM_NTH_WV(sm,T_NTH_V(t,1)),SM_VIEW_CENTER(sm));
2216 >        normalize(n1);
2217 >        VSUB(n2,SM_NTH_WV(sm,T_NTH_V(t,2)),SM_VIEW_CENTER(sm));
2218 >        normalize(n2);
2219 >        if(!smTest_samp(sm,t_id,NULL,wpt,&r_id,dir,n0,n1,n2,1.0,d0,on,which))
2220 >        {
2221 >          smUnalloc_samp(sm,s_id);
2222 >          qtremovelast(qt,s_id);
2223 >          return(INVALID);
2224 >        }
2225 >        if(r_id != INVALID)
2226 >        {
2227 >          smRemoveVertex(sm,r_id);
2228 >          if(nbr_id == r_id)
2229 >            {
2230 >              qtremovelast(qt,s_id);
2231 >              SM_S_NTH_QT(sm,s_id) = EMPTY;
2232 >            }
2233 >        }
2234 >        else
2235 >          break;
2236 >      }
2237 >      sInit_samp(SM_SAMP(sm),s_id,c,NULL,wpt,o_id);
2238 >      smInsert_samp_mesh(sm,s_id,t_id,dir,n0,n1,n2,on,which);
2239 >    }
2240      return(s_id);
2241   }
2242  
# Line 884 | Line 2251 | smAdd_sample_to_mesh(sm,c,dir,pt,s_id)
2251   * New sample representation will be output in next call to smUpdate().
2252   * If the point is a sky point: then v=NULL
2253   */
2254 + #define FVECT_TO_SFLOAT(p) \
2255 +        (p[0]=(SFLOAT)p[0],p[1]=(SFLOAT)p[1],p[2]=(SFLOAT)p[2])
2256   int
2257   smNewSamp(c,dir,p)
2258   COLR c;
2259   FVECT dir;
2260   FVECT p;
892
2261   {
2262 <    int s_id;
2263 <    
2262 >    S_ID s_id;
2263 >
2264      /* First check if this the first sample: if so initialize mesh */
2265      if(SM_NUM_SAMP(smMesh) == 0)
2266 < #ifdef TEST_DRIVER
2267 <      smInit_mesh(smMesh,View.vp);
2268 < #else
2269 <      smInit_mesh(smMesh,odev.v.vp);
2270 < #endif
2271 <    s_id = smAdd_sample_to_mesh(smMesh,c,dir,p,-1);
2272 < #if 0
2273 < {
906 <  char buff[100];
907 <  sprintf(buff,"Added sample %d\n",s_id);
908 <    eputs(buff);
909 < }
910 < #endif
911 <    return(s_id);
912 <    
913 < }    
914 < /*
915 < * int
916 < * smFindsamp(orig, dir): intersect ray with 3D rep. and find closest sample
917 < * FVECT        orig, dir;
918 < *
919 < * Find the closest sample to the given ray.  Return -1 on failure.
920 < */
2266 >    {
2267 >      smInit_sm(smMesh,odev.v.vp);
2268 >      sClear_all_flags(SM_SAMP(smMesh));
2269 >    }
2270 >    FVECT_TO_SFLOAT(p);
2271 >    FVECT_TO_SFLOAT(dir);
2272 >    /* Add the sample to the mesh */
2273 >    s_id = smAdd_samp(smMesh,c,dir,p,INVALID);
2274  
2275 < /*
923 < * smClean()            : display has been wiped clean
924 < *
925 < * Called after display has been effectively cleared, meaning that all
926 < * geometry must be resent down the pipeline in the next call to smUpdate().
927 < */
928 <
929 <
930 < /*
931 < * smUpdate(vp, qua)    : update OpenGL output geometry for view vp
932 < * VIEW *vp;            : desired view
933 < * int  qua;            : quality level (percentage on linear time scale)
934 < *
935 < * Draw new geometric representation using OpenGL calls.  Assume that the
936 < * view has already been set up and the correct frame buffer has been
937 < * selected for drawing.  The quality level is on a linear scale, where 100%
938 < * is full (final) quality.  It is not necessary to redraw geometry that has
939 < * been output since the last call to smClean().
940 < */
941 <
942 <
943 < int
944 < smClear_vert(sm,id)
945 < SM *sm;
946 < int id;
947 < {
948 <    if(SM_INVALID_POINT_ID(sm,id))
949 <       return(FALSE);
2275 >    return((int)s_id);
2276      
2277 <    SM_NTH_VERT(sm,id) = SM_INVALID;
2278 <
2279 <    return(TRUE);
954 < }
955 <
956 < int
957 < smAdd_base_vertex(sm,v,d)
2277 > }    
2278 > S_ID
2279 > smAdd_base_vertex(sm,v)
2280     SM *sm;
2281 <   FVECT v,d;
2281 >   FVECT v;
2282   {
2283 <  int id;
2283 >  S_ID id;
2284  
2285    /* First add coordinate to the sample array */
2286 <  id = smAdd_aux_point(sm,v,d);
2287 <  if(id == -1)
2288 <    return(SM_INVALID);
2286 >  id = sAdd_base_point(SM_SAMP(sm),v);
2287 >  if(id == INVALID)
2288 >    return(INVALID);
2289    /* Initialize triangle pointer to -1 */
2290    smClear_vert(sm,id);
2291    return(id);
# Line 981 | Line 2303 | smCreate_base_mesh(sm,type)
2303   SM *sm;
2304   int type;
2305   {
2306 <  int i,id;
2307 <  int p[4],ids[4];
2308 <  int v0_id,v1_id,v2_id;
2309 <  TRI *tris[4];
2310 <  FVECT d,pt,cntr;
2311 <  
990 <  /* First insert the base vertices into the sample point array */
2306 >  int i,s_id,tri_id,nbr_id;
2307 >  S_ID p[SM_BASE_POINTS];
2308 >  int ids[SM_BASE_TRIS];
2309 >  S_ID v0_id,v1_id,v2_id;
2310 >  FVECT d,pt,cntr,v0,v1,v2;
2311 >  TRI *t;
2312  
2313 <  for(i=0; i < 4; i++)
2313 >  /* First insert the base vertices into the sample point array */
2314 >  for(i=0; i < SM_BASE_POINTS; i++)
2315    {
2316 <      VADD(cntr,stDefault_base[i],SM_VIEW_CENTER(sm));
2317 <      point_on_sphere(d,cntr,SM_VIEW_CENTER(sm));
2318 <      id = smAdd_base_vertex(sm,cntr,d);
997 <    /* test to make sure vertex allocated */
998 <    if(id != -1)
999 <      p[i] = id;
1000 <    else
1001 <      return(0);
2316 >    VADD(cntr,icosa_verts[i],SM_VIEW_CENTER(sm));
2317 >    p[i]  = smAdd_base_vertex(sm,cntr);
2318 >    smInsert_samp(sm,p[i],icosa_verts[i],NULL);
2319    }
2320    /* Create the base triangles */
2321 <  for(i=0;i < 4; i++)
2321 >  for(i=0;i < SM_BASE_TRIS; i++)
2322    {
2323 <    v0_id = p[stTri_verts[i][0]];
2324 <    v1_id = p[stTri_verts[i][1]];
2325 <    v2_id = p[stTri_verts[i][2]];
2326 <    if((ids[i] = smAdd_tri(sm, v0_id,v1_id,v2_id,&(tris[i])))== -1)
2327 <     return(0);
2328 <    smLocator_add_tri(sm,ids[i],v0_id,v1_id,v2_id);
2323 >    v0_id = p[icosa_tris[i][0]];
2324 >    v1_id = p[icosa_tris[i][1]];
2325 >    v2_id = p[icosa_tris[i][2]];
2326 >    ids[i] = smAdd_tri(sm, v0_id,v1_id,v2_id,&t);
2327 >    /* Set neighbors */
2328 >    for(nbr_id=0; nbr_id < 3; nbr_id++)
2329 >      T_NTH_NBR(SM_NTH_TRI(sm,ids[i]),nbr_id) = icosa_nbrs[i][nbr_id];
2330 >
2331    }
2332 <  /* Set neighbors */
2332 > return(1);
2333  
2334 <  T_NTH_NBR(tris[0],0) = ids[3];
1016 <  T_NTH_NBR(tris[0],1) = ids[2];
1017 <  T_NTH_NBR(tris[0],2) = ids[1];
2334 > }
2335  
2336 <  T_NTH_NBR(tris[1],0) = ids[3];
2337 <  T_NTH_NBR(tris[1],1) = ids[0];
2338 <  T_NTH_NBR(tris[1],2) = ids[2];
2336 > smRebuild(sm,v)
2337 >   SM *sm;
2338 >   VIEW *v;
2339 > {
2340 >    S_ID s_id;
2341 >    int j,cnt;
2342 >    FVECT p,ov,dir;
2343 >    double d;
2344  
2345 <  T_NTH_NBR(tris[2],0) = ids[3];
2346 <  T_NTH_NBR(tris[2],1) = ids[1];
2347 <  T_NTH_NBR(tris[2],2) = ids[0];
2345 > #ifdef DEBUG
2346 >    fprintf(stderr,"smRebuild(): rebuilding....");
2347 > #endif
2348 >    smCull(sm,v,SM_ALL_LEVELS);
2349 >    /* Clear the mesh- and rebuild using the current sample array */
2350 >    /* Remember the current number of samples */
2351 >    cnt = SM_NUM_SAMP(sm);
2352 >    /* Calculate the difference between the current and new viewpoint*/
2353 >    /* Will need to subtract this off of sky points */
2354 >    VCOPY(ov,SM_VIEW_CENTER(sm));
2355  
2356 <  T_NTH_NBR(tris[3],0) = ids[1];
2357 <  T_NTH_NBR(tris[3],1) = ids[2];
2358 <  T_NTH_NBR(tris[3],2) = ids[0];
2359 <  return(1);
2356 >    /* Initialize the mesh to 0 samples and the base triangles */
2357 >    smInit_sm(sm,v->vp);
2358 >    /* Go through all samples and add in if in the new view frustum, and
2359 >       the dir is <= 30 degrees from new view
2360 >     */
2361 >    for(s_id=0; s_id < cnt; s_id++)
2362 >    {
2363 >      /* First check if sample visible(conservative approx: if one of tris
2364 >         attached to sample is in frustum)       */
2365 >      if(!S_IS_FLAG(s_id))
2366 >        continue;
2367 >      
2368 >      /* Next test if direction > 30 degrees from current direction */
2369 >        if(SM_NTH_W_DIR(sm,s_id)!=-1)
2370 >        {
2371 >            VSUB(p,SM_NTH_WV(sm,s_id),v->vp);
2372 >            decodedir(dir,SM_NTH_W_DIR(sm,s_id));
2373 >            d = DOT(dir,p);
2374 >            if (d*d < MAXDIFF2*DOT(p,p))
2375 >              continue;
2376 >            VCOPY(p,SM_NTH_WV(sm,s_id));
2377 >            smAdd_samp(sm,NULL,dir,p,s_id);
2378 >        }
2379 >        else
2380 >        {
2381 >          /* If the direction is > 45 degrees from current view direction:
2382 >             throw out
2383 >           */
2384 >          VSUB(dir,SM_NTH_WV(sm,s_id),ov);
2385 >          if(DOT(dir,v->vdir) < MAXDIR)
2386 >            continue;
2387  
2388 +          VADD(SM_NTH_WV(sm,s_id),dir,SM_VIEW_CENTER(sm));
2389 +          smAdd_samp(sm,NULL,dir,NULL,s_id);
2390 +        }
2391 +
2392 +    }
2393 + #ifdef DEBUG
2394 +    fprintf(stderr,"smRebuild():done\n");
2395 + #endif
2396   }
2397  
2398 <
2398 > /* OS is constrained to be <= QT_MAXCSET : if the set exceeds this, the
2399 > results of check_set are conservative
2400 > */
2401   int
2402 < smNext_tri_flag_set(sm,i,which,b)
2403 <     SM *sm;
1038 <     int i,which;
1039 <     char b;
2402 > compare_ids(id1,id2)
2403 > S_ID *id1,*id2;
2404   {
2405 +  int d;
2406  
2407 <  for(; i < SM_TRI_CNT(sm);i++)
2407 >  d = *id2-*id1;
2408 >  
2409 >  if(d > 0)
2410 >    return(-1);
2411 >  if(d < 0)
2412 >    return(1);
2413 >  
2414 >  return(0);
2415 > }
2416 >
2417 >
2418 > null_func(argptr,root,qt,n)
2419 >     int *argptr;
2420 >     int root;
2421 >     QUADTREE qt;
2422 >     int n;
2423 > {
2424 >  /* do nothing */
2425 > }
2426 >
2427 > mark_active_samples(argptr,root,qt,n)
2428 >     int *argptr;
2429 >     int root;
2430 >     QUADTREE qt;
2431 >     int n;
2432 > {
2433 >  S_ID *os,s_id;
2434 >  register int i,t_id,tri_id;
2435 >  TRI *tri;
2436 >
2437 >  if(QT_IS_EMPTY(qt) || QT_LEAF_IS_FLAG(qt))
2438 >    return;
2439 >  
2440 >  /* For each triangle in the set, set the which flag*/
2441 >  os = qtqueryset(qt);
2442 >
2443 >  for (i = QT_SET_CNT(os); i > 0; i--)
2444    {
2445 <    if(!SM_IS_NTH_T_FLAG(sm,i,which))
2446 <      continue;
2445 >    s_id = QT_SET_NEXT_ELEM(os);
2446 >    S_SET_FLAG(s_id);
2447  
2448 <    if(!b)
2449 <      break;
2450 <    if((b==1) && !SM_BG_TRI(sm,i))
2451 <      break;
2452 <    if((b==2) && SM_BG_TRI(sm,i))
2453 <      break;
2448 >    tri_id = SM_NTH_VERT(smMesh,s_id);
2449 >    /* Set the active flag for all adjacent triangles */
2450 >     tri = SM_NTH_TRI(smMesh,tri_id);
2451 >     SM_SET_NTH_T_ACTIVE(smMesh,tri_id);
2452 >     while((t_id = smTri_next_ccw_nbr(smMesh,tri,s_id)) != tri_id)
2453 >     {
2454 >       tri = SM_NTH_TRI(smMesh,t_id);
2455 >       SM_SET_NTH_T_ACTIVE(smMesh,t_id);
2456 >     }
2457    }
1054    
1055  return(i);
2458   }
2459  
2460 + smCull(sm,view,n)
2461 + SM *sm;
2462 + VIEW *view;
2463 + int n;
2464 + {
2465 +     FVECT nr[4],far[4];
2466 +     FPEQ peq;
2467 +     int debug=0;
2468 +     FUNC f;
2469  
2470 < int
2471 < smNext_valid_tri(sm,i)
1061 <     SM *sm;
1062 <     int i;
1063 < {
2470 >     /* First clear all the quadtree node flags */
2471 >     qtClearAllFlags();
2472  
2473 <  while( i < SM_TRI_CNT(sm) && !T_IS_VALID(SM_NTH_TRI(sm,i)))
2474 <     i++;
2475 <    
2476 <  return(i);
2477 < }
2473 >     F_ARGS(f) = NULL;
2474 >     /* If marking samples down to leaves */
2475 >     if(n == SM_ALL_LEVELS)
2476 >     {
2477 >     /* Mark triangles in approx. view frustum as being active:set
2478 >        LRU counter: for use in discarding samples when out
2479 >        of space
2480 >        */
2481 >       F_FUNC(f) = mark_active_samples;
2482 >       smClear_flags(sm,T_ACTIVE_FLAG);
2483 >       /* Clear all of the active sample flags*/
2484 >       sClear_all_flags(SM_SAMP(sm));
2485 >     }
2486 >     else
2487 >       /* Just mark qtree flags */
2488 >       F_FUNC(f) = null_func;
2489  
2490 +     /* calculate the world space coordinates of the view frustum:
2491 +        Radiance often has no far clipping plane: but driver will set
2492 +        dev_zmin,dev_zmax to satisfy OGL
2493 +    */
2494 +     calculate_view_frustum(view->vp,view->hvec,view->vvec,view->horiz,
2495 +                            view->vert, dev_zmin,dev_zmax,nr,far);
2496  
2497 + #ifdef TEST_DRIVER
2498 +     VCOPY(FrustumFar[0],far[0]);
2499 +     VCOPY(FrustumFar[1],far[1]);
2500 +     VCOPY(FrustumFar[2],far[2]);
2501 +     VCOPY(FrustumFar[3],far[3]);
2502 +     VCOPY(FrustumNear[0],nr[0]);
2503 +     VCOPY(FrustumNear[1],nr[1]);
2504 +     VCOPY(FrustumNear[2],nr[2]);
2505 +     VCOPY(FrustumNear[3],nr[3]);
2506 + #endif
2507 +     /* Project the view frustum onto the spherical quadtree */
2508 +     /* For every cell intersected by the projection of the faces
2509  
2510 < qtTri_verts_from_id(t_id,v0,v1,v2)
2511 < int t_id;
2512 < FVECT v0,v1,v2;
1076 < {
1077 <  TRI *t;
1078 <  int v0_id,v1_id,v2_id;
1079 <  
1080 <  t = SM_NTH_TRI(smMesh,t_id);
1081 <  v0_id = T_NTH_V(t,0);
1082 <  v1_id = T_NTH_V(t,1);
1083 <  v2_id = T_NTH_V(t,2);
2510 >        of the frustum: mark all triangles in the cell as ACTIVE-
2511 >        Also set the triangles LRU clock counter
2512 >        */
2513  
2514 <  smDir(smMesh,v0,v0_id);
2515 <  smDir(smMesh,v1,v1_id);
1087 <  smDir(smMesh,v2,v2_id);
2514 >     if(EQUAL_VEC3(view->vp,SM_VIEW_CENTER(sm)))
2515 >     {/* Near face triangles */
2516  
2517 +       smLocator_apply(sm,nr[0],nr[2],nr[3],f,n);
2518 +       smLocator_apply(sm,nr[2],nr[0],nr[1],f,n);
2519 +       return;
2520 +     }
2521 +     /* Test the view against the planes: and swap orientation if inside:*/
2522 +     tri_plane_equation(nr[0],nr[2],nr[3], &peq,FALSE);
2523 +     if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0)
2524 +     {/* Near face triangles */
2525 +       smLocator_apply(sm,nr[3],nr[2],nr[0],f,n);
2526 +       smLocator_apply(sm,nr[1],nr[0],nr[2],f,n);
2527 +     }
2528 +     else
2529 +     {/* Near face triangles */
2530 +       smLocator_apply(sm,nr[0],nr[2],nr[3],f,n);
2531 +       smLocator_apply(sm,nr[2],nr[0],nr[1],f,n);
2532 +     }
2533 +     tri_plane_equation(nr[0],far[3],far[0], &peq,FALSE);
2534 +     if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0)
2535 +     { /* Right face triangles */
2536 +       smLocator_apply(sm,far[0],far[3],nr[0],f,n);
2537 +       smLocator_apply(sm,nr[3],nr[0],far[3],f,n);
2538 +     }
2539 +     else
2540 +     {/* Right face triangles */
2541 +       smLocator_apply(sm,nr[0],far[3],far[0],f,n);
2542 +       smLocator_apply(sm,far[3],nr[0],nr[3],f,n);
2543 +     }
2544 +
2545 +     tri_plane_equation(nr[1],far[2],nr[2], &peq,FALSE);
2546 +     if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0)
2547 +     { /* Left face triangles */
2548 +       smLocator_apply(sm,nr[2],far[2],nr[1],f,n);
2549 +       smLocator_apply(sm,far[1],nr[1],far[2],f,n);
2550 +     }
2551 +     else
2552 +     { /* Left face triangles */
2553 +       smLocator_apply(sm,nr[1],far[2],nr[2],f,n);
2554 +       smLocator_apply(sm,far[2],nr[1],far[1],f,n);
2555 +     }
2556 +     tri_plane_equation(nr[0],far[0],nr[1], &peq,FALSE);
2557 +     if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0)
2558 +     {/* Top face triangles */
2559 +       smLocator_apply(sm,nr[1],far[0],nr[0],f,n);
2560 +       smLocator_apply(sm,far[1],far[0],nr[1],f,n);
2561 +     }
2562 +     else
2563 +     {/* Top face triangles */
2564 +       smLocator_apply(sm,nr[0],far[0],nr[1],f,n);
2565 +       smLocator_apply(sm,nr[1],far[0],far[1],f,n);
2566 +     }
2567 +     tri_plane_equation(nr[3],nr[2],far[3], &peq,FALSE);
2568 +     if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0)
2569 +     {/* Bottom face triangles */
2570 +       smLocator_apply(sm,far[3],nr[2],nr[3],f,n);
2571 +       smLocator_apply(sm,far[3],far[2],nr[2],f,n);
2572 +     }
2573 +     else
2574 +     { /* Bottom face triangles */
2575 +       smLocator_apply(sm,nr[3],nr[2],far[3],f,n);
2576 +       smLocator_apply(sm,nr[2],far[2],far[3],f,n);
2577 +     }
2578 +      tri_plane_equation(far[2],far[0],far[1], &peq,FALSE);
2579 +     if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0)
2580 +     {/* Far face triangles */
2581 +       smLocator_apply(sm,far[0],far[2],far[1],f,n);
2582 +       smLocator_apply(sm,far[2],far[0],far[3],f,n);
2583 +     }
2584 +     else
2585 +     {/* Far face triangles */
2586 +       smLocator_apply(sm,far[1],far[2],far[0],f,n);
2587 +       smLocator_apply(sm,far[3],far[0],far[2],f,n);
2588 +     }
2589 +
2590   }
2591  
2592  
1092 int
1093 smIntersectTriSet(sm,t_set,orig,dir,pt)
1094   SM *sm;
1095   OBJECT *t_set;
1096   FVECT orig,dir,pt;
1097 {
1098    OBJECT *optr;
1099    int i,t_id,v_id;
1100    TRI *tri;
1101    FVECT p0,p1,p2;
1102    char type,which;
1103    int p0_id,p1_id,p2_id;
1104    
1105    for(optr = QT_SET_PTR(t_set),i = QT_SET_CNT(t_set); i > 0; i--)
1106    {
1107        t_id = QT_SET_NEXT_ELEM(optr);
1108        tri = SM_NTH_TRI(sm,t_id);
1109        p0_id = T_NTH_V(tri,0);
1110        p1_id = T_NTH_V(tri,1);
1111        p2_id = T_NTH_V(tri,2);
1112        VCOPY(p0,SM_NTH_WV(sm,p0_id));
1113        VCOPY(p1,SM_NTH_WV(sm,p1_id));
1114        VCOPY(p2,SM_NTH_WV(sm,p2_id));
1115        if(type = ray_intersect_tri(orig,dir,p0,p1,p2,pt,&which))
1116        {
1117          if(type==GT_VERTEX)
1118            return(T_NTH_V(tri,which));
1119          v_id = smClosest_vertex_in_w_tri(sm,p0_id,p1_id,p2_id,pt);
1120          return(v_id);
1121        }
1122    }
1123    return(-1);
1124 }
2593  
2594  
1127 /*
1128 * int
1129 * smFindSamp(FVECT orig, FVECT dir)
1130 *
1131 * Find the closest sample to the given ray.  Returns sample id, -1 on failure.
1132 * "dir" is assumed to be normalized
1133 */
1134 int
1135 smFindSamp(orig,dir)
1136 FVECT orig,dir;
1137 {
1138  FVECT r,v0,v1,v2,a,b,p;
1139  OBJECT os[MAXCSET+1],t_set[MAXSET+1];
1140  QUADTREE qt;
1141  int s_id;
1142  double d;
2595  
1144 /*  r is the normalized vector from the view center to the current
1145  *  ray point ( starting with "orig"). Find the cell that r falls in,
1146  *  and test the ray against all triangles stored in the cell. If
1147  *  the test fails, trace the projection of the ray across to the
1148  *  next cell it intersects: iterate until either an intersection
1149  *  is found, or the projection ray is // to the direction. The sample
1150  *  corresponding to the triangle vertex closest to the intersection
1151  *  point is returned.
1152  */
1153  
1154  /* First test if "orig" coincides with the View_center or if "dir" is
1155     parallel to r formed by projecting "orig" on the sphere. In
1156     either case, do a single test against the cell containing the
1157     intersection of "dir" and the sphere
1158   */
1159  point_on_sphere(b,orig,SM_VIEW_CENTER(smMesh));
1160  d = -DOT(b,dir);
1161  if(EQUAL_VEC3(orig,SM_VIEW_CENTER(smMesh)) || EQUAL(fabs(d),1.0))
1162  {
1163      qt = smPointLocateCell(smMesh,dir,FALSE,NULL,NULL,NULL);
1164      /* Test triangles in the set for intersection with Ray:returns
1165         first found
1166      */
1167      qtgetset(t_set,qt);
1168      s_id = smIntersectTriSet(smMesh,t_set,orig,dir,p);
1169 #ifdef TEST_DRIVER
1170      VCOPY(Pick_point[0],p);
1171 #endif
1172      return(s_id);
1173  }
1174  else
1175  {
1176      /* Starting with orig, Walk along projection of ray onto sphere */
1177      point_on_sphere(r,orig,SM_VIEW_CENTER(smMesh));
1178      qt = smPointLocateCell(smMesh,r,FALSE,v0,v1,v2);
1179      qtgetset(t_set,qt);
1180      /* os will contain all triangles seen thus far */
1181      setcopy(os,t_set);
2596  
1183      /* Calculate ray perpendicular to dir: when projection ray is // to dir,
1184         the dot product will become negative.
1185       */
1186      VSUM(a,b,dir,d);
1187      d = DOT(a,b);
1188      while(d > 0)
1189      {
1190          s_id = smIntersectTriSet(smMesh,t_set,orig,dir,p);
1191 #ifdef TEST_DRIVER
1192          VCOPY(Pick_point[0],p);
1193 #endif    
1194          if(s_id != EMPTY)
1195               return(s_id);
1196          /* Find next cell that projection of ray intersects */
1197          traceRay(r,dir,v0,v1,v2,r);
1198          qt = smPointLocateCell(smMesh,r,FALSE,v0,v1,v2);
1199          qtgetset(t_set,qt);
1200          /* Check triangles in set against those seen so far(os):only
1201             check new triangles for intersection (t_set')
1202          */
1203          check_set(t_set,os);
1204          d = DOT(a,r);
1205      }
1206    }
1207 #ifdef DEBUG  
1208  eputs("smFindSamp():Pick Ray did not intersect mesh");
1209 #endif
1210  return(EMPTY);
1211 }
1212  
2597  
1214 smRebuild_mesh(sm,vptr)
1215   SM *sm;
1216   VIEW *vptr;
1217 {
1218    int i;
1219    FVECT dir;
1220    COLR c;
1221    FVECT p,ov;
2598  
1223    /* Clear the mesh- and rebuild using the current sample array */
1224 #ifdef TEST_DRIVER
1225    View = *vptr;
1226 #endif    
2599  
2600 <    VSUB(ov,vptr->vp,SM_VIEW_CENTER(sm));
2601 <    smInit_mesh(sm,vptr->vp);
2602 <    
2603 <    SM_FOR_ALL_SAMPLES(sm,i)
2604 <    {
2605 <        if(SM_NTH_W_DIR(sm,i)==-1)
2606 <           VADD(SM_NTH_WV(sm,i),SM_NTH_WV(sm,i),ov);        
2607 <        smAdd_sample_to_mesh(sm,NULL,NULL,NULL,i);      
2608 <    }
1237 < }
2600 >
2601 >
2602 >
2603 >
2604 >
2605 >
2606 >
2607 >
2608 >
2609  
2610  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines