Changeset 2870
- Timestamp:
- 01/20/10 09:07:36 (15 years ago)
- Location:
- issm/trunk/src/c/Bamgx
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk/src/c/Bamgx/Mesh2.h
r2865 r2870 29 29 namespace bamg { 30 30 31 const double Pi = 3.14159265358979323846264338328; 32 const float fPi = 3.14159265358979323846264338328; 33 34 extern int hinterpole; 35 36 typedef P2<Icoor1,Icoor2> I2; 37 38 inline int BinaryRand(){ 31 const double Pi = 3.14159265358979323846264338328; 32 const float fPi = 3.14159265358979323846264338328; 33 34 extern int hinterpole; 35 36 inline int BinaryRand(){ 39 37 #ifdef RAND_MAX 40 41 38 const long HalfRandMax = RAND_MAX/2; 39 return rand() < HalfRandMax; 42 40 #else 43 41 return rand() & 16384; // 2^14 (for sun because RAND_MAX is not def in stdlib.h) 44 42 #endif 45 46 } 47 typedef P2<Real8,Real8> R2; 48 typedef P2xP2<Int2,Int4> I2xI2; 49 typedef P2<Real4,Real8> R2xR2; 43 } 44 45 typedef P2<Icoor1,Icoor2> I2; 46 typedef P2xP2<Int2,Int4> I2xI2; 47 typedef P2<Real8,Real8> R2; 48 typedef P2<Real4,Real8> R2xR2; 50 49 } 51 50 … … 53 52 54 53 namespace bamg { 55 inline float OppositeAngle(float a) 56 {return a<0 ? fPi + a :a - fPi ;} 57 inline double OppositeAngle(double a) 58 {return a<0 ? Pi + a :a - Pi ;} 59 60 Icoor2 inline det(const I2 &a,const I2 & b,const I2 &c) 61 { 62 register Icoor2 bax = b.x - a.x ,bay = b.y - a.y; 63 register Icoor2 cax = c.x - a.x ,cay = c.y - a.y; 64 return bax*cay - bay*cax;} 65 66 67 // def de numerotation dans un triangles 68 static const Int2 VerticesOfTriangularEdge[3][2] = {{1,2},{2,0},{0,1}}; 69 static const Int2 EdgesVertexTriangle[3][2] = {{1,2},{2,0},{0,1}}; 70 static const Int2 OppositeVertex[3] = {0,1,2}; 71 static const Int2 OppositeEdge[3] = {0,1,2}; 72 static const Int2 NextEdge[3] = {1,2,0}; 73 static const Int2 PreviousEdge[3] = {2,0,1}; 74 static const Int2 NextVertex[3] = {1,2,0}; 75 static const Int2 PreviousVertex[3] = {2,0,1}; 76 77 Int4 AGoodNumberPrimeWith(Int4 n); 78 79 // remark all the angle are in radian beetwen [-Pi,Pi] 80 81 82 class Geometry; 83 //static Geometry *NULLGeometry=0; 84 class Triangles; 85 class Triangle; 86 class QuadTree; 87 class GeometricalEdge; 88 class VertexOnGeom; 89 class VertexOnEdge; 90 ///////////////////////////////////////////////////////////////////////////////////// 91 const int IsVertexOnGeom = 8; 92 const int IsVertexOnVertex = 16; 93 const int IsVertexOnEdge = 32; 94 ///////////////////////////////////////////////////////////////////////////////////// 95 96 //class from MeshGeom 97 class DoubleAndInt4 { 98 public: double q; Int4 i3j; 99 int operator<(DoubleAndInt4 a){return q > a.q;} 100 };// to sort by decroissant 101 template<class T> inline void HeapSort(T *c,long n){ 102 long l,j,r,i; 103 T crit; 104 c--; // on decale de 1 pour que le tableau commence a 1 105 if( n <= 1) return; 106 l = n/2 + 1; 107 r = n; 108 while (1) { // label 2 109 if(l <= 1 ) { // label 20 110 crit = c[r]; 111 c[r--] = c[1]; 112 if ( r == 1 ) { c[1]=crit; return;} 113 } else crit = c[--l]; 114 j=l; 115 while (1) {// label 4 116 i=j; 117 j=2*j; 118 if (j>r) {c[i]=crit;break;} // L8 -> G2 119 if ((j<r) && (c[j] < c[j+1])) j++; // L5 120 if (crit < c[j]) c[i]=c[j]; // L6+1 G4 121 else {c[i]=crit;break;} //L8 -> G2 54 55 inline float OppositeAngle(float a){return a<0 ? fPi + a :a - fPi ;} 56 inline double OppositeAngle(double a){return a<0 ? Pi + a :a - Pi ;} 57 58 Icoor2 inline det(const I2 &a,const I2 & b,const I2 &c){ 59 register Icoor2 bax = b.x - a.x ,bay = b.y - a.y; 60 register Icoor2 cax = c.x - a.x ,cay = c.y - a.y; 61 return bax*cay - bay*cax; 62 } 63 64 //triangle numbering definitions 65 static const Int2 VerticesOfTriangularEdge[3][2] = {{1,2},{2,0},{0,1}}; 66 static const Int2 EdgesVertexTriangle[3][2] = {{1,2},{2,0},{0,1}}; 67 static const Int2 OppositeVertex[3] = {0,1,2}; 68 static const Int2 OppositeEdge[3] = {0,1,2}; 69 static const Int2 NextEdge[3] = {1,2,0}; 70 static const Int2 PreviousEdge[3] = {2,0,1}; 71 static const Int2 NextVertex[3] = {1,2,0}; 72 static const Int2 PreviousVertex[3] = {2,0,1}; 73 74 Int4 AGoodNumberPrimeWith(Int4 n); 75 76 class Geometry; 77 class Triangles; 78 class Triangle; 79 class QuadTree; 80 class GeometricalEdge; 81 class VertexOnGeom; 82 class VertexOnEdge; 83 ///////////////////////////////////////////////////////////////////////////////////// 84 const int IsVertexOnGeom = 8; 85 const int IsVertexOnVertex = 16; 86 const int IsVertexOnEdge = 32; 87 ///////////////////////////////////////////////////////////////////////////////////// 88 89 /*CLASS: DoubleAndInt4 {{{1*/ 90 class DoubleAndInt4 { 91 public: double q; Int4 i3j; 92 int operator<(DoubleAndInt4 a){return q > a.q;} 93 }; 94 /*}}}1*/ 95 /*CLASS: Direction{{{1*/ 96 class Direction { // 97 private: 98 Icoor1 dir; 99 public: 100 Direction(): dir(MaxICoor){}; // no direction set 101 Direction(Icoor1 i,Icoor1 j) { Icoor2 n2 = 2*(Abs(i)+Abs(j)); 102 Icoor2 r = MaxICoor* (Icoor2) i; 103 Icoor1 r1 = (Icoor1) (2*(r/ n2)); // odd number 104 dir = (j>0) ? r1 : r1+1; // odd -> j>0 even -> j<0 105 } 106 int sens( Icoor1 i,Icoor1 j) { int r =1; 107 if (dir!= MaxICoor) { 108 Icoor2 x(dir/2),y1(MaxICoor/2-Abs(x)),y(dir%2?-y1:y1); 109 r = (x*i + y*j) >=0;} 110 return r;} 111 }; 112 /*}}}1*/ 113 /*CLASS: Vertex{{{1*/ 114 class Vertex { 115 public: 116 I2 i; // allow to use i.x, and i.y in long int (beware of scale and centering) 117 R2 r; // allow to use r.x, and r.y in double 118 Metric m; 119 Int4 ReferenceNumber; 120 Direction DirOfSearch; 121 union { 122 Triangle * t; // one triangle which contained the vertex 123 Int4 color; 124 Vertex * to;// use in geometry Vertex to now the Mesh Vertex associed 125 VertexOnGeom * on; // if vint 8; // set with Triangles::SetVertexFieldOn() 126 Vertex * onbv; // if vint == 16 on Background vertex Triangles::SetVertexFieldOnBTh() 127 VertexOnEdge * onbe; // if vint == 32 on Background edge 128 }; 129 Int1 vint; // the vertex number in triangle; varies between 0 and 2 in t 130 operator I2 () const {return i;} // operator de cast 131 operator const R2 & () const {return r;}// operator de cast 132 // operator R2 & () {return r;}// operator de cast 133 Real8 operator()(R2 x) const { return m(x);} 134 operator Metric () const {return m;}// operator de cast 135 Int4 Optim(int = 1,int =0); 136 // Vertex(){} 137 // ~Vertex(){} 138 Real8 Smoothing(Triangles & ,const Triangles & ,Triangle * & ,Real8 =1); 139 int ref() const { return ReferenceNumber;} 140 141 inline void Set(const Vertex & rec,const Triangles &,Triangles &); 142 }; 143 /*}}}1*/ 144 inline Vertex * TheVertex(Vertex * a); // for remove crak in mesh 145 double QuadQuality(const Vertex &,const Vertex &,const Vertex &,const Vertex &); 146 /*CLASS: TriangleAdjacent{{{1*/ 147 class TriangleAdjacent { 148 149 public: 150 Triangle * t; // le triangle 151 int a; // le numero de l arete 152 153 TriangleAdjacent(Triangle * tt,int aa): t(tt),a(aa &3) {}; 154 TriangleAdjacent() {}; 155 156 operator Triangle * () const {return t;} 157 operator Triangle & () const {return *t;} 158 operator int() const {return a;} 159 TriangleAdjacent & operator++() 160 { 161 a= NextEdge[a]; 162 return *this;} 163 TriangleAdjacent operator--() 164 { 165 a= PreviousEdge[a]; 166 return *this;} 167 inline TriangleAdjacent Adj() const ; 168 int swap(); 169 inline void SetAdj2(const TriangleAdjacent& , int =0); 170 inline Vertex * EdgeVertex(const int &) const ; 171 inline Vertex * OppositeVertex() const ; 172 inline Icoor2 & det() const; 173 inline int Locked() const ; 174 inline int GetAllFlag_UnSwap() const ; 175 inline void SetLock(); 176 inline int MarkUnSwap() const; 177 inline void SetMarkUnSwap(); 178 inline void SetCracked(); 179 inline int Cracked() const ; 180 }; 181 /*}}}1*/ 182 /*CLASS: Edge{{{1*/ 183 class Edge { 184 public: 185 Vertex * v[2]; 186 Int4 ref; 187 GeometricalEdge * on; 188 Vertex & operator[](int i){return *v[i];}; 189 Vertex * operator()(int i){return v[i];}; 190 191 void ReNumbering(Vertex *vb,Vertex *ve, Int4 *renu) 192 { 193 if (v[0] >=vb && v[0] <ve) v[0] = vb + renu[v[0]-vb]; 194 if (v[1] >=vb && v[1] <ve) v[1] = vb + renu[v[1]-vb]; 195 } 196 197 const Vertex & operator[](int i) const { return *v[i];}; 198 R2 operator()(double t) const; // return the point 199 // on the curve edge a t in [0:1] 200 Edge * adj[2]; // the 2 adj edges if on the same curve 201 202 int Intersection(const Edge & e) const { 203 if (!(adj[0]==&e || adj[1]==&e)){ 204 throw ErrorException(__FUNCT__,exprintf("Intersection bug")); 205 } 206 if (adj[0]!=&e && adj[1]!=&e){ 207 throw ErrorException(__FUNCT__,exprintf("adj[0]!=&e && adj[1]!=&e")); 208 } 209 return adj[0]==&e ? 0 : 1; 210 } 211 Real8 MetricLength() const ; 212 inline void Set(const Triangles &,Int4,Triangles &); 213 214 }; 215 /*}}}1*/ 216 inline TriangleAdjacent FindTriangleAdjacent(Edge &E); 217 /*CLASS: GeometricalVertex{{{1*/ 218 class GeometricalVertex :public Vertex { 219 int cas; 220 friend class Geometry; 221 GeometricalVertex * link; // link all the same GeometricalVertex circular (Crack) 222 public: 223 int Corner() const {return cas&4;} 224 int Required()const {return cas&6;}// a corner is required 225 void SetCorner(){ cas |= 4;} 226 void SetRequired(){ cas |= 2;} 227 void Set(){cas=0;} 228 GeometricalVertex() :cas(0), link(this) {}; 229 230 GeometricalVertex * The() { 231 if (!link){ 232 throw ErrorException(__FUNCT__,exprintf("!link")); 233 } 234 return link; 235 }// return a unique vertices 236 237 int IsThe() const { return link == this;} 238 239 inline void Set(const GeometricalVertex & rec,const Geometry & Gh ,const Geometry & GhNew); 240 }; 241 /*}}}1*/ 242 /*CLASS: GeometricalEdge{{{1*/ 243 class GeometricalEdge { 244 public: 245 GeometricalVertex * v[2]; 246 Int4 ref; 247 Int4 CurveNumber; 248 R2 tg[2]; // the 2 tangente 249 // if tg[0] =0 => no continuite 250 GeometricalEdge * Adj [2]; 251 int SensAdj[2]; 252 // private: 253 int flag ; 254 public: 255 GeometricalEdge * link; // if Cracked() or Equi() 256 257 // end of data 258 259 GeometricalVertex & operator[](int i){return *v[i];}; 260 const GeometricalVertex & operator[](int i) const { return *v[i];}; 261 GeometricalVertex * operator()(int i){return v[i];}; 262 // inline void Set(const Geometry &,Int4,Geometry &); 263 264 R2 F(Real8 theta) const ; // parametrization of the curve edge 265 Real8 R1tg(Real8 theta,R2 &t) const ; // 1/radius of curvature + tangente 266 int Cracked() const {return flag & 1;} 267 int Dup() const { return flag & 32;} 268 int Equi()const {return flag & 2;} 269 int ReverseEqui()const {return flag & 128;} 270 int TgA()const {return flag &4;} 271 int TgB()const {return flag &8;} 272 int Tg(int i) const{return i==0 ? TgA() : TgB();} 273 int Mark()const {return flag &16;} 274 int Required() { return flag & 64;} 275 void SetCracked() { flag |= 1;} 276 void SetDup() { flag |= 32;} // not a real edge 277 void SetEqui() { flag |= 2;} 278 void SetTgA() { flag|=4;} 279 void SetTgB() { flag|=8;} 280 void SetMark() { flag|=16;} 281 void SetUnMark() { flag &= 1007 /* 1023-16*/;} 282 void SetRequired() { flag |= 64;} 283 void SetReverseEqui() {flag |= 128;} 284 285 inline void Set(const GeometricalEdge & rec,const Geometry & Th ,Geometry & ThNew); 286 287 }; 288 /*}}}1*/ 289 /*CLASS: Curve{{{1*/ 290 class Curve {public: 291 GeometricalEdge * be,*ee; // begin et end edge 292 int kb,ke; // begin vetex and end vertex 293 Curve *next; // next curve equi to this 294 bool master; // true => of equi curve point on this curve 295 inline void Set(const Curve & rec,const Geometry & Th ,Geometry & ThNew); 296 Curve() : be(0),ee(0),kb(0),ke(0),next(0),master(true) {} 297 void Reverse() { Exchange(be,ee); Exchange(kb,ke);} // revese the sens of the curse 298 }; 299 /*}}}1*/ 300 /*CLASS: Triangle{{{1*/ 301 class Triangle { 302 friend class TriangleAdjacent; 303 304 private: // les arete sont opposes a un sommet 305 Vertex * ns [3]; // 3 vertices if t is triangle, t[i] allowed by access function, (*t)[i] if pointer 306 Triangle * at [3]; // nu triangle adjacent 307 Int1 aa[3]; // les nu des arete dans le triangles (mod 4) 308 public: 309 Icoor2 det; // determinant du triangle (2 fois l aire des vertices entieres) 310 union { 311 Triangle * link ; 312 Int4 color; 313 }; 314 void SetDet() { 315 if(ns[0] && ns[1] && ns[2]) det = bamg::det(*ns[0],*ns[1],*ns[2]); 316 else det = -1; } 317 Triangle() {} 318 Triangle(Triangles *Th,Int4 i,Int4 j,Int4 k); 319 Triangle(Vertex *v0,Vertex *v1,Vertex *v2); 320 inline void Set(const Triangle &,const Triangles &,Triangles &); 321 inline int In(Vertex *v) const { return ns[0]==v || ns[1]==v || ns[2]==v ;} 322 TriangleAdjacent FindBoundaryEdge(int ) const; 323 324 void ReNumbering(Triangle *tb,Triangle *te, Int4 *renu) 325 { 326 if (link >=tb && link <te) link = tb + renu[link -tb]; 327 if (at[0] >=tb && at[0] <te) at[0] = tb + renu[at[0]-tb]; 328 if (at[1] >=tb && at[1] <te) at[1] = tb + renu[at[1]-tb]; 329 if (at[2] >=tb && at[2] <te) at[2] = tb + renu[at[2]-tb]; 330 } 331 void ReNumbering(Vertex *vb,Vertex *ve, Int4 *renu) 332 { 333 if (ns[0] >=vb && ns[0] <ve) ns[0] = vb + renu[ns[0]-vb]; 334 if (ns[1] >=vb && ns[1] <ve) ns[1] = vb + renu[ns[1]-vb]; 335 if (ns[2] >=vb && ns[2] <ve) ns[2] = vb + renu[ns[2]-vb]; 336 } 337 338 339 const Vertex & operator[](int i) const {return *ns[i];}; 340 Vertex & operator[](int i) {return *ns[i];}; 341 342 const Vertex * operator()(int i) const {return ns[i];}; 343 Vertex * & operator()(int i) {return ns[i];}; 344 345 TriangleAdjacent Adj(int i) const // triangle adjacent + arete 346 { return TriangleAdjacent(at[i],aa[i]&3);}; 347 348 Triangle * TriangleAdj(int i) const 349 {return at[i&3];} // triangle adjacent + arete 350 Int1 NuEdgeTriangleAdj(int i) const 351 {return aa[i&3]&3;} // Number of the adjacent edge in adj tria 352 353 inline Real4 qualite() ; 354 355 356 void SetAdjAdj(Int1 a) 357 { a &= 3; 358 register Triangle *tt=at[a]; 359 aa [a] &= 55; // remove MarkUnSwap 360 register Int1 aatt = aa[a] & 3; 361 if(tt){ 362 tt->at[aatt]=this; 363 tt->aa[aatt]=a + (aa[a] & 60 ) ;}// Copy all the mark 364 } 365 366 void SetAdj2(Int1 a,Triangle *t,Int1 aat) 367 { at[a]=t;aa[a]=aat; 368 if(t) {t->at[aat]=this;t->aa[aat]=a;} 369 } 370 371 void SetTriangleContainingTheVertex() 372 { 373 if (ns[0]) (ns[0]->t=this,ns[0]->vint=0); 374 if (ns[1]) (ns[1]->t=this,ns[1]->vint=1); 375 if (ns[2]) (ns[2]->t=this,ns[2]->vint=2); 376 } 377 378 int swap(Int2 a1,int=0); 379 Int4 Optim(Int2 a,int =0); 380 381 int Locked(int a)const { return aa[a]&4;} 382 int Hidden(int a)const { return aa[a]&16;} 383 int Cracked(int a) const { return aa[a] & 32;} 384 // for optimisation 385 int GetAllflag(int a){return aa[a] & 1020;} 386 void SetAllFlag(int a,int f){aa[a] = (aa[a] &3) + (1020 & f);} 387 388 void SetHidden(int a){ 389 register Triangle * t = at[a]; 390 if(t) t->aa[aa[a] & 3] |=16; 391 aa[a] |= 16;} 392 void SetCracked(int a){ 393 register Triangle * t = at[a]; 394 if(t) t->aa[aa[a] & 3] |=32; 395 aa[a] |= 32;} 396 397 double QualityQuad(int a,int option=1) const; 398 Triangle * Quadrangle(Vertex * & v0,Vertex * & v1,Vertex * & v2,Vertex * & v3) const ; 399 400 void SetLocked(int a){ 401 register Triangle * t = at[a]; 402 t->aa[aa[a] & 3] |=4; 403 aa[a] |= 4;} 404 405 void SetMarkUnSwap(int a){ 406 register Triangle * t = at[a]; 407 t->aa[aa[a] & 3] |=8; 408 aa[a] |=8 ;} 409 410 411 void SetUnMarkUnSwap(int a){ 412 register Triangle * t = at[a]; 413 t->aa[aa[a] & 3] &=55; // 23 + 32 414 aa[a] &=55 ;} 415 416 }; // end of Triangle class 417 /*}}}1*/ 418 /*CLASS: ListofIntersectionTriangles{{{1*/ 419 class ListofIntersectionTriangles { 420 421 class IntersectionTriangles { 422 public: 423 Triangle *t; 424 Real8 bary[3]; // use if t != 0 425 R2 x; 426 Metric m; 427 Real8 s;// abscisse curviline 428 Real8 sp; // len of the previous seg in m 429 Real8 sn;// len of the next seg in m 430 }; 431 432 class SegInterpolation { 433 public: 434 GeometricalEdge * e; 435 Real8 sBegin,sEnd; // abscisse of the seg on edge parameter 436 Real8 lBegin,lEnd; // length abscisse set in ListofIntersectionTriangles::Length 437 int last;// last index in ListofIntersectionTriangles for this Sub seg of edge 438 R2 F(Real8 s){ 439 Real8 c01=lEnd-lBegin, c0=(lEnd-s)/c01, c1=(s-lBegin)/c01; 440 if (lBegin>s || s>lEnd){ 441 throw ErrorException(__FUNCT__,exprintf("lBegin>s || s>lEnd")); 442 } 443 return e->F(sBegin*c0+sEnd*c1);} 444 }; 445 446 int MaxSize; // 447 int Size; // 448 Real8 len; // 449 int state; 450 IntersectionTriangles * lIntTria; 451 int NbSeg; 452 int MaxNbSeg; 453 SegInterpolation * lSegsI; 454 public: 455 IntersectionTriangles & operator[](int i) {return lIntTria[i];} 456 operator int&() {return Size;} 457 458 ListofIntersectionTriangles(int n=256,int m=16) 459 : MaxSize(n), Size(0), len(-1),state(-1),lIntTria(new IntersectionTriangles[n]) , 460 NbSeg(0), MaxNbSeg(m), lSegsI(new SegInterpolation[m]) 461 { 462 long int verbosity=0; 463 if (verbosity>9) printf(" construct ListofIntersectionTriangles %i %i\n",MaxSize,MaxNbSeg); 464 }; 465 466 ~ListofIntersectionTriangles(){ 467 if (lIntTria) delete [] lIntTria,lIntTria=0; 468 if (lSegsI) delete [] lSegsI,lSegsI=0;} 469 void init(){state=0;len=0;Size=0;} 470 471 int NewItem(Triangle * tt,Real8 d0,Real8 d1,Real8 d2); 472 int NewItem(R2,const Metric & ); 473 void NewSubSeg(GeometricalEdge *e,Real8 s0,Real8 s1) 474 { 475 long int verbosity=0; 476 477 if (NbSeg>=MaxNbSeg) { 478 int mneo= MaxNbSeg; 479 MaxNbSeg *= 2; 480 if (verbosity>3){ 481 printf(" reshape lSegsI from %i to %i\n",mneo,MaxNbSeg); 482 } 483 SegInterpolation * lEn = new SegInterpolation[MaxNbSeg]; 484 if (!lSegsI || NbSeg>=MaxNbSeg){ 485 throw ErrorException(__FUNCT__,exprintf("!lSegsI || NbSeg>=MaxNbSeg")); 486 } 487 for (int i=0;i< NbSeg;i++) 488 lEn[i] = lSegsI[MaxNbSeg]; // copy old to new 489 delete [] lSegsI; // remove old 490 lSegsI = lEn; 491 } 492 if (NbSeg) 493 lSegsI[NbSeg-1].last=Size; 494 lSegsI[NbSeg].e=e; 495 lSegsI[NbSeg].sBegin=s0; 496 lSegsI[NbSeg].sEnd=s1; 497 NbSeg++; 498 } 499 500 // void CopyMetric(int i,int j){ lIntTria[j].m=lIntTria[i].m;} 501 // void CopyMetric(const Metric & mm,int j){ lIntTria[j].m=mm;} 502 503 void ReShape() { 504 register int newsize = MaxSize*2; 505 IntersectionTriangles* nw = new IntersectionTriangles[newsize]; 506 if (!nw){ 507 throw ErrorException(__FUNCT__,exprintf("!nw")); 508 } 509 for (int i=0;i<MaxSize;i++) // recopy 510 nw[i] = lIntTria[i]; 511 long int verbosity=0; 512 if(verbosity>3) printf(" ListofIntersectionTriangles ReShape Maxsize %i -> %i\n",MaxSize,MaxNbSeg); 513 MaxSize = newsize; 514 delete [] lIntTria;// remove old 515 lIntTria = nw; // copy pointer 516 } 517 518 void SplitEdge(const Triangles & ,const R2 &,const R2 &,int nbegin=0); 519 Real8 Length(); 520 Int4 NewPoints(Vertex *,Int4 & nbv,Int4 nbvx); 521 }; 522 /*}}}1*/ 523 /*CLASS: GeometricalSubDomain{{{1*/ 524 class GeometricalSubDomain { 525 public: 526 GeometricalEdge *edge; 527 int sens; // -1 or 1 528 Int4 ref; 529 inline void Set(const GeometricalSubDomain &,const Geometry & ,const Geometry &); 530 531 }; 532 /*}}}1*/ 533 /*CLASS: SubDomain{{{1*/ 534 class SubDomain { 535 public: 536 Triangle * head; 537 Int4 ref; 538 int sens; // -1 or 1 539 Edge * edge; // to geometrical 540 inline void Set(const Triangles &,Int4,Triangles &); 541 542 }; 543 /*}}}1*/ 544 /*CLASS: VertexOnGeom{{{1*/ 545 class VertexOnGeom{ 546 public: 547 548 Vertex * mv; 549 Real8 abscisse; 550 union{ 551 GeometricalVertex * gv; // if abscisse <0; 552 GeometricalEdge * ge; // if abscisse in [0..1] 553 }; 554 inline void Set(const VertexOnGeom&,const Triangles &,Triangles &); 555 int OnGeomVertex()const {return this? abscisse <0 :0;} 556 int OnGeomEdge() const {return this? abscisse >=0 :0;} 557 VertexOnGeom(): mv(0),abscisse(0){gv=0;} 558 VertexOnGeom(Vertex & m,GeometricalVertex &g) : mv(&m),abscisse(-1){gv=&g;} 559 VertexOnGeom(Vertex & m,GeometricalEdge &g,Real8 s) : mv(&m),abscisse(s){ge=&g;} 560 operator Vertex * () const {return mv;} 561 operator GeometricalVertex * () const {return gv;} 562 operator GeometricalEdge * () const {return ge;} 563 operator const Real8 & () const {return abscisse;} 564 int IsRequiredVertex(){ return this? (( abscisse<0 ? (gv?gv->Required():0):0 )) : 0;} 565 void SetOn(){mv->on=this;mv->vint=IsVertexOnGeom;} 566 inline void Set(const Triangles &,Int4,Triangles &); 567 568 }; 569 /*}}}1*/ 570 /*CLASS: VertexOnVertex{{{1*/ 571 class VertexOnVertex { 572 public: 573 Vertex * v, *bv; 574 VertexOnVertex(Vertex * w,Vertex *bw) :v(w),bv(bw){} 575 VertexOnVertex() {}; 576 inline void Set(const Triangles &,Int4,Triangles &); 577 void SetOnBTh(){v->onbv=bv;v->vint=IsVertexOnVertex;} 578 }; 579 /*}}}1*/ 580 /*CLASS: VertexOnEdge{{{1*/ 581 class VertexOnEdge { 582 public: 583 Vertex * v; 584 Edge * be; 585 Real8 abcisse; 586 VertexOnEdge( Vertex * w, Edge *bw,Real8 s) :v(w),be(bw),abcisse(s) {} 587 VertexOnEdge(){} 588 inline void Set(const Triangles &,Int4,Triangles &); 589 void SetOnBTh(){v->onbe=this;v->vint=IsVertexOnEdge;} 590 Vertex & operator[](int i) const { return (*be)[i];} 591 operator Real8 () const { return abcisse;} 592 operator Vertex * () const { return v;} 593 operator Edge * () const { return be;} 594 }; 595 /*}}}1*/ 596 /*CLASS: CrackedEdge{{{1*/ 597 class CrackedEdge { 598 friend class Triangles; 599 600 class CrackedTriangle { 601 friend class Triangles; 602 friend class CrackedEdge; 603 Triangle * t; // edge of triangle t 604 int i; // edge number of in triangle 605 Edge *edge; // the 2 edge 606 Vertex *New[2]; // new vertex number 607 CrackedTriangle() : t(0),i(0),edge(0) { New[0]=New[1]=0;} 608 CrackedTriangle(Edge * a) : t(0),i(0),edge(a) { New[0]=New[1]=0;} 609 void Crack(){ 610 Triangle & T(*t); 611 int i0=VerticesOfTriangularEdge[i][0]; 612 int i1=VerticesOfTriangularEdge[i][0]; 613 if (!New[0] && !New[1]){ 614 throw ErrorException(__FUNCT__,exprintf("!New[0] && !New[1]")); 615 } 616 T(i0) = New[0]; 617 T(i1) = New[1];} 618 void UnCrack(){ 619 Triangle & T(*t); 620 int i0=VerticesOfTriangularEdge[i][0]; 621 int i1=VerticesOfTriangularEdge[i][0]; 622 if (!New[0] && !New[1]){ 623 throw ErrorException(__FUNCT__,exprintf("!New[0] && !New[1]")); 624 } 625 T(i0) = TheVertex(T(i0)); 626 T(i1) = TheVertex(T(i1));} 627 void Set() { 628 TriangleAdjacent ta ( FindTriangleAdjacent(*edge)); 629 t = ta; 630 i = ta; 631 632 New[0] = ta.EdgeVertex(0); 633 New[1] = ta.EdgeVertex(1); 634 // warning the ref 635 } 636 }; 637 638 public: 639 CrackedTriangle a,b; 640 CrackedEdge() :a(),b() {} 641 CrackedEdge(Edge * start, Int4 i,Int4 j) : a(start+i),b(start+j) {}; 642 CrackedEdge(Edge * e0, Edge * e1 ) : a(e0),b(e1) {}; 643 644 void Crack() { a.Crack(); b.Crack();} 645 void UnCrack() { a.UnCrack(); b.UnCrack();} 646 void Set() { a.Set(), b.Set();} 647 }; 648 /*}}}1*/ 649 /*CLASS: Triangles{{{1*/ 650 class Triangles { 651 public: 652 653 enum TypeFileMesh { 654 AutoMesh=0,BDMesh=1,NOPOMesh=2,amMesh=3,am_fmtMesh=4,amdbaMesh=5, 655 ftqMesh=6,mshMesh=7}; 656 657 int static counter; // to kown the number of mesh in memory 658 int OnDisk; // true if on disk 659 Geometry & Gh; // Geometry 660 Triangles & BTh; // Background Mesh Bth==*this =>no background 661 662 Int4 NbRef; // counter of ref on the this class if 0 we can delete 663 Int4 nbvx,nbtx; // nombre max de sommets , de triangles 664 665 Int4 nt,nbv,nbt,nbiv,nbe; // nb of legal triangles, nb of vertex, of triangles, 666 // of initial vertices, of edges with reference, 667 Int4 NbOfQuad; // nb of quadrangle 668 669 Int4 NbSubDomains; // 670 Int4 NbOutT; // Nb of oudeside triangle 671 Int4 NbOfTriangleSearchFind; 672 Int4 NbOfSwapTriangle; 673 char * name, *identity; 674 Vertex * vertices; // data of vertices des sommets 675 676 Int4 NbVerticesOnGeomVertex; 677 VertexOnGeom * VerticesOnGeomVertex; 678 679 Int4 NbVerticesOnGeomEdge; 680 VertexOnGeom * VerticesOnGeomEdge; 681 682 Int4 NbVertexOnBThVertex; 683 VertexOnVertex *VertexOnBThVertex; 684 685 Int4 NbVertexOnBThEdge; 686 VertexOnEdge *VertexOnBThEdge; 687 688 689 Int4 NbCrackedVertices; 690 691 692 Int4 NbCrackedEdges; 693 CrackedEdge *CrackedEdges; 694 695 696 R2 pmin,pmax; // extrema 697 Real8 coefIcoor; // coef to integer Icoor1; 698 699 Triangle * triangles; 700 Edge * edges; 701 702 QuadTree *quadtree; 703 Vertex ** ordre; 704 SubDomain * subdomains; 705 ListofIntersectionTriangles lIntTria; 706 // end of variable 707 708 Triangles(Int4 i);//:BTh(*this),Gh(*new Geometry()){PreInit(i);} 709 710 711 ~Triangles(); 712 Triangles(const char * ,Real8=-1) ; 713 Triangles(BamgMesh* bamgmesh,BamgOpts* bamgopts); 714 715 Triangles(Int4 nbvx,Triangles & BT,int keepBackVertices=1) 716 :Gh(BT.Gh),BTh(BT) { 717 try {GeomToTriangles1(nbvx,keepBackVertices);} 718 catch(...) { this->~Triangles(); throw; } } 719 720 Triangles(Int4 nbvx,Geometry & G) 721 :Gh(G),BTh(*this){ 722 try { GeomToTriangles0(nbvx);} 723 catch(...) { this->~Triangles(); throw; } } 724 Triangles(Triangles &,Geometry * pGh=0,Triangles* pBTh=0,Int4 nbvxx=0 ); // COPY OPERATEUR 725 Triangles(const Triangles &,const int *flag,const int *bb); // truncature 726 727 void SetIntCoor(const char * from =0); 728 729 // void RandomInit(); 730 // void CubeInit(int ,int); 731 732 Real8 MinimalHmin() {return 2.0/coefIcoor;} 733 Real8 MaximalHmax() {return Max(pmax.x-pmin.x,pmax.y-pmin.y);} 734 const Vertex & operator[] (Int4 i) const { return vertices[i];}; 735 Vertex & operator[](Int4 i) { return vertices[i];}; 736 const Triangle & operator() (Int4 i) const { return triangles[i];}; 737 Triangle & operator()(Int4 i) { return triangles[i];}; 738 I2 toI2(const R2 & P) const { 739 return I2( (Icoor1) (coefIcoor*(P.x-pmin.x)) 740 ,(Icoor1) (coefIcoor*(P.y-pmin.y)) );} 741 R2 toR2(const I2 & P) const { 742 return R2( (double) P.x/coefIcoor+pmin.x, (double) P.y/coefIcoor+pmin.y);} 743 void Add( Vertex & s,Triangle * t,Icoor2 * =0) ; 744 void Insert(); 745 // void InsertOld(); 746 void ForceBoundary(); 747 void Heap(); 748 void FindSubDomain(int ); 749 Int4 ConsRefTriangle(Int4 *) const; 750 void ShowHistogram() const; 751 void ShowRegulaty() const; // Add FH avril 2007 752 // void ConsLinkTriangle(); 753 754 void ReMakeTriangleContainingTheVertex(); 755 void UnMarkUnSwapTriangle(); 756 void SmoothMetric(Real8 raisonmax) ; 757 void BoundAnisotropy(Real8 anisomax,double hminaniso= 1e-100) ; 758 void MaxSubDivision(Real8 maxsubdiv); 759 Edge** MakeGeometricalEdgeToEdge(); 760 void SetVertexFieldOn(); 761 void SetVertexFieldOnBTh(); 762 Int4 SplitInternalEdgeWithBorderVertices(); 763 void MakeQuadrangles(double costheta); 764 int SplitElement(int choice); 765 void MakeQuadTree(); 766 void NewPoints( Triangles &,int KeepBackVertex =1 ); 767 Int4 InsertNewPoints(Int4 nbvold,Int4 & NbTSwap) ; 768 void NewPoints(int KeepBackVertex=1){ NewPoints(*this,KeepBackVertex);} 769 void ReNumberingTheTriangleBySubDomain(bool justcompress=false); 770 void ReNumberingVertex(Int4 * renu); 771 void SmoothingVertex(int =3,Real8=0.3); 772 Metric MetricAt (const R2 &) const; 773 GeometricalEdge * ProjectOnCurve( Edge & AB, Vertex & A, Vertex & B,Real8 theta, 774 Vertex & R,VertexOnEdge & BR,VertexOnGeom & GR); 775 776 Int4 Number(const Triangle & t) const { return &t - triangles;} 777 Int4 Number(const Triangle * t) const { return t - triangles;} 778 Int4 Number(const Vertex & t) const { return &t - vertices;} 779 Int4 Number(const Vertex * t) const { return t - vertices;} 780 Int4 Number(const Edge & t) const { return &t - edges;} 781 Int4 Number(const Edge * t) const { return t - edges;} 782 Int4 Number2(const Triangle * t) const { 783 // if(t>= triangles && t < triangles + nbt ) 784 return t - triangles; 785 // else return t - OutSidesTriangles; 786 } 787 788 Vertex * NearestVertex(Icoor1 i,Icoor1 j) ; 789 Triangle * FindTriangleContening(const I2 & ,Icoor2 [3],Triangle *tstart=0) const; 790 791 void ReadMesh(BamgMesh* bamgmesh, BamgOpts* bamgopts); 792 void WriteMesh(BamgMesh* bamgmesh,BamgOpts* bamgopts); 793 794 void ReadMetric(BamgOpts* bamgopts,const Real8 hmin,const Real8 hmax,const Real8 coef); 795 void WriteMetric(BamgOpts* bamgopts); 796 void IntersectConsMetric(const double * s,const Int4 nbsol,const int * typsols, 797 const Real8 hmin,const Real8 hmax, const Real8 coef, 798 const Real8 anisomax,const Real8 CutOff=1.e-4,const int NbJacobi=1, 799 const int DoNormalisation=1, 800 const double power=1.0, 801 const int choise=0); 802 void IntersectGeomMetric(const Real8 err,const int iso); 803 804 805 int isCracked() const {return NbCrackedVertices != 0;} 806 int Crack(); 807 int UnCrack(); 808 809 void ConsGeometry(Real8 =-1.0,int *equiedges=0); // construct a geometry if no geo 810 void FillHoleInMesh() ; 811 int CrackMesh(); 812 private: 813 void GeomToTriangles1(Int4 nbvx,int KeepBackVertices=1);// the real constructor mesh adaption 814 void GeomToTriangles0(Int4 nbvx);// the real constructor mesh generator 815 void PreInit(Int4,char * =0 ); 816 817 }; 818 /*}}}1*/ 819 /*CLASS: Geometry{{{1*/ 820 class Geometry { 821 public: 822 int OnDisk; 823 Int4 NbRef; // counter of ref on the this class if 0 we can delete 824 825 char *name; 826 Int4 nbvx,nbtx; // nombre max de sommets , de Geometry 827 Int4 nbv,nbt,nbiv,nbe; // nombre de sommets, de Geometry, de sommets initiaux, 828 Int4 NbSubDomains; // 829 Int4 NbEquiEdges; 830 Int4 NbCrackedEdges; 831 // Int4 nbtf;// de triangle frontiere 832 Int4 NbOfCurves; 833 int empty(){return (nbv ==0) && (nbt==0) && (nbe==0) && (NbSubDomains==0); } 834 GeometricalVertex * vertices; // data of vertices des sommets 835 Triangle * triangles; 836 GeometricalEdge * edges; 837 QuadTree *quadtree; 838 GeometricalSubDomain *subdomains; 839 Curve *curves; 840 ~Geometry(); 841 Geometry(const Geometry & Gh); //Copy Operator 842 Geometry(int nbg,const Geometry ** ag); // intersection operator 843 844 R2 pmin,pmax; // extrema 845 Real8 coefIcoor; // coef to integer Icoor1; 846 Real8 MaximalAngleOfCorner; 847 848 // end of data 849 850 851 I2 toI2(const R2 & P) const { 852 return I2( (Icoor1) (coefIcoor*(P.x-pmin.x)) 853 ,(Icoor1) (coefIcoor*(P.y-pmin.y)) );} 854 855 Real8 MinimalHmin() {return 2.0/coefIcoor;} 856 Real8 MaximalHmax() {return Max(pmax.x-pmin.x,pmax.y-pmin.y);} 857 void ReadGeometry(BamgGeom* bamggeom, BamgOpts* bamgopts); 858 void EmptyGeometry(); 859 Geometry() {EmptyGeometry();}// empty Geometry 860 void AfterRead(); 861 Geometry(BamgGeom* bamggeom, BamgOpts* bamgopts) {EmptyGeometry();OnDisk=1;ReadGeometry(bamggeom,bamgopts);AfterRead();} 862 863 const GeometricalVertex & operator[] (Int4 i) const { return vertices[i];}; 864 GeometricalVertex & operator[](Int4 i) { return vertices[i];}; 865 const GeometricalEdge & operator() (Int4 i) const { return edges[i];}; 866 GeometricalEdge & operator()(Int4 i) { return edges[i];}; 867 Int4 Number(const GeometricalVertex & t) const { return &t - vertices;} 868 Int4 Number(const GeometricalVertex * t) const { return t - vertices;} 869 Int4 Number(const GeometricalEdge & t) const { return &t - edges;} 870 Int4 Number(const GeometricalEdge * t) const { return t - edges;} 871 Int4 Number(const Curve * c) const { return c - curves;} 872 873 void UnMarkEdges() { 874 for (Int4 i=0;i<nbe;i++) edges[i].SetUnMark();} 875 876 GeometricalEdge * ProjectOnCurve(const Edge & ,Real8,Vertex &,VertexOnGeom &) const ; 877 GeometricalEdge * Contening(const R2 P, GeometricalEdge * start) const; 878 void WriteGeometry(BamgGeom* bamggeom, BamgOpts* bamgopts); 879 }; 880 /*}}}1*/ 881 882 // to sort in descending order 883 template<class T> inline void HeapSort(T *c,long n){ 884 long l,j,r,i; 885 T crit; 886 c--; // on decale de 1 pour que le tableau commence a 1 887 if( n <= 1) return; 888 l = n/2 + 1; 889 r = n; 890 while (1) { // label 2 891 if(l <= 1 ) { // label 20 892 crit = c[r]; 893 c[r--] = c[1]; 894 if ( r == 1 ) { c[1]=crit; return;} 895 } else crit = c[--l]; 896 j=l; 897 while (1) {// label 4 898 i=j; 899 j=2*j; 900 if (j>r) {c[i]=crit;break;} // L8 -> G2 901 if ((j<r) && (c[j] < c[j+1])) j++; // L5 902 if (crit < c[j]) c[i]=c[j]; // L6+1 G4 903 else {c[i]=crit;break;} //L8 -> G2 904 } 122 905 } 123 906 } 124 } 125 //End from MeshGeom 126 127 128 class Direction { // 129 private: 130 Icoor1 dir; 131 public: 132 Direction(): dir(MaxICoor){}; // no direction set 133 Direction(Icoor1 i,Icoor1 j) { Icoor2 n2 = 2*(Abs(i)+Abs(j)); 134 Icoor2 r = MaxICoor* (Icoor2) i; 135 Icoor1 r1 = (Icoor1) (2*(r/ n2)); // odd number 136 dir = (j>0) ? r1 : r1+1; // odd -> j>0 even -> j<0 137 } 138 int sens( Icoor1 i,Icoor1 j) { int r =1; 139 if (dir!= MaxICoor) { 140 Icoor2 x(dir/2),y1(MaxICoor/2-Abs(x)),y(dir%2?-y1:y1); 141 r = (x*i + y*j) >=0;} 142 return r;} 143 }; 144 ///////////////////////////////////////////////////////////////////////////////////// 145 class Vertex {public: 146 I2 i; // allow to use i.x, and i.y in long int (beware of scale and centering) 147 R2 r; // allow to use r.x, and r.y in double 148 Metric m; 149 Int4 ReferenceNumber; 150 Direction DirOfSearch; 151 union { 152 Triangle * t; // one triangle which contained the vertex 153 Int4 color; 154 Vertex * to;// use in geometry Vertex to now the Mesh Vertex associed 155 VertexOnGeom * on; // if vint 8; // set with Triangles::SetVertexFieldOn() 156 Vertex * onbv; // if vint == 16 on Background vertex Triangles::SetVertexFieldOnBTh() 157 VertexOnEdge * onbe; // if vint == 32 on Background edge 158 }; 159 Int1 vint; // the vertex number in triangle; varies between 0 and 2 in t 160 operator I2 () const {return i;} // operator de cast 161 operator const R2 & () const {return r;}// operator de cast 162 // operator R2 & () {return r;}// operator de cast 163 Real8 operator()(R2 x) const { return m(x);} 164 operator Metric () const {return m;}// operator de cast 165 Int4 Optim(int = 1,int =0); 166 // Vertex(){} 167 // ~Vertex(){} 168 Real8 Smoothing(Triangles & ,const Triangles & ,Triangle * & ,Real8 =1); 169 int ref() const { return ReferenceNumber;} 170 171 inline void Set(const Vertex & rec,const Triangles &,Triangles &); 172 }; 173 174 double QuadQuality(const Vertex &,const Vertex &,const Vertex &,const Vertex &); 175 176 // extern Vertex *Meshend , *Meshbegin; 177 178 ///////////////////////////////////////////////////////////////////////////////////// 179 class TriangleAdjacent { 180 181 public: 182 Triangle * t; // le triangle 183 int a; // le numero de l arete 184 185 TriangleAdjacent(Triangle * tt,int aa): t(tt),a(aa &3) {}; 186 TriangleAdjacent() {}; 187 188 operator Triangle * () const {return t;} 189 operator Triangle & () const {return *t;} 190 operator int() const {return a;} 191 TriangleAdjacent & operator++() 192 { 193 a= NextEdge[a]; 194 return *this;} 195 TriangleAdjacent operator--() 196 { 197 a= PreviousEdge[a]; 198 return *this;} 199 inline TriangleAdjacent Adj() const ; 200 int swap(); 201 inline void SetAdj2(const TriangleAdjacent& , int =0); 202 inline Vertex * EdgeVertex(const int &) const ; 203 inline Vertex * OppositeVertex() const ; 204 inline Icoor2 & det() const; 205 inline int Locked() const ; 206 inline int GetAllFlag_UnSwap() const ; 207 inline void SetLock(); 208 inline int MarkUnSwap() const; 209 inline void SetMarkUnSwap(); 210 inline void SetCracked(); 211 inline int Cracked() const ; 212 };// end of Vertex class 213 214 215 ///////////////////////////////////////////////////////////////////////////////////// 216 class Edge { public: 217 Vertex * v[2]; 218 Int4 ref; 219 GeometricalEdge * on; 220 Vertex & operator[](int i){return *v[i];}; 221 Vertex * operator()(int i){return v[i];}; 222 223 void ReNumbering(Vertex *vb,Vertex *ve, Int4 *renu) 224 { 225 if (v[0] >=vb && v[0] <ve) v[0] = vb + renu[v[0]-vb]; 226 if (v[1] >=vb && v[1] <ve) v[1] = vb + renu[v[1]-vb]; 227 } 228 229 const Vertex & operator[](int i) const { return *v[i];}; 230 R2 operator()(double t) const; // return the point 231 // on the curve edge a t in [0:1] 232 Edge * adj[2]; // the 2 adj edges if on the same curve 233 234 int Intersection(const Edge & e) const { 235 if (!(adj[0]==&e || adj[1]==&e)){ 236 throw ErrorException(__FUNCT__,exprintf("Intersection bug")); 237 } 238 if (adj[0]!=&e && adj[1]!=&e){ 239 throw ErrorException(__FUNCT__,exprintf("adj[0]!=&e && adj[1]!=&e")); 240 } 241 return adj[0]==&e ? 0 : 1; 242 } 243 Real8 MetricLength() const ; 244 inline void Set(const Triangles &,Int4,Triangles &); 245 246 }; // end of Edge class 247 248 ///////////////////////////////////////////////////////////////////////////////////// 249 class GeometricalVertex :public Vertex { 250 int cas; 251 friend class Geometry; 252 GeometricalVertex * link; // link all the same GeometricalVertex circular (Crack) 253 public: 254 int Corner() const {return cas&4;} 255 int Required()const {return cas&6;}// a corner is required 256 void SetCorner(){ cas |= 4;} 257 void SetRequired(){ cas |= 2;} 258 void Set(){cas=0;} 259 GeometricalVertex() :cas(0), link(this) {}; 260 261 GeometricalVertex * The() { 262 if (!link){ 263 throw ErrorException(__FUNCT__,exprintf("!link")); 264 } 265 return link; 266 }// return a unique vertices 267 268 int IsThe() const { return link == this;} 269 270 inline void Set(const GeometricalVertex & rec,const Geometry & Gh ,const Geometry & GhNew); 271 }; 272 273 ///////////////////////////////////////////////////////////////////////////////////// 274 class GeometricalEdge { 275 public: 276 GeometricalVertex * v[2]; 277 Int4 ref; 278 Int4 CurveNumber; 279 R2 tg[2]; // the 2 tangente 280 // if tg[0] =0 => no continuite 281 GeometricalEdge * Adj [2]; 282 int SensAdj[2]; 283 // private: 284 int flag ; 285 public: 286 GeometricalEdge * link; // if Cracked() or Equi() 287 288 // end of data 289 290 GeometricalVertex & operator[](int i){return *v[i];}; 291 const GeometricalVertex & operator[](int i) const { return *v[i];}; 292 GeometricalVertex * operator()(int i){return v[i];}; 293 // inline void Set(const Geometry &,Int4,Geometry &); 294 295 R2 F(Real8 theta) const ; // parametrization of the curve edge 296 Real8 R1tg(Real8 theta,R2 &t) const ; // 1/radius of curvature + tangente 297 int Cracked() const {return flag & 1;} 298 int Dup() const { return flag & 32;} 299 int Equi()const {return flag & 2;} 300 int ReverseEqui()const {return flag & 128;} 301 int TgA()const {return flag &4;} 302 int TgB()const {return flag &8;} 303 int Tg(int i) const{return i==0 ? TgA() : TgB();} 304 int Mark()const {return flag &16;} 305 int Required() { return flag & 64;} 306 void SetCracked() { flag |= 1;} 307 void SetDup() { flag |= 32;} // not a real edge 308 void SetEqui() { flag |= 2;} 309 void SetTgA() { flag|=4;} 310 void SetTgB() { flag|=8;} 311 void SetMark() { flag|=16;} 312 void SetUnMark() { flag &= 1007 /* 1023-16*/;} 313 void SetRequired() { flag |= 64;} 314 void SetReverseEqui() {flag |= 128;} 315 316 inline void Set(const GeometricalEdge & rec,const Geometry & Th ,Geometry & ThNew); 317 318 }; 319 320 class Curve {public: 321 GeometricalEdge * be,*ee; // begin et end edge 322 int kb,ke; // begin vetex and end vertex 323 Curve *next; // next curve equi to this 324 bool master; // true => of equi curve point on this curve 325 inline void Set(const Curve & rec,const Geometry & Th ,Geometry & ThNew); 326 Curve() : be(0),ee(0),kb(0),ke(0),next(0),master(true) {} 327 void Reverse() { Exchange(be,ee); Exchange(kb,ke);} // revese the sens of the curse 328 }; 329 330 331 332 ///////////////////////////////////////////////////////////////////////////////////// 333 class Triangle { 334 friend class TriangleAdjacent; 335 336 337 private: // les arete sont opposes a un sommet 338 Vertex * ns [3]; // 3 vertices if t is triangle, t[i] allowed by access function, (*t)[i] if pointer 339 Triangle * at [3]; // nu triangle adjacent 340 Int1 aa[3]; // les nu des arete dans le triangles (mod 4) 341 public: 342 Icoor2 det; // determinant du triangle (2 fois l aire des vertices entieres) 343 union { 344 Triangle * link ; 345 Int4 color; 346 }; 347 void SetDet() { 348 if(ns[0] && ns[1] && ns[2]) det = bamg::det(*ns[0],*ns[1],*ns[2]); 349 else det = -1; } 350 Triangle() {} 351 Triangle(Triangles *Th,Int4 i,Int4 j,Int4 k); 352 Triangle(Vertex *v0,Vertex *v1,Vertex *v2); 353 inline void Set(const Triangle &,const Triangles &,Triangles &); 354 inline int In(Vertex *v) const { return ns[0]==v || ns[1]==v || ns[2]==v ;} 355 TriangleAdjacent FindBoundaryEdge(int ) const; 356 357 void ReNumbering(Triangle *tb,Triangle *te, Int4 *renu) 358 { 359 if (link >=tb && link <te) link = tb + renu[link -tb]; 360 if (at[0] >=tb && at[0] <te) at[0] = tb + renu[at[0]-tb]; 361 if (at[1] >=tb && at[1] <te) at[1] = tb + renu[at[1]-tb]; 362 if (at[2] >=tb && at[2] <te) at[2] = tb + renu[at[2]-tb]; 363 } 364 void ReNumbering(Vertex *vb,Vertex *ve, Int4 *renu) 365 { 366 if (ns[0] >=vb && ns[0] <ve) ns[0] = vb + renu[ns[0]-vb]; 367 if (ns[1] >=vb && ns[1] <ve) ns[1] = vb + renu[ns[1]-vb]; 368 if (ns[2] >=vb && ns[2] <ve) ns[2] = vb + renu[ns[2]-vb]; 369 } 370 371 372 const Vertex & operator[](int i) const {return *ns[i];}; 373 Vertex & operator[](int i) {return *ns[i];}; 374 375 const Vertex * operator()(int i) const {return ns[i];}; 376 Vertex * & operator()(int i) {return ns[i];}; 377 378 TriangleAdjacent Adj(int i) const // triangle adjacent + arete 379 { return TriangleAdjacent(at[i],aa[i]&3);}; 380 381 Triangle * TriangleAdj(int i) const 382 {return at[i&3];} // triangle adjacent + arete 383 Int1 NuEdgeTriangleAdj(int i) const 384 {return aa[i&3]&3;} // Number of the adjacent edge in adj tria 385 386 inline Real4 qualite() ; 387 388 389 void SetAdjAdj(Int1 a) 390 { a &= 3; 391 register Triangle *tt=at[a]; 392 aa [a] &= 55; // remove MarkUnSwap 393 register Int1 aatt = aa[a] & 3; 394 if(tt){ 395 tt->at[aatt]=this; 396 tt->aa[aatt]=a + (aa[a] & 60 ) ;}// Copy all the mark 397 } 398 399 void SetAdj2(Int1 a,Triangle *t,Int1 aat) 400 { at[a]=t;aa[a]=aat; 401 if(t) {t->at[aat]=this;t->aa[aat]=a;} 402 } 403 404 void SetTriangleContainingTheVertex() 405 { 406 if (ns[0]) (ns[0]->t=this,ns[0]->vint=0); 407 if (ns[1]) (ns[1]->t=this,ns[1]->vint=1); 408 if (ns[2]) (ns[2]->t=this,ns[2]->vint=2); 409 } 410 411 int swap(Int2 a1,int=0); 412 Int4 Optim(Int2 a,int =0); 413 414 int Locked(int a)const { return aa[a]&4;} 415 int Hidden(int a)const { return aa[a]&16;} 416 int Cracked(int a) const { return aa[a] & 32;} 417 // for optimisation 418 int GetAllflag(int a){return aa[a] & 1020;} 419 void SetAllFlag(int a,int f){aa[a] = (aa[a] &3) + (1020 & f);} 420 421 void SetHidden(int a){ 422 register Triangle * t = at[a]; 423 if(t) t->aa[aa[a] & 3] |=16; 424 aa[a] |= 16;} 425 void SetCracked(int a){ 426 register Triangle * t = at[a]; 427 if(t) t->aa[aa[a] & 3] |=32; 428 aa[a] |= 32;} 429 430 double QualityQuad(int a,int option=1) const; 431 Triangle * Quadrangle(Vertex * & v0,Vertex * & v1,Vertex * & v2,Vertex * & v3) const ; 432 433 void SetLocked(int a){ 434 register Triangle * t = at[a]; 435 t->aa[aa[a] & 3] |=4; 436 aa[a] |= 4;} 437 438 void SetMarkUnSwap(int a){ 439 register Triangle * t = at[a]; 440 t->aa[aa[a] & 3] |=8; 441 aa[a] |=8 ;} 442 443 444 void SetUnMarkUnSwap(int a){ 445 register Triangle * t = at[a]; 446 t->aa[aa[a] & 3] &=55; // 23 + 32 447 aa[a] &=55 ;} 448 449 }; // end of Triangle class 450 451 452 453 454 class ListofIntersectionTriangles { 455 ///////////////////////////////////////////////////////////////////////////////////// 456 class IntersectionTriangles { 457 public: 458 Triangle *t; 459 Real8 bary[3]; // use if t != 0 460 R2 x; 461 Metric m; 462 Real8 s;// abscisse curviline 463 Real8 sp; // len of the previous seg in m 464 Real8 sn;// len of the next seg in m 465 }; 466 ///////////////////////////////////////////////////////////////////////////////////// 467 class SegInterpolation { 468 public: 469 GeometricalEdge * e; 470 Real8 sBegin,sEnd; // abscisse of the seg on edge parameter 471 Real8 lBegin,lEnd; // length abscisse set in ListofIntersectionTriangles::Length 472 int last;// last index in ListofIntersectionTriangles for this Sub seg of edge 473 R2 F(Real8 s){ 474 Real8 c01=lEnd-lBegin, c0=(lEnd-s)/c01, c1=(s-lBegin)/c01; 475 if (lBegin>s || s>lEnd){ 476 throw ErrorException(__FUNCT__,exprintf("lBegin>s || s>lEnd")); 477 } 478 return e->F(sBegin*c0+sEnd*c1);} 479 }; 480 481 int MaxSize; // 482 int Size; // 483 Real8 len; // 484 int state; 485 IntersectionTriangles * lIntTria; 486 int NbSeg; 487 int MaxNbSeg; 488 SegInterpolation * lSegsI; 489 public: 490 IntersectionTriangles & operator[](int i) {return lIntTria[i];} 491 operator int&() {return Size;} 492 493 ListofIntersectionTriangles(int n=256,int m=16) 494 : MaxSize(n), Size(0), len(-1),state(-1),lIntTria(new IntersectionTriangles[n]) , 495 NbSeg(0), MaxNbSeg(m), lSegsI(new SegInterpolation[m]) 496 { 497 long int verbosity=0; 498 if (verbosity>9) printf(" construct ListofIntersectionTriangles %i %i\n",MaxSize,MaxNbSeg); 499 }; 500 501 ~ListofIntersectionTriangles(){ 502 if (lIntTria) delete [] lIntTria,lIntTria=0; 503 if (lSegsI) delete [] lSegsI,lSegsI=0;} 504 void init(){state=0;len=0;Size=0;} 505 506 int NewItem(Triangle * tt,Real8 d0,Real8 d1,Real8 d2); 507 int NewItem(R2,const Metric & ); 508 void NewSubSeg(GeometricalEdge *e,Real8 s0,Real8 s1) 509 { 510 long int verbosity=0; 511 512 if (NbSeg>=MaxNbSeg) { 513 int mneo= MaxNbSeg; 514 MaxNbSeg *= 2; 515 if (verbosity>3){ 516 printf(" reshape lSegsI from %i to %i\n",mneo,MaxNbSeg); 517 } 518 SegInterpolation * lEn = new SegInterpolation[MaxNbSeg]; 519 if (!lSegsI || NbSeg>=MaxNbSeg){ 520 throw ErrorException(__FUNCT__,exprintf("!lSegsI || NbSeg>=MaxNbSeg")); 907 908 //From Metric.cpp 909 inline Real8 det3x3(Real8 A[3] ,Real8 B[3],Real8 C[3]) 910 { return A[0] * ( B[1]*C[2]-B[2]*C[1]) 911 - A[1] * ( B[0]*C[2]-B[2]*C[0]) 912 + A[2] * ( B[0]*C[1]-B[1]*C[0]); 913 } 914 915 inline Triangles::Triangles(Int4 i) :Gh(*new Geometry()),BTh(*this){PreInit(i);} 916 917 TriangleAdjacent CloseBoundaryEdge(I2 ,Triangle *, double &,double &) ; 918 TriangleAdjacent CloseBoundaryEdgeV2(I2 A,Triangle *t, double &a,double &b); 919 920 Int4 FindTriangle(Triangles &Th, Real8 x, Real8 y, double* a,int & inside); 921 922 inline Triangle* Triangle::Quadrangle(Vertex * & v0,Vertex * & v1,Vertex * & v2,Vertex * & v3) const 923 { 924 // return the other triangle of the quad if a quad or 0 if not a quat 925 Triangle * t =0; 926 if (link) { 927 int a=-1; 928 if (aa[0] & 16 ) a=0; 929 if (aa[1] & 16 ) a=1; 930 if (aa[2] & 16 ) a=2; 931 if (a>=0) { 932 t = at[a]; 933 // if (t-this<0) return 0; 934 v2 = ns[VerticesOfTriangularEdge[a][0]]; 935 v0 = ns[VerticesOfTriangularEdge[a][1]]; 936 v1 = ns[OppositeEdge[a]]; 937 v3 = t->ns[OppositeEdge[aa[a]&3]]; 938 } 939 } 940 return t; 941 } 942 943 inline double Triangle::QualityQuad(int a,int option) const 944 { // first do the logique part 945 double q; 946 if (!link || aa[a] &4) 947 q= -1; 948 else { 949 Triangle * t = at[a]; 950 if (t-this<0) q= -1;// because we do 2 times 951 else if (!t->link ) q= -1; 952 else if (aa[0] & 16 || aa[1] & 16 || aa[2] & 16 || t->aa[0] & 16 || t->aa[1] & 16 || t->aa[2] & 16 ) 953 q= -1; 954 else if(option) 955 { 956 const Vertex & v2 = *ns[VerticesOfTriangularEdge[a][0]]; 957 const Vertex & v0 = *ns[VerticesOfTriangularEdge[a][1]]; 958 const Vertex & v1 = *ns[OppositeEdge[a]]; 959 const Vertex & v3 = * t->ns[OppositeEdge[aa[a]&3]]; 960 q = QuadQuality(v0,v1,v2,v3); // do the float part 521 961 } 522 for (int i=0;i< NbSeg;i++) 523 lEn[i] = lSegsI[MaxNbSeg]; // copy old to new 524 delete [] lSegsI; // remove old 525 lSegsI = lEn; 526 } 527 if (NbSeg) 528 lSegsI[NbSeg-1].last=Size; 529 lSegsI[NbSeg].e=e; 530 lSegsI[NbSeg].sBegin=s0; 531 lSegsI[NbSeg].sEnd=s1; 532 NbSeg++; 533 } 534 535 // void CopyMetric(int i,int j){ lIntTria[j].m=lIntTria[i].m;} 536 // void CopyMetric(const Metric & mm,int j){ lIntTria[j].m=mm;} 537 538 void ReShape() { 539 register int newsize = MaxSize*2; 540 IntersectionTriangles* nw = new IntersectionTriangles[newsize]; 541 if (!nw){ 542 throw ErrorException(__FUNCT__,exprintf("!nw")); 543 } 544 for (int i=0;i<MaxSize;i++) // recopy 545 nw[i] = lIntTria[i]; 546 long int verbosity=0; 547 if(verbosity>3) printf(" ListofIntersectionTriangles ReShape Maxsize %i -> %i\n",MaxSize,MaxNbSeg); 548 MaxSize = newsize; 549 delete [] lIntTria;// remove old 550 lIntTria = nw; // copy pointer 551 } 552 553 void SplitEdge(const Triangles & ,const R2 &,const R2 &,int nbegin=0); 554 Real8 Length(); 555 Int4 NewPoints(Vertex *,Int4 & nbv,Int4 nbvx); 556 }; 557 558 559 ///////////////////////////////////////////////////////////////////////////////////// 560 class GeometricalSubDomain { 561 public: 562 GeometricalEdge *edge; 563 int sens; // -1 or 1 564 Int4 ref; 565 inline void Set(const GeometricalSubDomain &,const Geometry & ,const Geometry &); 566 567 }; 568 ///////////////////////////////////////////////////////////////////////////////////// 569 class SubDomain { 570 public: 571 Triangle * head; 572 Int4 ref; 573 int sens; // -1 or 1 574 Edge * edge; // to geometrical 575 inline void Set(const Triangles &,Int4,Triangles &); 576 577 }; 578 ///////////////////////////////////////////////////////////////////////////////////// 579 class VertexOnGeom { public: 580 581 Vertex * mv; 582 Real8 abscisse; 583 union{ 584 GeometricalVertex * gv; // if abscisse <0; 585 GeometricalEdge * ge; // if abscisse in [0..1] 586 }; 587 inline void Set(const VertexOnGeom&,const Triangles &,Triangles &); 588 int OnGeomVertex()const {return this? abscisse <0 :0;} 589 int OnGeomEdge() const {return this? abscisse >=0 :0;} 590 VertexOnGeom(): mv(0),abscisse(0){gv=0;} 591 VertexOnGeom(Vertex & m,GeometricalVertex &g) : mv(&m),abscisse(-1){gv=&g;} 592 VertexOnGeom(Vertex & m,GeometricalEdge &g,Real8 s) : mv(&m),abscisse(s){ge=&g;} 593 operator Vertex * () const {return mv;} 594 operator GeometricalVertex * () const {return gv;} 595 operator GeometricalEdge * () const {return ge;} 596 operator const Real8 & () const {return abscisse;} 597 int IsRequiredVertex(){ return this? (( abscisse<0 ? (gv?gv->Required():0):0 )) : 0;} 598 void SetOn(){mv->on=this;mv->vint=IsVertexOnGeom;} 599 inline void Set(const Triangles &,Int4,Triangles &); 600 601 }; 602 ///////////////////////////////////////////////////////////////////////////////////// 603 class VertexOnVertex {public: 604 Vertex * v, *bv; 605 VertexOnVertex(Vertex * w,Vertex *bw) :v(w),bv(bw){} 606 VertexOnVertex() {}; 607 inline void Set(const Triangles &,Int4,Triangles &); 608 void SetOnBTh(){v->onbv=bv;v->vint=IsVertexOnVertex;} 609 }; 610 ///////////////////////////////////////////////////////////////////////////////////// 611 class VertexOnEdge {public: 612 Vertex * v; 613 Edge * be; 614 Real8 abcisse; 615 VertexOnEdge( Vertex * w, Edge *bw,Real8 s) :v(w),be(bw),abcisse(s) {} 616 VertexOnEdge(){} 617 inline void Set(const Triangles &,Int4,Triangles &); 618 void SetOnBTh(){v->onbe=this;v->vint=IsVertexOnEdge;} 619 Vertex & operator[](int i) const { return (*be)[i];} 620 operator Real8 () const { return abcisse;} 621 operator Vertex * () const { return v;} 622 operator Edge * () const { return be;} 623 }; 624 625 inline TriangleAdjacent FindTriangleAdjacent(Edge &E); 626 inline Vertex * TheVertex(Vertex * a); // for remove crak in mesh 627 ///////////////////////////////////////////////////////////////////////////////////// 628 629 class CrackedEdge { // a small class to store on crack an uncrack information 630 friend class Triangles; 631 class CrackedTriangle { 632 friend class Triangles; 633 friend class CrackedEdge; 634 Triangle * t; // edge of triangle t 635 int i; // edge number of in triangle 636 Edge *edge; // the 2 edge 637 Vertex *New[2]; // new vertex number 638 CrackedTriangle() : t(0),i(0),edge(0) { New[0]=New[1]=0;} 639 CrackedTriangle(Edge * a) : t(0),i(0),edge(a) { New[0]=New[1]=0;} 640 void Crack(){ 641 Triangle & T(*t); 642 int i0=VerticesOfTriangularEdge[i][0]; 643 int i1=VerticesOfTriangularEdge[i][0]; 644 if (!New[0] && !New[1]){ 645 throw ErrorException(__FUNCT__,exprintf("!New[0] && !New[1]")); 646 } 647 T(i0) = New[0]; 648 T(i1) = New[1];} 649 void UnCrack(){ 650 Triangle & T(*t); 651 int i0=VerticesOfTriangularEdge[i][0]; 652 int i1=VerticesOfTriangularEdge[i][0]; 653 if (!New[0] && !New[1]){ 654 throw ErrorException(__FUNCT__,exprintf("!New[0] && !New[1]")); 655 } 656 T(i0) = TheVertex(T(i0)); 657 T(i1) = TheVertex(T(i1));} 658 void Set() { 659 TriangleAdjacent ta ( FindTriangleAdjacent(*edge)); 660 t = ta; 661 i = ta; 662 663 New[0] = ta.EdgeVertex(0); 664 New[1] = ta.EdgeVertex(1); 665 // warning the ref 666 667 } 668 669 }; // end of class CrackedTriangle 670 public: 671 CrackedTriangle a,b; 672 CrackedEdge() :a(),b() {} 673 CrackedEdge(Edge * start, Int4 i,Int4 j) : a(start+i),b(start+j) {}; 674 CrackedEdge(Edge * e0, Edge * e1 ) : a(e0),b(e1) {}; 675 676 void Crack() { a.Crack(); b.Crack();} 677 void UnCrack() { a.UnCrack(); b.UnCrack();} 678 void Set() { a.Set(), b.Set();} 679 }; 680 681 ///////////////////////////////////////////////////////////////////////////////////// 682 class Triangles { 683 public: 684 685 enum TypeFileMesh { 686 AutoMesh=0,BDMesh=1,NOPOMesh=2,amMesh=3,am_fmtMesh=4,amdbaMesh=5, 687 ftqMesh=6,mshMesh=7}; 688 689 int static counter; // to kown the number of mesh in memory 690 int OnDisk; // true if on disk 691 Geometry & Gh; // Geometry 692 Triangles & BTh; // Background Mesh Bth==*this =>no background 693 694 Int4 NbRef; // counter of ref on the this class if 0 we can delete 695 Int4 nbvx,nbtx; // nombre max de sommets , de triangles 696 697 Int4 nt,nbv,nbt,nbiv,nbe; // nb of legal triangles, nb of vertex, of triangles, 698 // of initial vertices, of edges with reference, 699 Int4 NbOfQuad; // nb of quadrangle 700 701 Int4 NbSubDomains; // 702 Int4 NbOutT; // Nb of oudeside triangle 703 Int4 NbOfTriangleSearchFind; 704 Int4 NbOfSwapTriangle; 705 char * name, *identity; 706 Vertex * vertices; // data of vertices des sommets 707 708 Int4 NbVerticesOnGeomVertex; 709 VertexOnGeom * VerticesOnGeomVertex; 710 711 Int4 NbVerticesOnGeomEdge; 712 VertexOnGeom * VerticesOnGeomEdge; 713 714 Int4 NbVertexOnBThVertex; 715 VertexOnVertex *VertexOnBThVertex; 716 717 Int4 NbVertexOnBThEdge; 718 VertexOnEdge *VertexOnBThEdge; 719 720 721 Int4 NbCrackedVertices; 722 723 724 Int4 NbCrackedEdges; 725 CrackedEdge *CrackedEdges; 726 727 728 R2 pmin,pmax; // extrema 729 Real8 coefIcoor; // coef to integer Icoor1; 730 731 Triangle * triangles; 732 Edge * edges; 733 734 QuadTree *quadtree; 735 Vertex ** ordre; 736 SubDomain * subdomains; 737 ListofIntersectionTriangles lIntTria; 738 // end of variable 739 740 Triangles(Int4 i);//:BTh(*this),Gh(*new Geometry()){PreInit(i);} 741 742 743 ~Triangles(); 744 Triangles(const char * ,Real8=-1) ; 745 Triangles(BamgMesh* bamgmesh,BamgOpts* bamgopts); 746 747 Triangles(Int4 nbvx,Triangles & BT,int keepBackVertices=1) 748 :Gh(BT.Gh),BTh(BT) { 749 try {GeomToTriangles1(nbvx,keepBackVertices);} 750 catch(...) { this->~Triangles(); throw; } } 751 752 Triangles(Int4 nbvx,Geometry & G) 753 :Gh(G),BTh(*this){ 754 try { GeomToTriangles0(nbvx);} 755 catch(...) { this->~Triangles(); throw; } } 756 Triangles(Triangles &,Geometry * pGh=0,Triangles* pBTh=0,Int4 nbvxx=0 ); // COPY OPERATEUR 757 Triangles(const Triangles &,const int *flag,const int *bb); // truncature 758 759 void SetIntCoor(const char * from =0); 760 761 // void RandomInit(); 762 // void CubeInit(int ,int); 763 764 Real8 MinimalHmin() {return 2.0/coefIcoor;} 765 Real8 MaximalHmax() {return Max(pmax.x-pmin.x,pmax.y-pmin.y);} 766 const Vertex & operator[] (Int4 i) const { return vertices[i];}; 767 Vertex & operator[](Int4 i) { return vertices[i];}; 768 const Triangle & operator() (Int4 i) const { return triangles[i];}; 769 Triangle & operator()(Int4 i) { return triangles[i];}; 770 I2 toI2(const R2 & P) const { 771 return I2( (Icoor1) (coefIcoor*(P.x-pmin.x)) 772 ,(Icoor1) (coefIcoor*(P.y-pmin.y)) );} 773 R2 toR2(const I2 & P) const { 774 return R2( (double) P.x/coefIcoor+pmin.x, (double) P.y/coefIcoor+pmin.y);} 775 void Add( Vertex & s,Triangle * t,Icoor2 * =0) ; 776 void Insert(); 777 // void InsertOld(); 778 void ForceBoundary(); 779 void Heap(); 780 void FindSubDomain(int ); 781 Int4 ConsRefTriangle(Int4 *) const; 782 void ShowHistogram() const; 783 void ShowRegulaty() const; // Add FH avril 2007 784 // void ConsLinkTriangle(); 785 786 void ReMakeTriangleContainingTheVertex(); 787 void UnMarkUnSwapTriangle(); 788 void SmoothMetric(Real8 raisonmax) ; 789 void BoundAnisotropy(Real8 anisomax,double hminaniso= 1e-100) ; 790 void MaxSubDivision(Real8 maxsubdiv); 791 Edge** MakeGeometricalEdgeToEdge(); 792 void SetVertexFieldOn(); 793 void SetVertexFieldOnBTh(); 794 Int4 SplitInternalEdgeWithBorderVertices(); 795 void MakeQuadrangles(double costheta); 796 int SplitElement(int choice); 797 void MakeQuadTree(); 798 void NewPoints( Triangles &,int KeepBackVertex =1 ); 799 Int4 InsertNewPoints(Int4 nbvold,Int4 & NbTSwap) ; 800 void NewPoints(int KeepBackVertex=1){ NewPoints(*this,KeepBackVertex);} 801 void ReNumberingTheTriangleBySubDomain(bool justcompress=false); 802 void ReNumberingVertex(Int4 * renu); 803 void SmoothingVertex(int =3,Real8=0.3); 804 Metric MetricAt (const R2 &) const; 805 GeometricalEdge * ProjectOnCurve( Edge & AB, Vertex & A, Vertex & B,Real8 theta, 806 Vertex & R,VertexOnEdge & BR,VertexOnGeom & GR); 807 808 Int4 Number(const Triangle & t) const { return &t - triangles;} 809 Int4 Number(const Triangle * t) const { return t - triangles;} 810 Int4 Number(const Vertex & t) const { return &t - vertices;} 811 Int4 Number(const Vertex * t) const { return t - vertices;} 812 Int4 Number(const Edge & t) const { return &t - edges;} 813 Int4 Number(const Edge * t) const { return t - edges;} 814 Int4 Number2(const Triangle * t) const { 815 // if(t>= triangles && t < triangles + nbt ) 816 return t - triangles; 817 // else return t - OutSidesTriangles; 818 } 819 820 Vertex * NearestVertex(Icoor1 i,Icoor1 j) ; 821 Triangle * FindTriangleContening(const I2 & ,Icoor2 [3],Triangle *tstart=0) const; 822 823 void ReadMesh(BamgMesh* bamgmesh, BamgOpts* bamgopts); 824 void WriteMesh(BamgMesh* bamgmesh,BamgOpts* bamgopts); 825 826 void ReadMetric(BamgOpts* bamgopts,const Real8 hmin,const Real8 hmax,const Real8 coef); 827 void WriteMetric(BamgOpts* bamgopts); 828 void IntersectConsMetric(const double * s,const Int4 nbsol,const int * typsols, 829 const Real8 hmin,const Real8 hmax, const Real8 coef, 830 const Real8 anisomax,const Real8 CutOff=1.e-4,const int NbJacobi=1, 831 const int DoNormalisation=1, 832 const double power=1.0, 833 const int choise=0); 834 void IntersectGeomMetric(const Real8 err,const int iso); 835 836 837 int isCracked() const {return NbCrackedVertices != 0;} 838 int Crack(); 839 int UnCrack(); 840 841 void ConsGeometry(Real8 =-1.0,int *equiedges=0); // construct a geometry if no geo 842 void FillHoleInMesh() ; 843 int CrackMesh(); 844 private: 845 void GeomToTriangles1(Int4 nbvx,int KeepBackVertices=1);// the real constructor mesh adaption 846 void GeomToTriangles0(Int4 nbvx);// the real constructor mesh generator 847 void PreInit(Int4,char * =0 ); 848 849 }; // End Class Triangles 850 851 852 ///////////////////////////////////////////////////////////////////////////////////// 853 class Geometry { 854 public: 855 int OnDisk; 856 Int4 NbRef; // counter of ref on the this class if 0 we can delete 857 858 char *name; 859 Int4 nbvx,nbtx; // nombre max de sommets , de Geometry 860 Int4 nbv,nbt,nbiv,nbe; // nombre de sommets, de Geometry, de sommets initiaux, 861 Int4 NbSubDomains; // 862 Int4 NbEquiEdges; 863 Int4 NbCrackedEdges; 864 // Int4 nbtf;// de triangle frontiere 865 Int4 NbOfCurves; 866 int empty(){return (nbv ==0) && (nbt==0) && (nbe==0) && (NbSubDomains==0); } 867 GeometricalVertex * vertices; // data of vertices des sommets 868 Triangle * triangles; 869 GeometricalEdge * edges; 870 QuadTree *quadtree; 871 GeometricalSubDomain *subdomains; 872 Curve *curves; 873 ~Geometry(); 874 Geometry(const Geometry & Gh); //Copy Operator 875 Geometry(int nbg,const Geometry ** ag); // intersection operator 876 877 R2 pmin,pmax; // extrema 878 Real8 coefIcoor; // coef to integer Icoor1; 879 Real8 MaximalAngleOfCorner; 880 881 // end of data 882 883 884 I2 toI2(const R2 & P) const { 885 return I2( (Icoor1) (coefIcoor*(P.x-pmin.x)) 886 ,(Icoor1) (coefIcoor*(P.y-pmin.y)) );} 887 888 Real8 MinimalHmin() {return 2.0/coefIcoor;} 889 Real8 MaximalHmax() {return Max(pmax.x-pmin.x,pmax.y-pmin.y);} 890 void ReadGeometry(BamgGeom* bamggeom, BamgOpts* bamgopts); 891 void EmptyGeometry(); 892 Geometry() {EmptyGeometry();}// empty Geometry 893 void AfterRead(); 894 Geometry(BamgGeom* bamggeom, BamgOpts* bamgopts) {EmptyGeometry();OnDisk=1;ReadGeometry(bamggeom,bamgopts);AfterRead();} 895 896 const GeometricalVertex & operator[] (Int4 i) const { return vertices[i];}; 897 GeometricalVertex & operator[](Int4 i) { return vertices[i];}; 898 const GeometricalEdge & operator() (Int4 i) const { return edges[i];}; 899 GeometricalEdge & operator()(Int4 i) { return edges[i];}; 900 Int4 Number(const GeometricalVertex & t) const { return &t - vertices;} 901 Int4 Number(const GeometricalVertex * t) const { return t - vertices;} 902 Int4 Number(const GeometricalEdge & t) const { return &t - edges;} 903 Int4 Number(const GeometricalEdge * t) const { return t - edges;} 904 Int4 Number(const Curve * c) const { return c - curves;} 905 906 void UnMarkEdges() { 907 for (Int4 i=0;i<nbe;i++) edges[i].SetUnMark();} 908 909 GeometricalEdge * ProjectOnCurve(const Edge & ,Real8,Vertex &,VertexOnGeom &) const ; 910 GeometricalEdge * Contening(const R2 P, GeometricalEdge * start) const; 911 void WriteGeometry(BamgGeom* bamggeom, BamgOpts* bamgopts); 912 }; // End Class Geometry 913 914 //From Metric.cpp 915 inline Real8 det3x3(Real8 A[3] ,Real8 B[3],Real8 C[3]) 916 { return A[0] * ( B[1]*C[2]-B[2]*C[1]) 917 - A[1] * ( B[0]*C[2]-B[2]*C[0]) 918 + A[2] * ( B[0]*C[1]-B[1]*C[0]); 919 } 920 921 ///////////////////////////////////////////////////////////////////////////////////// 922 ///////////////////////////////////////////////////////////////////////////////////// 923 /////////////////// END CLASS //////////////////////////////////// 924 ///////////////////////////////////////////////////////////////////////////////////// 925 ///////////////////////////////////////////////////////////////////////////////////// 926 927 inline Triangles::Triangles(Int4 i) :Gh(*new Geometry()),BTh(*this){PreInit(i);} 928 929 extern Triangles * CurrentTh; 930 931 TriangleAdjacent CloseBoundaryEdge(I2 ,Triangle *, double &,double &) ; 932 TriangleAdjacent CloseBoundaryEdgeV2(I2 A,Triangle *t, double &a,double &b); 933 934 Int4 FindTriangle(Triangles &Th, Real8 x, Real8 y, double* a,int & inside); 935 936 937 938 inline Triangle * Triangle::Quadrangle(Vertex * & v0,Vertex * & v1,Vertex * & v2,Vertex * & v3) const 939 { 940 // return the other triangle of the quad if a quad or 0 if not a quat 941 Triangle * t =0; 942 if (link) { 943 int a=-1; 944 if (aa[0] & 16 ) a=0; 945 if (aa[1] & 16 ) a=1; 946 if (aa[2] & 16 ) a=2; 947 if (a>=0) { 948 t = at[a]; 949 // if (t-this<0) return 0; 950 v2 = ns[VerticesOfTriangularEdge[a][0]]; 951 v0 = ns[VerticesOfTriangularEdge[a][1]]; 952 v1 = ns[OppositeEdge[a]]; 953 v3 = t->ns[OppositeEdge[aa[a]&3]]; 954 } 955 } 956 return t; 957 } 958 959 inline double Triangle::QualityQuad(int a,int option) const 960 { // first do the logique part 961 double q; 962 if (!link || aa[a] &4) 963 q= -1; 964 else { 965 Triangle * t = at[a]; 966 if (t-this<0) q= -1;// because we do 2 times 967 else if (!t->link ) q= -1; 968 else if (aa[0] & 16 || aa[1] & 16 || aa[2] & 16 || t->aa[0] & 16 || t->aa[1] & 16 || t->aa[2] & 16 ) 969 q= -1; 970 else if(option) 971 { 972 const Vertex & v2 = *ns[VerticesOfTriangularEdge[a][0]]; 973 const Vertex & v0 = *ns[VerticesOfTriangularEdge[a][1]]; 974 const Vertex & v1 = *ns[OppositeEdge[a]]; 975 const Vertex & v3 = * t->ns[OppositeEdge[aa[a]&3]]; 976 q = QuadQuality(v0,v1,v2,v3); // do the float part 977 } 978 else q= 1; 979 } 980 return q; 981 } 982 983 984 inline void Vertex::Set(const Vertex & rec,const Triangles & ,Triangles & ) 985 { 986 *this = rec; 987 } 988 inline void GeometricalVertex::Set(const GeometricalVertex & rec,const Geometry & ,const Geometry & ) 989 { 990 *this = rec; 991 } 992 inline void Edge::Set(const Triangles & Th ,Int4 i,Triangles & ThNew) 993 { 994 *this = Th.edges[i]; 995 v[0] = ThNew.vertices + Th.Number(v[0]); 996 v[1] = ThNew.vertices + Th.Number(v[1]); 997 if (on) 998 on = ThNew.Gh.edges+Th.Gh.Number(on); 999 if (adj[0]) adj[0] = ThNew.edges + Th.Number(adj[0]); 1000 if (adj[1]) adj[1] = ThNew.edges + Th.Number(adj[1]); 1001 1002 } 1003 inline void GeometricalEdge::Set(const GeometricalEdge & rec,const Geometry & Gh ,Geometry & GhNew) 1004 { 1005 *this = rec; 1006 v[0] = GhNew.vertices + Gh.Number(v[0]); 1007 v[1] = GhNew.vertices + Gh.Number(v[1]); 1008 if (Adj[0]) Adj[0] = GhNew.edges + Gh.Number(Adj[0]); 1009 if (Adj[1]) Adj[1] = GhNew.edges + Gh.Number(Adj[1]); 1010 } 1011 1012 inline void Curve::Set(const Curve & rec,const Geometry & Gh ,Geometry & GhNew) 1013 { 1014 *this = rec; 1015 be = GhNew.edges + Gh.Number(be); 1016 ee = GhNew.edges + Gh.Number(ee); 1017 if(next) next= GhNew.curves + Gh.Number(next); 1018 } 1019 1020 inline void Triangle::Set(const Triangle & rec,const Triangles & Th ,Triangles & ThNew) 1021 { 1022 *this = rec; 1023 if ( ns[0] ) ns[0] = ThNew.vertices + Th.Number(ns[0]); 1024 if ( ns[1] ) ns[1] = ThNew.vertices + Th.Number(ns[1]); 1025 if ( ns[2] ) ns[2] = ThNew.vertices + Th.Number(ns[2]); 1026 if(at[0]) at[0] = ThNew.triangles + Th.Number(at[0]); 1027 if(at[1]) at[1] = ThNew.triangles + Th.Number(at[1]); 1028 if(at[2]) at[2] = ThNew.triangles + Th.Number(at[2]); 1029 if (link >= Th.triangles && link < Th.triangles + Th.nbt) 1030 link = ThNew.triangles + Th.Number(link); 1031 } 1032 inline void VertexOnVertex::Set(const Triangles & Th ,Int4 i,Triangles & ThNew) 1033 { 1034 *this = Th.VertexOnBThVertex[i]; 1035 v = ThNew.vertices + Th.Number(v); 1036 1037 } 1038 inline void SubDomain::Set(const Triangles & Th ,Int4 i,Triangles & ThNew) 1039 { 1040 *this = Th.subdomains[i]; 1041 if ( head-Th.triangles<0 || head-Th.triangles>=Th.nbt){ 1042 throw ErrorException(__FUNCT__,exprintf("head-Th.triangles<0 || head-Th.triangles>=Th.nbt")); 1043 } 1044 head = ThNew.triangles + Th.Number(head) ; 1045 if (edge-Th.edges<0 || edge-Th.edges>=Th.nbe);{ 1046 throw ErrorException(__FUNCT__,exprintf("edge-Th.edges<0 || edge-Th.edges>=Th.nbe")); 1047 } 1048 edge = ThNew.edges+ Th.Number(edge); 1049 } 1050 inline void GeometricalSubDomain::Set(const GeometricalSubDomain & rec,const Geometry & Gh ,const Geometry & GhNew) 1051 { 1052 *this = rec; 1053 edge = Gh.Number(edge) + GhNew.edges; 1054 } 1055 inline void VertexOnEdge::Set(const Triangles & Th ,Int4 i,Triangles & ThNew) 1056 { 1057 *this = Th.VertexOnBThEdge[i]; 1058 v = ThNew.vertices + Th.Number(v); 1059 } 1060 1061 inline void VertexOnGeom::Set(const VertexOnGeom & rec,const Triangles & Th ,Triangles & ThNew) 1062 { 1063 *this = rec; 1064 mv = ThNew.vertices + Th.Number(mv); 1065 if (gv) 1066 if (abscisse < 0 ) 1067 gv = ThNew.Gh.vertices + Th.Gh.Number(gv); 1068 else 1069 ge = ThNew.Gh.edges + Th.Gh.Number(ge); 1070 1071 } 1072 inline Real8 Edge::MetricLength() const 1073 { 1074 return LengthInterpole(v[0]->m,v[1]->m,v[1]->r - v[0]->r) ; 1075 } 1076 1077 inline void Triangles::ReMakeTriangleContainingTheVertex() 1078 { 1079 register Int4 i; 1080 for ( i=0;i<nbv;i++) 1081 { 1082 vertices[i].vint = 0; 1083 vertices[i].t=0; 1084 } 1085 for ( i=0;i<nbt;i++) 1086 triangles[i].SetTriangleContainingTheVertex(); 1087 } 1088 1089 inline void Triangles::UnMarkUnSwapTriangle() 1090 { 1091 register Int4 i; 1092 for ( i=0;i<nbt;i++) 1093 for(int j=0;j<3;j++) 1094 triangles[i].SetUnMarkUnSwap(j); 1095 } 1096 1097 inline void Triangles::SetVertexFieldOn() 1098 { 1099 for (Int4 i=0;i<nbv;i++) 1100 vertices[i].on=0; 1101 for (Int4 j=0;j<NbVerticesOnGeomVertex;j++ ) 1102 VerticesOnGeomVertex[j].SetOn(); 1103 for (Int4 k=0;k<NbVerticesOnGeomEdge;k++ ) 1104 VerticesOnGeomEdge[k].SetOn(); 1105 } 1106 inline void Triangles::SetVertexFieldOnBTh() 1107 { 1108 for (Int4 i=0;i<nbv;i++) 1109 vertices[i].on=0; 1110 for (Int4 j=0;j<NbVertexOnBThVertex;j++ ) 1111 VertexOnBThVertex[j].SetOnBTh(); 1112 for (Int4 k=0;k<NbVertexOnBThEdge;k++ ) 1113 VertexOnBThEdge[k].SetOnBTh(); 1114 1115 } 1116 1117 inline void TriangleAdjacent::SetAdj2(const TriangleAdjacent & ta, int l ) 1118 { // set du triangle adjacent 1119 if(t) { 1120 t->at[a]=ta.t; 1121 t->aa[a]=ta.a|l;} 1122 if(ta.t) { 1123 ta.t->at[ta.a] = t ; 1124 ta.t->aa[ta.a] = a| l ; 1125 } 1126 } 1127 1128 1129 inline int TriangleAdjacent::Locked() const 1130 { return t->aa[a] &4;} 1131 inline int TriangleAdjacent::Cracked() const 1132 { return t->aa[a] &32;} 1133 inline int TriangleAdjacent::GetAllFlag_UnSwap() const 1134 { return t->aa[a] & 1012;} // take all flag except MarkUnSwap 1135 1136 inline int TriangleAdjacent::MarkUnSwap() const 1137 { return t->aa[a] &8;} 1138 1139 inline void TriangleAdjacent::SetLock(){ t->SetLocked(a);} 1140 1141 inline void TriangleAdjacent::SetCracked() { t->SetCracked(a);} 1142 1143 inline TriangleAdjacent TriangleAdjacent::Adj() const 1144 { return t->Adj(a);} 1145 1146 inline Vertex * TriangleAdjacent::EdgeVertex(const int & i) const 1147 {return t->ns[VerticesOfTriangularEdge[a][i]]; } 1148 inline Vertex * TriangleAdjacent::OppositeVertex() const 1149 {return t->ns[bamg::OppositeVertex[a]]; } 1150 inline Icoor2 & TriangleAdjacent::det() const 1151 { return t->det;} 1152 inline TriangleAdjacent Adj(const TriangleAdjacent & a) 1153 { return a.Adj();} 1154 1155 inline TriangleAdjacent Next(const TriangleAdjacent & ta) 1156 { return TriangleAdjacent(ta.t,NextEdge[ta.a]);} 1157 1158 inline TriangleAdjacent Previous(const TriangleAdjacent & ta) 1159 { return TriangleAdjacent(ta.t,PreviousEdge[ta.a]);} 1160 1161 inline void Adj(GeometricalEdge * & on,int &i) 1162 {int j=i;i=on->SensAdj[i];on=on->Adj[j];} 1163 1164 inline Real4 qualite(const Vertex &va,const Vertex &vb,const Vertex &vc) 1165 { 1166 Real4 ret; 1167 I2 ia=va,ib=vb,ic=vc; 1168 I2 ab=ib-ia,bc=ic-ib,ac=ic-ia; 1169 Icoor2 deta=Det(ab,ac); 1170 if (deta <=0) ret = -1; 1171 else { 1172 Real8 a = sqrt((Real8) (ac,ac)), 1173 b = sqrt((Real8) (bc,bc)), 1174 c = sqrt((Real8) (ab,ab)), 1175 p = a+b+c; 1176 Real8 h= Max(Max(a,b),c),ro=deta/p; 1177 ret = ro/h;} 1178 return ret; 1179 } 1180 1181 1182 inline Triangle::Triangle(Triangles *Th,Int4 i,Int4 j,Int4 k) { 1183 Vertex *v=Th->vertices; 1184 Int4 nbv = Th->nbv; 1185 if (i<0 || j<0 || k<0){ 1186 throw ErrorException(__FUNCT__,exprintf("i<0 || j<0 || k<0")); 1187 } 1188 if (i>=nbv || j>=nbv || k>=nbv){ 1189 throw ErrorException(__FUNCT__,exprintf("i>=nbv || j>=nbv || k>=nbv")); 1190 } 1191 ns[0]=v+i; 1192 ns[1]=v+j; 1193 ns[2]=v+k; 1194 at[0]=at[1]=at[2]=0; 1195 aa[0]=aa[1]=aa[2]=0; 1196 det=0; 1197 } 1198 1199 inline Triangle::Triangle(Vertex *v0,Vertex *v1,Vertex *v2){ 1200 ns[0]=v0; 1201 ns[1]=v1; 1202 ns[2]=v2; 1203 at[0]=at[1]=at[2]=0; 1204 aa[0]=aa[1]=aa[2]=0; 1205 if (v0) det=0; 1206 else { 1207 det=-1; 1208 link=NULL;}; 1209 } 1210 1211 inline Real4 Triangle::qualite() 1212 { 1213 return det < 0 ? -1 : bamg::qualite(*ns[0],*ns[1],*ns[2]); 1214 } 1215 1216 Int4 inline Vertex::Optim(int i,int koption) 1217 { 1218 Int4 ret=0; 1219 if ( t && (vint >= 0 ) && (vint <3) ) 1220 { 1221 ret = t->Optim(vint,koption); 1222 if(!i) 1223 { 1224 t =0; // for no future optime 1225 vint= 0; } 1226 } 1227 return ret; 1228 } 1229 1230 Icoor2 inline det(const Vertex & a,const Vertex & b,const Vertex & c) 1231 { 1232 register Icoor2 bax = b.i.x - a.i.x ,bay = b.i.y - a.i.y; 1233 register Icoor2 cax = c.i.x - a.i.x ,cay = c.i.y - a.i.y; 1234 return bax*cay - bay*cax;} 1235 1236 1237 void swap(Triangle *t1,Int1 a1, 1238 Triangle *t2,Int1 a2, 1239 Vertex *s1,Vertex *s2,Icoor2 det1,Icoor2 det2); 1240 1241 1242 1243 int inline TriangleAdjacent::swap() 1244 { return t->swap(a);} 1245 1246 1247 1248 int SwapForForcingEdge(Vertex * & pva ,Vertex * & pvb , 1249 TriangleAdjacent & tt1,Icoor2 & dets1, 1250 Icoor2 & detsa,Icoor2 & detsb, int & nbswap); 1251 1252 int ForceEdge(Vertex &a, Vertex & b,TriangleAdjacent & taret) ; 1253 1254 // inline bofbof FH 1255 inline TriangleAdjacent FindTriangleAdjacent(Edge &E) 1256 { 1257 Vertex * a = E.v[0]; 1258 Vertex * b = E.v[1]; 1259 1260 Triangle * t = a->t; 1261 int i = a->vint; 1262 TriangleAdjacent ta(t,EdgesVertexTriangle[i][0]); // Previous edge 1263 if (!t || i<0 || i>=3){ 1264 throw ErrorException(__FUNCT__,exprintf("!t || i<0 !! i>=3")); 1265 } 1266 if ( a!=(*t)(i)){ 1267 throw ErrorException(__FUNCT__,exprintf("a!=(*t)(i)")); 1268 } 1269 int k=0; 1270 do { // turn around vertex in direct sens (trigo) 1271 k++; 1272 if (k>=20000){ 1273 throw ErrorException(__FUNCT__,exprintf("k>=20000")); 962 else q= 1; 1274 963 } 1275 // in no crack => ta.EdgeVertex(1) == a otherwise ??? 1276 if (ta.EdgeVertex(1) == a && ta.EdgeVertex(0) == b) return ta; // find 1277 ta = ta.Adj(); 1278 if (ta.EdgeVertex(0) == a && ta.EdgeVertex(1) == b) return ta; // find 1279 --ta; 1280 } while (t != (Triangle *)ta); 1281 throw ErrorException(__FUNCT__,exprintf("FindTriangleAdjacent: triangle not found")); 1282 return TriangleAdjacent(0,0);//for compiler 1283 } 1284 1285 inline Vertex * TheVertex(Vertex * a) // give a unique vertex with smallest number 1286 { // in case on crack in mesh 1287 Vertex * r(a), *rr; 1288 Triangle * t = a->t; 1289 int i = a->vint; 1290 TriangleAdjacent ta(t,EdgesVertexTriangle[i][0]); // Previous edge 1291 if (!t || i<0 || i>=3){ 1292 throw ErrorException(__FUNCT__,exprintf("!t || i<0 !! i>=3")); 1293 } 1294 if ( a!=(*t)(i)){ 1295 throw ErrorException(__FUNCT__,exprintf("a!=(*t)(i)")); 1296 } 1297 int k=0; 1298 do { // turn around vertex in direct sens (trigo) 1299 k++; 1300 if (k>=20000){ 1301 throw ErrorException(__FUNCT__,exprintf("k>=20000")); 964 return q; 965 } 966 967 inline void Vertex::Set(const Vertex & rec,const Triangles & ,Triangles & ) 968 { 969 *this = rec; 970 } 971 inline void GeometricalVertex::Set(const GeometricalVertex & rec,const Geometry & ,const Geometry & ) 972 { 973 *this = rec; 974 } 975 inline void Edge::Set(const Triangles & Th ,Int4 i,Triangles & ThNew) 976 { 977 *this = Th.edges[i]; 978 v[0] = ThNew.vertices + Th.Number(v[0]); 979 v[1] = ThNew.vertices + Th.Number(v[1]); 980 if (on) 981 on = ThNew.Gh.edges+Th.Gh.Number(on); 982 if (adj[0]) adj[0] = ThNew.edges + Th.Number(adj[0]); 983 if (adj[1]) adj[1] = ThNew.edges + Th.Number(adj[1]); 984 985 } 986 inline void GeometricalEdge::Set(const GeometricalEdge & rec,const Geometry & Gh ,Geometry & GhNew) 987 { 988 *this = rec; 989 v[0] = GhNew.vertices + Gh.Number(v[0]); 990 v[1] = GhNew.vertices + Gh.Number(v[1]); 991 if (Adj[0]) Adj[0] = GhNew.edges + Gh.Number(Adj[0]); 992 if (Adj[1]) Adj[1] = GhNew.edges + Gh.Number(Adj[1]); 993 } 994 995 inline void Curve::Set(const Curve & rec,const Geometry & Gh ,Geometry & GhNew) 996 { 997 *this = rec; 998 be = GhNew.edges + Gh.Number(be); 999 ee = GhNew.edges + Gh.Number(ee); 1000 if(next) next= GhNew.curves + Gh.Number(next); 1001 } 1002 1003 inline void Triangle::Set(const Triangle & rec,const Triangles & Th ,Triangles & ThNew) 1004 { 1005 *this = rec; 1006 if ( ns[0] ) ns[0] = ThNew.vertices + Th.Number(ns[0]); 1007 if ( ns[1] ) ns[1] = ThNew.vertices + Th.Number(ns[1]); 1008 if ( ns[2] ) ns[2] = ThNew.vertices + Th.Number(ns[2]); 1009 if(at[0]) at[0] = ThNew.triangles + Th.Number(at[0]); 1010 if(at[1]) at[1] = ThNew.triangles + Th.Number(at[1]); 1011 if(at[2]) at[2] = ThNew.triangles + Th.Number(at[2]); 1012 if (link >= Th.triangles && link < Th.triangles + Th.nbt) 1013 link = ThNew.triangles + Th.Number(link); 1014 } 1015 inline void VertexOnVertex::Set(const Triangles & Th ,Int4 i,Triangles & ThNew) 1016 { 1017 *this = Th.VertexOnBThVertex[i]; 1018 v = ThNew.vertices + Th.Number(v); 1019 1020 } 1021 inline void SubDomain::Set(const Triangles & Th ,Int4 i,Triangles & ThNew) 1022 { 1023 *this = Th.subdomains[i]; 1024 if ( head-Th.triangles<0 || head-Th.triangles>=Th.nbt){ 1025 throw ErrorException(__FUNCT__,exprintf("head-Th.triangles<0 || head-Th.triangles>=Th.nbt")); 1302 1026 } 1303 // in no crack => ta.EdgeVertex(1) == a 1304 if ((rr=ta.EdgeVertex(0)) < r) r = rr; 1305 ta = ta.Adj(); 1306 if ((rr=ta.EdgeVertex(1)) < r) r =rr; 1307 --ta; 1308 } while (t != (Triangle*) ta); 1309 return r; 1310 } 1311 1312 inline double CPUtime(){ 1313 #ifdef SYSTIMES 1314 struct tms buf; 1315 if (times(&buf)!=-1) 1316 return ((double)buf.tms_utime+(double)buf.tms_stime)/(long) sysconf(_SC_CLK_TCK); 1317 else 1318 #endif 1319 return ((double) clock())/CLOCKS_PER_SEC; 1320 } 1321 1027 head = ThNew.triangles + Th.Number(head) ; 1028 if (edge-Th.edges<0 || edge-Th.edges>=Th.nbe);{ 1029 throw ErrorException(__FUNCT__,exprintf("edge-Th.edges<0 || edge-Th.edges>=Th.nbe")); 1030 } 1031 edge = ThNew.edges+ Th.Number(edge); 1032 } 1033 inline void GeometricalSubDomain::Set(const GeometricalSubDomain & rec,const Geometry & Gh ,const Geometry & GhNew) 1034 { 1035 *this = rec; 1036 edge = Gh.Number(edge) + GhNew.edges; 1037 } 1038 inline void VertexOnEdge::Set(const Triangles & Th ,Int4 i,Triangles & ThNew) 1039 { 1040 *this = Th.VertexOnBThEdge[i]; 1041 v = ThNew.vertices + Th.Number(v); 1042 } 1043 1044 inline void VertexOnGeom::Set(const VertexOnGeom & rec,const Triangles & Th ,Triangles & ThNew) 1045 { 1046 *this = rec; 1047 mv = ThNew.vertices + Th.Number(mv); 1048 if (gv) 1049 if (abscisse < 0 ) 1050 gv = ThNew.Gh.vertices + Th.Gh.Number(gv); 1051 else 1052 ge = ThNew.Gh.edges + Th.Gh.Number(ge); 1053 1054 } 1055 inline Real8 Edge::MetricLength() const 1056 { 1057 return LengthInterpole(v[0]->m,v[1]->m,v[1]->r - v[0]->r) ; 1058 } 1059 1060 inline void Triangles::ReMakeTriangleContainingTheVertex() 1061 { 1062 register Int4 i; 1063 for ( i=0;i<nbv;i++) 1064 { 1065 vertices[i].vint = 0; 1066 vertices[i].t=0; 1067 } 1068 for ( i=0;i<nbt;i++) 1069 triangles[i].SetTriangleContainingTheVertex(); 1070 } 1071 1072 inline void Triangles::UnMarkUnSwapTriangle() 1073 { 1074 register Int4 i; 1075 for ( i=0;i<nbt;i++) 1076 for(int j=0;j<3;j++) 1077 triangles[i].SetUnMarkUnSwap(j); 1078 } 1079 1080 inline void Triangles::SetVertexFieldOn() 1081 { 1082 for (Int4 i=0;i<nbv;i++) 1083 vertices[i].on=0; 1084 for (Int4 j=0;j<NbVerticesOnGeomVertex;j++ ) 1085 VerticesOnGeomVertex[j].SetOn(); 1086 for (Int4 k=0;k<NbVerticesOnGeomEdge;k++ ) 1087 VerticesOnGeomEdge[k].SetOn(); 1088 } 1089 inline void Triangles::SetVertexFieldOnBTh() 1090 { 1091 for (Int4 i=0;i<nbv;i++) 1092 vertices[i].on=0; 1093 for (Int4 j=0;j<NbVertexOnBThVertex;j++ ) 1094 VertexOnBThVertex[j].SetOnBTh(); 1095 for (Int4 k=0;k<NbVertexOnBThEdge;k++ ) 1096 VertexOnBThEdge[k].SetOnBTh(); 1097 1098 } 1099 1100 inline void TriangleAdjacent::SetAdj2(const TriangleAdjacent & ta, int l ) 1101 { // set du triangle adjacent 1102 if(t) { 1103 t->at[a]=ta.t; 1104 t->aa[a]=ta.a|l;} 1105 if(ta.t) { 1106 ta.t->at[ta.a] = t ; 1107 ta.t->aa[ta.a] = a| l ; 1108 } 1109 } 1110 1111 1112 inline int TriangleAdjacent::Locked() const 1113 { return t->aa[a] &4;} 1114 inline int TriangleAdjacent::Cracked() const 1115 { return t->aa[a] &32;} 1116 inline int TriangleAdjacent::GetAllFlag_UnSwap() const 1117 { return t->aa[a] & 1012;} // take all flag except MarkUnSwap 1118 1119 inline int TriangleAdjacent::MarkUnSwap() const 1120 { return t->aa[a] &8;} 1121 1122 inline void TriangleAdjacent::SetLock(){ t->SetLocked(a);} 1123 1124 inline void TriangleAdjacent::SetCracked() { t->SetCracked(a);} 1125 1126 inline TriangleAdjacent TriangleAdjacent::Adj() const 1127 { return t->Adj(a);} 1128 1129 inline Vertex * TriangleAdjacent::EdgeVertex(const int & i) const 1130 {return t->ns[VerticesOfTriangularEdge[a][i]]; } 1131 inline Vertex * TriangleAdjacent::OppositeVertex() const 1132 {return t->ns[bamg::OppositeVertex[a]]; } 1133 inline Icoor2 & TriangleAdjacent::det() const 1134 { return t->det;} 1135 inline TriangleAdjacent Adj(const TriangleAdjacent & a) 1136 { return a.Adj();} 1137 1138 inline TriangleAdjacent Next(const TriangleAdjacent & ta) 1139 { return TriangleAdjacent(ta.t,NextEdge[ta.a]);} 1140 1141 inline TriangleAdjacent Previous(const TriangleAdjacent & ta) 1142 { return TriangleAdjacent(ta.t,PreviousEdge[ta.a]);} 1143 1144 inline void Adj(GeometricalEdge * & on,int &i) 1145 {int j=i;i=on->SensAdj[i];on=on->Adj[j];} 1146 1147 inline Real4 qualite(const Vertex &va,const Vertex &vb,const Vertex &vc) 1148 { 1149 Real4 ret; 1150 I2 ia=va,ib=vb,ic=vc; 1151 I2 ab=ib-ia,bc=ic-ib,ac=ic-ia; 1152 Icoor2 deta=Det(ab,ac); 1153 if (deta <=0) ret = -1; 1154 else { 1155 Real8 a = sqrt((Real8) (ac,ac)), 1156 b = sqrt((Real8) (bc,bc)), 1157 c = sqrt((Real8) (ab,ab)), 1158 p = a+b+c; 1159 Real8 h= Max(Max(a,b),c),ro=deta/p; 1160 ret = ro/h;} 1161 return ret; 1162 } 1163 1164 1165 inline Triangle::Triangle(Triangles *Th,Int4 i,Int4 j,Int4 k) { 1166 Vertex *v=Th->vertices; 1167 Int4 nbv = Th->nbv; 1168 if (i<0 || j<0 || k<0){ 1169 throw ErrorException(__FUNCT__,exprintf("i<0 || j<0 || k<0")); 1170 } 1171 if (i>=nbv || j>=nbv || k>=nbv){ 1172 throw ErrorException(__FUNCT__,exprintf("i>=nbv || j>=nbv || k>=nbv")); 1173 } 1174 ns[0]=v+i; 1175 ns[1]=v+j; 1176 ns[2]=v+k; 1177 at[0]=at[1]=at[2]=0; 1178 aa[0]=aa[1]=aa[2]=0; 1179 det=0; 1180 } 1181 1182 inline Triangle::Triangle(Vertex *v0,Vertex *v1,Vertex *v2){ 1183 ns[0]=v0; 1184 ns[1]=v1; 1185 ns[2]=v2; 1186 at[0]=at[1]=at[2]=0; 1187 aa[0]=aa[1]=aa[2]=0; 1188 if (v0) det=0; 1189 else { 1190 det=-1; 1191 link=NULL;}; 1192 } 1193 1194 inline Real4 Triangle::qualite() 1195 { 1196 return det < 0 ? -1 : bamg::qualite(*ns[0],*ns[1],*ns[2]); 1197 } 1198 1199 Int4 inline Vertex::Optim(int i,int koption) 1200 { 1201 Int4 ret=0; 1202 if ( t && (vint >= 0 ) && (vint <3) ) 1203 { 1204 ret = t->Optim(vint,koption); 1205 if(!i) 1206 { 1207 t =0; // for no future optime 1208 vint= 0; } 1209 } 1210 return ret; 1211 } 1212 1213 Icoor2 inline det(const Vertex & a,const Vertex & b,const Vertex & c) 1214 { 1215 register Icoor2 bax = b.i.x - a.i.x ,bay = b.i.y - a.i.y; 1216 register Icoor2 cax = c.i.x - a.i.x ,cay = c.i.y - a.i.y; 1217 return bax*cay - bay*cax;} 1218 1219 1220 void swap(Triangle *t1,Int1 a1, 1221 Triangle *t2,Int1 a2, 1222 Vertex *s1,Vertex *s2,Icoor2 det1,Icoor2 det2); 1223 1224 1225 1226 int inline TriangleAdjacent::swap() 1227 { return t->swap(a);} 1228 1229 1230 1231 int SwapForForcingEdge(Vertex * & pva ,Vertex * & pvb , 1232 TriangleAdjacent & tt1,Icoor2 & dets1, 1233 Icoor2 & detsa,Icoor2 & detsb, int & nbswap); 1234 1235 int ForceEdge(Vertex &a, Vertex & b,TriangleAdjacent & taret) ; 1236 1237 // inline bofbof FH 1238 inline TriangleAdjacent FindTriangleAdjacent(Edge &E) 1239 { 1240 Vertex * a = E.v[0]; 1241 Vertex * b = E.v[1]; 1242 1243 Triangle * t = a->t; 1244 int i = a->vint; 1245 TriangleAdjacent ta(t,EdgesVertexTriangle[i][0]); // Previous edge 1246 if (!t || i<0 || i>=3){ 1247 throw ErrorException(__FUNCT__,exprintf("!t || i<0 !! i>=3")); 1248 } 1249 if ( a!=(*t)(i)){ 1250 throw ErrorException(__FUNCT__,exprintf("a!=(*t)(i)")); 1251 } 1252 int k=0; 1253 do { // turn around vertex in direct sens (trigo) 1254 k++; 1255 if (k>=20000){ 1256 throw ErrorException(__FUNCT__,exprintf("k>=20000")); 1257 } 1258 // in no crack => ta.EdgeVertex(1) == a otherwise ??? 1259 if (ta.EdgeVertex(1) == a && ta.EdgeVertex(0) == b) return ta; // find 1260 ta = ta.Adj(); 1261 if (ta.EdgeVertex(0) == a && ta.EdgeVertex(1) == b) return ta; // find 1262 --ta; 1263 } while (t != (Triangle *)ta); 1264 throw ErrorException(__FUNCT__,exprintf("FindTriangleAdjacent: triangle not found")); 1265 return TriangleAdjacent(0,0);//for compiler 1266 } 1267 1268 inline Vertex * TheVertex(Vertex * a) // give a unique vertex with smallest number 1269 { // in case on crack in mesh 1270 Vertex * r(a), *rr; 1271 Triangle * t = a->t; 1272 int i = a->vint; 1273 TriangleAdjacent ta(t,EdgesVertexTriangle[i][0]); // Previous edge 1274 if (!t || i<0 || i>=3){ 1275 throw ErrorException(__FUNCT__,exprintf("!t || i<0 !! i>=3")); 1276 } 1277 if ( a!=(*t)(i)){ 1278 throw ErrorException(__FUNCT__,exprintf("a!=(*t)(i)")); 1279 } 1280 int k=0; 1281 do { // turn around vertex in direct sens (trigo) 1282 k++; 1283 if (k>=20000){ 1284 throw ErrorException(__FUNCT__,exprintf("k>=20000")); 1285 } 1286 // in no crack => ta.EdgeVertex(1) == a 1287 if ((rr=ta.EdgeVertex(0)) < r) r = rr; 1288 ta = ta.Adj(); 1289 if ((rr=ta.EdgeVertex(1)) < r) r =rr; 1290 --ta; 1291 } while (t != (Triangle*) ta); 1292 return r; 1293 } 1322 1294 } 1323 1295 #endif -
issm/trunk/src/c/Bamgx/objects/Triangles.cpp
r2865 r2870 20 20 long NbUnSwap =0; 21 21 int Triangles::counter = 0; 22 Triangles* CurrentTh= 0; //To delete22 Triangles* CurrentTh=NULL; //To delete 23 23 24 24 /*Constructors/Destructors*/
Note:
See TracChangeset
for help on using the changeset viewer.