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