Changeset 2811


Ignore:
Timestamp:
01/12/10 16:50:43 (15 years ago)
Author:
Mathieu Morlighem
Message:

moved Triangles routines of Mesh2.cpp to Triangles.cpp

Location:
issm/trunk/src/c/Bamgx
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk/src/c/Bamgx/Mesh2.cpp

    r2810 r2811  
    4949        int hinterpole=1;
    5050
    51 
    52         long NbUnSwap =0;
    5351        int  ForDebugging = 0;
    5452        const Direction NoDirOfSearch = Direction();
     
    428426                        return er;
    429427                }
    430 
    431 
    432 
    433                 Metric Triangles::MetricAt  (const R2 & A) const
    434                 { //if ((vertices <= &v) && (vertices < v+nbv)) return v.m;
    435                         I2 a = toI2(A);
    436                         Icoor2 deta[3];
    437                         Triangle * t =FindTriangleContening(a,deta);
    438                         if (t->det <0) { // outside
    439                                 double ba,bb;
    440                                 TriangleAdjacent edge= CloseBoundaryEdge(a,t,ba,bb) ;
    441                                 return Metric(ba,*edge.EdgeVertex(0),bb,*edge.EdgeVertex(1));}
    442                         else { // inside
    443                                 Real8   aa[3];
    444                                 Real8 s = deta[0]+deta[1]+deta[2];
    445                                 aa[0]=deta[0]/s;
    446                                 aa[1]=deta[1]/s;
    447                                 aa[2]=deta[2]/s;
    448                                 return Metric(aa,(*t)[0],(*t)[1],(*t)[2]);
    449                         }
    450                 }
    451428
    452429
     
    988965
    989966
    990                 int Triangle::swap(Int2 a,int koption){
    991                         if(a/4 !=0) return 0;// arete lock or MarkUnSwap
    992 
    993                         register Triangle *t1=this,*t2=at[a];// les 2 triangles adjacent
    994                         register Int1 a1=a,a2=aa[a];// les 2 numero de l arete dans les 2 triangles
    995                         if(a2/4 !=0) return 0; // arete lock or MarkUnSwap
    996 
    997                         register Vertex  *sa=t1->ns[VerticesOfTriangularEdge[a1][0]];
    998                         register Vertex  *sb=t1->ns[VerticesOfTriangularEdge[a1][1]];
    999                         register Vertex  *s1=t1->ns[OppositeVertex[a1]];
    1000                         register Vertex  *s2=t2->ns[OppositeVertex[a2]];
    1001 
    1002                         Icoor2 det1=t1->det , det2=t2->det ;
    1003                         Icoor2 detT = det1+det2;
    1004                         Icoor2 detA = Abs(det1) + Abs(det2);
    1005                         Icoor2 detMin = Min(det1,det2);
    1006 
    1007                         int OnSwap = 0;       
    1008                         // si 2 triangle infini (bord) => detT = -2;
    1009                         if (sa == 0) {// les deux triangles sont frontieres
    1010                                 det2=bamg::det(s2->i,sb->i,s1->i);
    1011                                 OnSwap = det2 >0;}
    1012                         else if (sb == 0) { // les deux triangles sont frontieres
    1013                                 det1=bamg::det(s1->i,sa->i,s2->i);
    1014                                 OnSwap = det1 >0;}
    1015                         else if(( s1 != 0) && (s2 != 0) ) {
    1016                                 det1 = bamg::det(s1->i,sa->i,s2->i);
    1017                                 det2 = detT - det1;
    1018                                 OnSwap = (Abs(det1) + Abs(det2)) < detA;
    1019 
    1020                                 Icoor2 detMinNew=Min(det1,det2);
    1021                                 //     if (detMin<0 && (Abs(det1) + Abs(det2) == detA)) OnSwap=BinaryRand();// just for test   
    1022                                 if (! OnSwap &&(detMinNew>0)) {
    1023                                         OnSwap = detMin ==0;
    1024                                         if (! OnSwap) {
    1025                                                 int  kopt = koption;
    1026                                                 while (1)
    1027                                                         if(kopt) {
    1028                                                                 // critere de Delaunay pure isotrope
    1029                                                                 register Icoor2 xb1 = sb->i.x - s1->i.x,
    1030                                                                                  x21 = s2->i.x - s1->i.x,
    1031                                                                                  yb1 = sb->i.y - s1->i.y,
    1032                                                                                  y21 = s2->i.y - s1->i.y,
    1033                                                                                  xba = sb->i.x - sa->i.x,
    1034                                                                                  x2a = s2->i.x - sa->i.x,
    1035                                                                                  yba = sb->i.y - sa->i.y,
    1036                                                                                  y2a = s2->i.y - sa->i.y;
    1037                                                                 register double
    1038                                                                         cosb12 =  double(xb1*x21 + yb1*y21),
    1039                                                                                    cosba2 =  double(xba*x2a + yba*y2a) ,
    1040                                                                                    sinb12 = double(det2),
    1041                                                                                    sinba2 = double(t2->det);
    1042 
    1043 
    1044                                                                 // angle b12 > angle ba2 => cotg(angle b12) < cotg(angle ba2)
    1045                                                                 OnSwap =  ((double) cosb12 * (double)  sinba2) <  ((double) cosba2 * (double) sinb12);
    1046                                                                 //       if(CurrentTh)
    1047                                                                 //         cout << "swap " << CurrentTh->Number(sa) << " " << CurrentTh->Number(sb) << " " ;
    1048                                                                 //       cout <<  cosb12 << " " <<  sinba2 << " "  <<  cosba2 << " " << sinb12
    1049                                                                 //            << " Onswap = " <<  OnSwap << endl;
    1050                                                                 break;
    1051                                                         }
    1052                                                         else
    1053                                                         {       
    1054                                                                 // critere de Delaunay anisotrope
    1055                                                                 Real8 som;
    1056                                                                 I2 AB=(I2) *sb - (I2) *sa;
    1057                                                                 I2 MAB2=((I2) *sb + (I2) *sa);
    1058                                                                 R2 MAB(MAB2.x*0.5,MAB2.y*0.5);
    1059                                                                 I2 A1=(I2) *s1 - (I2) *sa;
    1060                                                                 I2 D = (I2) * s1 - (I2) * sb ;
    1061                                                                 R2 S2(s2->i.x,s2->i.y);
    1062                                                                 R2 S1(s1->i.x,s1->i.y);
    1063                                                                 {
    1064                                                                         Metric M=s1->m;
    1065                                                                         R2 ABo = M.Orthogonal(AB);
    1066                                                                         R2 A1o = M.Orthogonal(A1);
    1067                                                                         // (A+B)+ x ABo = (S1+B)/2+ y A1
    1068                                                                         // ABo x - A1o y =  (S1+B)/2-(A+B)/2 = (S1-B)/2 = D/2
    1069                                                                         double dd = Abs(ABo.x*A1o.y)+Abs(ABo.y*A1o.x);
    1070                                                                         double d = (ABo.x*A1o.y - ABo.y*A1o.x)*2; // because D/2
    1071                                                                         if (Abs(d) > dd*1.e-3) {
    1072                                                                                 R2 C(MAB+ABo*((D.x*A1o.y - D.y*A1o.x)/d));
    1073                                                                                 som  = M(C - S2)/M(C - S1);
    1074                                                                         } else
    1075                                                                         {kopt=1;continue;}
    1076 
    1077                                                                 }
    1078                                                                 {
    1079                                                                         Metric M=s2->m;
    1080                                                                         R2 ABo = M.Orthogonal(AB);
    1081                                                                         R2 A1o = M.Orthogonal(A1);
    1082                                                                         // (A+B)+ x ABo = (S1+B)/2+ y A1
    1083                                                                         // ABo x - A1o y =  (S1+B)/2-(A+B)/2 = (S1-B)/2 = D/2
    1084                                                                         double dd = Abs(ABo.x*A1o.y)+Abs(ABo.y*A1o.x);
    1085                                                                         double d = (ABo.x*A1o.y - ABo.y*A1o.x)*2; // because D/2
    1086                                                                         if(Abs(d) > dd*1.e-3) {
    1087                                                                                 R2 C(MAB+ABo*((D.x*A1o.y - D.y*A1o.x)/d));
    1088                                                                                 som  += M(C - S2)/M(C -  S1);
    1089                                                                         } else
    1090                                                                         {kopt=1;continue;}
    1091                                                                 }
    1092                                                                 OnSwap = som < 2;
    1093                                                                 break;
    1094                                                         }
    1095 
    1096                                         } // OnSwap
    1097                                 } // (! OnSwap &&(det1 > 0) && (det2 > 0) )
    1098                         }
    1099                         if( OnSwap )
    1100                                 bamg::swap(t1,a1,t2,a2,s1,s2,det1,det2);
    1101                         else {
    1102                                 NbUnSwap ++;
    1103                                 t1->SetMarkUnSwap(a1);     
    1104                         }
    1105                         return OnSwap;
    1106                 }
     967
    1107968
    1108969                Real8  Vertex::Smoothing(Triangles & Th,const Triangles & BTh,Triangle  * & tstart ,Real8 omega)
     
    12131074                }
    12141075
    1215 
    1216 
    1217 
    1218                 void Triangles::Add( Vertex & s,Triangle * t, Icoor2 * det3)
    1219                 {
    1220                         // -------------------------------------------
    1221                         //             s2
    1222                         //                                            !
    1223                         //             /|\                            !
    1224                         //            / | \                           !
    1225                         //           /  |  \                          !
    1226                         //    tt1   /   |   \ tt0                     !
    1227                         //         /    |s   \                        !
    1228                         //        /     .     \                       !
    1229                         //       /  .      `   \                      !
    1230                         //      / .           ` \                     !
    1231                         //      ----------------                      !
    1232                         //   s0       tt2       s1
    1233                         //--------------------------------------------
    1234 
    1235                         Triangle * tt[3]; // the 3 new Triangles
    1236                         Vertex &s0 = (* t)[0], &s1=(* t)[1], &s2=(* t)[2];
    1237                         Icoor2  det3local[3];
    1238                         int infv = &s0 ?  ((  &s1 ? ( &s2  ? -1 : 2) : 1  )) : 0;
    1239                         // infv = ordre of the infini vertex (null)
    1240                         register int nbd0 =0; // number of zero det3
    1241                         register int izerodet=-1,iedge; // izerodet = egde contening the vertex s
    1242                         Icoor2 detOld = t->det;
    1243 
    1244                         if ( ( infv <0 ) && (detOld <0) ||  ( infv >=0  ) && (detOld >0) )
    1245                         {
    1246                                 cerr << "  infv " << infv << " det = " << detOld << endl;
    1247                                 cerr << Number(s) << " "<< Number(s0) << " " 
    1248                                         << Number(s1) << " "  << Number(s2) << endl;
    1249                                 MeshError(3);
    1250                         }
    1251 
    1252                         // if det3 do not exist then constuct det3
    1253                         if (!det3) {
    1254                                 det3 = det3local; // alloc
    1255                                 if ( infv<0 ) {
    1256                                         det3[0]=bamg::det(s ,s1,s2);
    1257                                         det3[1]=bamg::det(s0,s ,s2);
    1258                                         det3[2]=bamg::det(s0,s1,s );}
    1259                                 else {
    1260                                         // one of &s1  &s2  &s0 is NULL so (&si || &sj) <=> !&sk
    1261                                         det3[0]=  &s0 ? -1  : bamg::det(s ,s1,s2) ;
    1262                                         det3[1]=  &s1 ? -1 : bamg::det(s0,s ,s2) ;
    1263                                         det3[2]=  &s2 ? -1 : bamg::det(s0,s1,s ) ;}}
    1264 
    1265 
    1266                                         if (!det3[0]) izerodet=0,nbd0++;
    1267                                         if (!det3[1]) izerodet=1,nbd0++;
    1268                                         if (!det3[2]) izerodet=2,nbd0++;
    1269 
    1270                                         if  (nbd0 >0 ) // point s on a egde or on a vertex
    1271                                                 if (nbd0 == 1) {
    1272                                                         iedge = OppositeEdge[izerodet];
    1273                                                         TriangleAdjacent ta = t->Adj(iedge);
    1274 
    1275                                                         // the point is on the edge
    1276                                                         // if the point is one the boundary
    1277                                                         // add the point in outside part
    1278                                                         if ( t->det >=0) { // inside triangle
    1279                                                                 if ((( Triangle *) ta)->det < 0 ) {
    1280                                                                         // add in outside triangle
    1281                                                                         Add(s,( Triangle *) ta);
    1282                                                                         return;}
    1283                                                         }}
    1284                                                 else {
    1285                                                         cerr << " bug  " << nbd0 <<endl;
    1286                                                         cerr << " Bug double points in " << endl ;
    1287                                                         cerr << " s = " << Number(s) << " " <<  s << endl;
    1288                                                         cerr << " s0 = "<< Number(s0) << " "  << s0 << endl;
    1289                                                         cerr << " s1 = "<< Number(s1) << " "  << s1 << endl;
    1290                                                         cerr << " s2 = "<< Number(s2) << " "  << s2 << endl;
    1291                                                         MeshError(5,this);}
    1292 
    1293                                                         // remove de MarkUnSwap edge
    1294                                                         t->SetUnMarkUnSwap(0);     
    1295                                                         t->SetUnMarkUnSwap(1);     
    1296                                                         t->SetUnMarkUnSwap(2);
    1297 
    1298                                                         tt[0]= t;
    1299                                                         tt[1]= &triangles[nbt++];
    1300                                                         tt[2]= &triangles[nbt++];
    1301 
    1302                                                         if (nbt>nbtx) {
    1303                                                                 cerr << " No enougth triangles " << endl;
    1304                                                                 MeshError(999,this);
    1305                                                         }
    1306 
    1307                                                         *tt[1]=   *tt[2]= *t;
    1308                                                         // gestion of the link
    1309                                                         tt[0]->link=tt[1];
    1310                                                         tt[1]->link=tt[2];
    1311 
    1312                                                         (* tt[0])(OppositeVertex[0])=&s;
    1313                                                         (* tt[1])(OppositeVertex[1])=&s;
    1314                                                         (* tt[2])(OppositeVertex[2])=&s;
    1315 
    1316                                                         tt[0]->det=det3[0];
    1317                                                         tt[1]->det=det3[1];
    1318                                                         tt[2]->det=det3[2];         
    1319 
    1320                                                         //  update adj des triangles externe
    1321                                                         tt[0]->SetAdjAdj(0);
    1322                                                         tt[1]->SetAdjAdj(1);
    1323                                                         tt[2]->SetAdjAdj(2);
    1324                                                         //  update des adj des 3 triangle interne
    1325                                                         const int i0 = 0;
    1326                                                         const int i1= NextEdge[i0];
    1327                                                         const int i2 = PreviousEdge[i0];
    1328 
    1329                                                         tt[i0]->SetAdj2(i2,tt[i2],i0);
    1330                                                         tt[i1]->SetAdj2(i0,tt[i0],i1);
    1331                                                         tt[i2]->SetAdj2(i1,tt[i1],i2);
    1332 
    1333                                                         tt[0]->SetTriangleContainingTheVertex();
    1334                                                         tt[1]->SetTriangleContainingTheVertex();
    1335                                                         tt[2]->SetTriangleContainingTheVertex();
    1336 
    1337 
    1338                                                         // swap if the point s is on a edge
    1339                                                         if(izerodet>=0) {
    1340                                                                 //  cout << " the point s is on a edge =>swap " << iedge << " "  << *tt[izerodet] << endl;
    1341                                                                 int rswap =tt[izerodet]->swap(iedge);
    1342 
    1343                                                                 if (!rswap)
    1344                                                                 {
    1345                                                                         cout << " Pb swap the point s is on a edge =>swap " << iedge << " "  << *tt[izerodet] << endl;
    1346                                                                 }
    1347                                                                 assert(rswap);
    1348                                                         }
    1349                 }
    1350 
    1351 
    1352                 Int4  Triangles::SplitInternalEdgeWithBorderVertices()
    1353                 {
    1354                         Int4 NbSplitEdge=0;
    1355                         SetVertexFieldOn(); 
    1356                         Int4 it;
    1357                         Int4 nbvold=nbv;
    1358                         long int verbosity=2;
    1359                         for (it=0;it<nbt;it++)
    1360                         {
    1361                                 Triangle &t=triangles[it];
    1362                                 if (t.link)
    1363                                         for (int j=0;j<3;j++)
    1364                                                 if(!t.Locked(j) && !t.Hidden(j)){
    1365                                                         Triangle &tt = *t.TriangleAdj(j);
    1366                                                         if ( &tt && tt.link && it < Number(tt))
    1367                                                         { // an internal edge
    1368                                                                 Vertex &v0 = t[VerticesOfTriangularEdge[j][0]];
    1369                                                                 Vertex &v1 = t[VerticesOfTriangularEdge[j][1]];
    1370                                                                 if (v0.on && v1.on)
    1371                                                                 {
    1372                                                                         R2 P= ((R2) v0 + (R2) v1)*0.5;
    1373                                                                         if ( nbv<nbvx) {
    1374                                                                                 vertices[nbv].r = P;
    1375                                                                                 vertices[nbv++].m = Metric(0.5,v0.m,0.5,v1.m);
    1376                                                                                 vertices[nbv].ReferenceNumber=0;
    1377                                                                                 vertices[nbv].DirOfSearch = NoDirOfSearch ;
    1378                                                                         }
    1379                                                                         NbSplitEdge++;
    1380                                                                         if (verbosity>7)
    1381                                                                                 cout <<" Internal edge with two vertices on boundary"
    1382                                                                                         << Number(v0) << " " << Number(v1) << " by " <<  endl;
    1383                                                                 }
    1384                                                         }
    1385                                                 }
    1386                         }
    1387                         ReMakeTriangleContainingTheVertex();   
    1388                         if (nbvold!=nbv)
    1389                         {
    1390                                 Int4  iv = nbvold;
    1391                                 Int4 NbSwap = 0;
    1392                                 Icoor2 dete[3]; 
    1393                                 for (Int4 i=nbvold;i<nbv;i++)
    1394                                 {// for all the new point
    1395                                         Vertex & vi = vertices[i];
    1396                                         vi.i = toI2(vi.r);
    1397                                         vi.r = toR2(vi.i);
    1398                                         //      if (!quadtree->ToClose(vi,seuil,hi,hj)) {
    1399                                         // a good new point
    1400                                         vi.ReferenceNumber=0;
    1401                                         vi.DirOfSearch =NoDirOfSearch;
    1402                                         //      cout << " Add " << Number(vi) << " " << vi
    1403                                         // << "   " <<  Number(vi) << " <--> " << Number(vi) <<endl;
    1404                                         Triangle *tcvi = FindTriangleContening(vi.i,dete);
    1405                                         if (tcvi && !tcvi->link) {
    1406                                                 cout << i <<  " PB insert point " << Number(vi) << vi << Number(vi)
    1407                                                         << " tcvi = " << tcvi << " " << tcvi->link << endl;
    1408                                                 cout << (*tcvi)[1] <<  (*tcvi)[2] << endl;
    1409                                                 tcvi = FindTriangleContening(vi.i,dete);
    1410                                                 cout << (*tcvi)[1] <<  (*tcvi)[2] << endl;
    1411                                                 MeshError(1001,this);
    1412                                         }
    1413 
    1414 
    1415                                         quadtree->Add(vi);
    1416                                         assert (tcvi && tcvi->det >= 0) ;// internal
    1417                                         Add(vi,tcvi,dete);
    1418                                         NbSwap += vi.Optim(1);         
    1419                                         iv++;
    1420                                         //      }
    1421                                 }
    1422                                 if (verbosity>3)
    1423                                 {
    1424                                         cout << "    Nb Of New Point " << iv ;
    1425                                         cout << " Nb swap = " << NbSwap << " to  split internal edges with border vertices" ;}
    1426 
    1427                                         nbv = iv;
    1428                         }
    1429                         if (NbSplitEdge >  nbv-nbvold)
    1430                                 cout << " Warning not enough vertices  to split all internal edges "  << endl
    1431                                         << "    we lost " << NbSplitEdge - ( nbv-nbvold) << " Edges Sorry " << endl;
    1432                         if (verbosity>2)
    1433                                 cout << "SplitInternalEdgeWithBorderVertices: Number of splited edge " << NbSplitEdge << endl;
    1434                         return  NbSplitEdge;
    1435                 }
    1436                 Int4 Triangles::InsertNewPoints(Int4 nbvold,Int4 & NbTSwap)
    1437                 {
    1438                         long int verbosity=2;
    1439                         Real8 seuil= 1.414/2 ;// for two close point
    1440                         Int4 i;
    1441                         // insertion part ---
    1442 
    1443                         const Int4 nbvnew = nbv-nbvold;
    1444                         if (verbosity>5)
    1445                                 cout << "    Try to Insert the " <<nbvnew<< " new points " << endl; 
    1446                         Int4 NbSwap=0;
    1447                         Icoor2 dete[3];
    1448 
    1449                         // construction d'un ordre aleatoire
    1450                         if (! nbvnew)
    1451                                 return 0;
    1452                         if (nbvnew) {
    1453                                 const Int4 PrimeNumber= AGoodNumberPrimeWith(nbv)  ;
    1454                                 Int4 k3 = rand()%nbvnew ;
    1455                                 for (Int4 is3=0; is3<nbvnew; is3++) {
    1456                                         register Int4 j = nbvold +(k3 = (k3 + PrimeNumber)% nbvnew);
    1457                                         register Int4 i = nbvold+is3;
    1458                                         ordre[i]= vertices + j;
    1459                                         ordre[i]->ReferenceNumber=i;
    1460                                 }
    1461                                 // be carefull
    1462                                 Int4  iv = nbvold;
    1463                                 for (i=nbvold;i<nbv;i++)
    1464                                 {// for all the new point
    1465                                         Vertex & vi = *ordre[i];
    1466                                         vi.i = toI2(vi.r);
    1467                                         vi.r = toR2(vi.i);
    1468                                         Real4 hx,hy;
    1469                                         vi.m.Box(hx,hy);
    1470                                         Icoor1 hi=(Icoor1) (hx*coefIcoor),hj=(Icoor1) (hy*coefIcoor);
    1471                                         if (!quadtree->ToClose(vi,seuil,hi,hj))
    1472                                         {
    1473                                                 // a good new point
    1474                                                 Vertex & vj = vertices[iv];
    1475                                                 Int4 j = vj.ReferenceNumber;
    1476                                                 assert( &vj== ordre[j]);
    1477                                                 if(i!=j)
    1478                                                 { //  for valgring
    1479                                                         Exchange(vi,vj);
    1480                                                         Exchange(ordre[j],ordre[i]);
    1481                                                 }
    1482                                                 vj.ReferenceNumber=0;
    1483                                                 //      cout << " Add " << Number(vj) << " " << vj
    1484                                                 // << "   " <<  Number(vi) << " <--> " << Number(vj) <<endl;
    1485                                                 Triangle *tcvj = FindTriangleContening(vj.i,dete);
    1486                                                 if (tcvj && !tcvj->link)
    1487                                                 {
    1488                                                         cerr << i <<  " PB insert point " << Number(vj) << vj << Number(vi)
    1489                                                                 << " tcvj = " << tcvj << " " << tcvj->link << endl;
    1490                                                         cerr << (*tcvj)[1] <<  (*tcvj)[2] << endl;
    1491                                                         tcvj = FindTriangleContening(vj.i,dete);
    1492                                                         cout << (*tcvj)[1] <<  (*tcvj)[2] << endl;
    1493                                                         MeshError(1001,this);
    1494                                                 }
    1495 
    1496 
    1497                                                 quadtree->Add(vj);
    1498                                                 assert (tcvj && tcvj->det >= 0) ;// internal
    1499                                                 Add(vj,tcvj,dete);
    1500                                                 NbSwap += vj.Optim(1);         
    1501                                                 iv++;
    1502                                         }
    1503                                 }
    1504                                 if (verbosity>3) {
    1505                                         cout << "    Nb Of New Point " << iv << " Nb Of To close Points " << nbv-iv ;
    1506                                         cout << " Nb swap = " << NbSwap << " after " ;}
    1507 
    1508                                         nbv = iv;
    1509                         }
    1510 
    1511                         for (i=nbvold;i<nbv;i++)
    1512                                 NbSwap += vertices[i].Optim(1); 
    1513                         if (verbosity>3)
    1514                                 cout << " NbSwap = " <<  NbSwap << endl;
    1515 
    1516 
    1517                         NbTSwap +=  NbSwap ;
    1518                         return nbv-nbvold;
    1519 
    1520                 }
    1521                 void  Triangles::NewPoints(Triangles & Bh,int KeepBackVertex)
    1522                 { // Triangles::NewPoints
    1523                         long int verbosity=2;
    1524                         Int4 nbtold(nbt),nbvold(nbv);
    1525                         if (verbosity>2)
    1526                                 cout << "  -- Triangles::NewPoints ";
    1527                         if (verbosity>3)cout <<  " nbv (in)  on Boundary  = " << nbv  <<endl;
    1528                         Int4 i,k;
    1529                         int j;
    1530                         Int4 *first_np_or_next_t = new Int4[nbtx];
    1531                         Int4 NbTSwap =0;
    1532                         //    insert old point
    1533                         nbtold = nbt;
    1534 
    1535                         if (KeepBackVertex && (&Bh != this) && (nbv+Bh.nbv< nbvx))
    1536                         {
    1537                                 //   Bh.SetVertexFieldOn();
    1538                                 for (i=0;i<Bh.nbv;i++)
    1539                                 {
    1540                                         Vertex & bv = Bh[i];
    1541                                         if (!bv.on) {
    1542                                                 vertices[nbv].r = bv.r;
    1543                                                 vertices[nbv++].m = bv.m;}
    1544                                 }
    1545                                 int nbv1=nbv;
    1546                                 Bh.ReMakeTriangleContainingTheVertex();     
    1547                                 InsertNewPoints(nbvold,NbTSwap)   ;           
    1548                                 if (verbosity>2)
    1549                                         cout <<  "      (Nb of Points from background mesh  = "
    1550                                                 << nbv-nbvold  << " / " << nbv1-nbvold << ")" << endl;
    1551                         } 
    1552                         else
    1553                                 Bh.ReMakeTriangleContainingTheVertex();     
    1554 
    1555                         Triangle *t;
    1556                         // generation of the list of next Triangle
    1557                         // at 1 time we test all the triangles
    1558                         Int4 Headt =0,next_t;
    1559                         for(i=0;i<nbt;i++)
    1560                                 first_np_or_next_t[i]=-(i+1);
    1561                         // end list i >= nbt
    1562                         // the list of test triangle is
    1563                         // the next traingle on i is  -first_np_or_next_t[i]
    1564                         int iter=0;
    1565                         // Big loop
    1566                         do {
    1567                                 iter++;
    1568                                 nbtold = nbt;
    1569                                 nbvold = nbv;
    1570 
    1571                                 // default size of  IntersectionTriangle
    1572 
    1573                                 i=Headt;
    1574                                 next_t=-first_np_or_next_t[i];
    1575                                 for(t=&triangles[i];i<nbt;t=&triangles[i=next_t],next_t=-first_np_or_next_t[i])
    1576                                 { // for each triangle  t
    1577                                         // we can change first_np_or_next_t[i]
    1578                                         //      cout << " Do the triangle " << i << " Next_t=" << next_t << endl;
    1579                                         assert(i>=0 && i < nbt );
    1580                                         first_np_or_next_t[i] = iter;
    1581                                         for(j=0;j<3;j++)
    1582                                         { // for each edge
    1583                                                 TriangleAdjacent tj(t,j);
    1584                                                 Vertex & vA = * tj.EdgeVertex(0);
    1585                                                 Vertex & vB = * tj.EdgeVertex(1);
    1586 
    1587                                                 if (!t->link) continue;// boundary
    1588                                                 if (t->det <0) continue;
    1589                                                 if (t->Locked(j)) continue;
    1590 
    1591                                                 TriangleAdjacent tadjj = t->Adj(j);       
    1592                                                 Triangle * ta= tadjj;
    1593 
    1594                                                 if (ta->det <0) continue;         
    1595 
    1596                                                 R2 A = vA;
    1597                                                 R2 B = vB;
    1598 
    1599                                                 k=Number(ta);
    1600 
    1601                                                 if(first_np_or_next_t[k]==iter)  // this edge is done before
    1602                                                         continue; // next edge of the triangle
    1603 
    1604                                                 //const Int4 NbvOld = nbv;
    1605                                                 lIntTria.SplitEdge(Bh,A,B);
    1606                                                 lIntTria.NewPoints(vertices,nbv,nbvx);
    1607                                         } // end loop for each edge
    1608 
    1609                                 }// for triangle   
    1610 
    1611                                 if (!InsertNewPoints(nbvold,NbTSwap))
    1612                                         break;
    1613 
    1614                                 for (i=nbtold;i<nbt;i++)
    1615                                         first_np_or_next_t[i]=iter;
    1616 
    1617                                 Headt = nbt; // empty list
    1618                                 for (i=nbvold;i<nbv;i++)
    1619                                 { // for all the triangle contening the vertex i
    1620                                         Vertex * s  = vertices + i;
    1621                                         TriangleAdjacent ta(s->t, EdgesVertexTriangle[s->vint][1]);
    1622                                         Triangle * tbegin= (Triangle*) ta;
    1623                                         Int4 kt;
    1624                                         do {
    1625                                                 kt = Number((Triangle*) ta);
    1626                                                 if (first_np_or_next_t[kt]>0)
    1627                                                         first_np_or_next_t[kt]=-Headt,Headt=kt;
    1628                                                 assert( ta.EdgeVertex(0) == s);
    1629                                                 ta = Next(Adj(ta));
    1630                                         } while ( (tbegin != (Triangle*) ta));
    1631                                 }   
    1632 
    1633                         } while (nbv!=nbvold);
    1634 
    1635                         delete []  first_np_or_next_t;
    1636 
    1637                         Int4 NbSwapf =0,NbSwp;
    1638 
    1639                         // bofbof
    1640 
    1641 
    1642                         NbSwp = NbSwapf;
    1643                         for (i=0;i<nbv;i++)
    1644                                 NbSwapf += vertices[i].Optim(0);
    1645                         /*
    1646                            for (i=0;i<nbv;i++)
    1647                            NbSwapf += vertices[i].Optim(0);
    1648                            for (i=0;i<nbv;i++)
    1649                            NbSwapf += vertices[i].Optim(0);
    1650                            for (i=0;i<nbv;i++)
    1651                            NbSwapf += vertices[i].Optim(0);
    1652                            for (i=0;i<nbv;i++)
    1653                            NbSwapf += vertices[i].Optim(0);
    1654                            */
    1655                         NbTSwap +=  NbSwapf ;
    1656                         if (verbosity>3) cout << "   " ;
    1657                         if (verbosity>2)
    1658                                 cout << " Nb Of Vertices =" << nbv << " Nb of triangles = " << nbt-NbOutT
    1659                                         << " NbSwap final = " << NbSwapf << " Nb Total Of Swap = " << NbTSwap << endl;
    1660 
    1661 
    1662                 }
    1663 
    1664                 void  Triangles::NewPointsOld(Triangles & Bh)
    1665                 { // Triangles::NewPointsOld
    1666                         long int verbosity=2;
    1667                         Real8 seuil= 0.7 ;// for two neart point
    1668                         if (verbosity>1)
    1669                                 cout << " begin :  Triangles::NewPointsOld " << endl;
    1670                         Int4 i,k;
    1671                         int j;
    1672                         Int4 BeginNewPoint[3];
    1673                         Int4 EndNewPoint[3];
    1674 #ifdef TRACETRIANGLE
    1675                         Int4 trace=0;
    1676 #endif
    1677                         int step[3];
    1678                         Int4 *first_np_or_next_t = new Int4[nbtx];
    1679                         Int4 ColorEdge[3];
    1680                         Int4 color=-1;
    1681                         Triangle *t;
    1682                         // generation of the list of next Triangle
    1683                         // at 1 time we test all the triangles
    1684                         Int4 Headt =0,next_t;
    1685                         for(i=0;i<nbt;i++)
    1686                                 first_np_or_next_t[i]=-(i+1);
    1687                         // end list i >= nbt
    1688                         // the list of test triangle is
    1689                         // the next Triangle on i is  -first_np_or_next_t[i]
    1690                         Int4 nbtold,nbvold;
    1691 
    1692                         // Big loop
    1693                         do {
    1694                                 nbtold = nbt;
    1695                                 nbvold = nbv;
    1696                                 // default size of  IntersectionTriangle
    1697 
    1698                                 i=Headt;
    1699                                 next_t=-first_np_or_next_t[i];
    1700                                 for(t=&triangles[i];i<nbt;t=&triangles[i=next_t],next_t=-first_np_or_next_t[i])
    1701                                 { // for each triangle  t
    1702                                         // we can change first_np_or_next_t[i]
    1703 #ifdef TRACETRIANGLE
    1704                                         trace =  TRACETRIANGLE <0 ? 1 : i == TRACETRIANGLE;
    1705 #endif
    1706                                         //      cout << " Do the triangle " << i << " Next_t=" << next_t << endl;
    1707                                         assert(i>=0 && i < nbt );
    1708                                         first_np_or_next_t[i] = nbv; // to save the fist new point of triangle
    1709                                         for(j=0;j<3;j++)
    1710                                         { // for each edge
    1711                                                 TriangleAdjacent tj(t,j);
    1712                                                 // color++;// the color is 3i+j
    1713                                                 color = 3*i + j ;;
    1714                                                 ColorEdge[j]=color;
    1715                                                 BeginNewPoint[j]=nbv;
    1716                                                 EndNewPoint[j]=nbv-1;
    1717                                                 step[j]=1;// right sens
    1718                                                 Vertex & vA = * tj.EdgeVertex(0);
    1719                                                 Vertex & vB = * tj.EdgeVertex(1);
    1720 
    1721 #ifdef TRACETRIANGLE
    1722                                                 if(trace) {
    1723                                                         cout << " i " << Number(vA) <<" j "<<  Number(vB)
    1724                                                                 << " "  << t->Locked(j) ;
    1725                                                 }
    1726 #endif
    1727                                                 if (!t->link) continue;// boundary
    1728                                                 if (t->det <0) continue;
    1729                                                 if (t->Locked(j)) continue;
    1730 
    1731                                                 TriangleAdjacent tadjj = t->Adj(j);       
    1732                                                 Triangle * ta= tadjj;
    1733 
    1734                                                 if (ta->det <0) continue;         
    1735 
    1736                                                 R2 A = vA;
    1737                                                 R2 B = vB;
    1738 
    1739                                                 k=Number(ta);
    1740                                                 // the 2 opposite vertices
    1741                                                 const Vertex & vC1  =  *tj.OppositeVertex();
    1742                                                 const Vertex & vC2 = *tadjj.OppositeVertex();
    1743 
    1744 #ifdef TRACETRIANGLE
    1745                                                 trace = trace || k == TRACETRIANGLE;
    1746                                                 if(trace) {
    1747                                                         cout << "Test Arete " << i << " AB = " << A << B
    1748                                                                 << "i "  <<Number(vA)<< "j" <<Number(vB);
    1749                                                         cout << " link" <<(int)t->link << " ta=" << Number( ta)
    1750                                                                 << " det " <<ta->det ;
    1751                                                         cout << " hA = " <<vA.m.h << " hB = " <<vB.m.h ;
    1752                                                         cout << " loc " << ta->Locked(j) << endl;
    1753                                                 }
    1754 #endif
    1755 
    1756                                                 if(first_np_or_next_t[k]>0) { // this edge is done before
    1757                                                         // find the color of the edge and begin , end of newpoint
    1758                                                         register int kk = t->NuEdgeTriangleAdj(j);
    1759                                                         assert ((*t)(VerticesOfTriangularEdge[j][0]) == (*ta)(VerticesOfTriangularEdge[kk][1]));
    1760                                                         assert ((*t)(VerticesOfTriangularEdge[j][1]) == (*ta)(VerticesOfTriangularEdge[kk][0]));
    1761                                                         register Int4 kolor =3*k + kk;
    1762                                                         ColorEdge[j]=kolor;
    1763                                                         register Int4 kkk= 1;
    1764                                                         step[j]=-1;// other sens
    1765                                                         BeginNewPoint[j]=0;
    1766                                                         EndNewPoint[j]=-1; // empty list         
    1767                                                         for (Int4 iv=first_np_or_next_t[k];iv<nbv;iv++)
    1768                                                                 if (vertices[iv].color > kolor)
    1769                                                                         break; // the color is passed           
    1770                                                                 else if (vertices[iv].color == kolor) {
    1771                                                                         EndNewPoint[j]=iv;
    1772                                                                         if (kkk) // one time test
    1773                                                                                 kkk=0,BeginNewPoint[j]=iv;}
    1774                                                                         continue; // next edge of the triangle
    1775                                                 } // end  if( k < i)
    1776 
    1777 
    1778                                                 const Int4 NbvOld = nbv;
    1779                                                 lIntTria.SplitEdge(Bh,A,B);
    1780                                                 // Int4 NbvNp =
    1781                                                 lIntTria.NewPoints(vertices,nbv,nbvx);
    1782                                                 Int4 nbvNew=nbv;
    1783                                                 nbv = NbvOld;
    1784                                                 for (Int4 iv=NbvOld;iv<nbvNew;iv++) {
    1785                                                         vertices[nbv].color = color;
    1786                                                         vertices[nbv].ReferenceNumber=nbv;// circular link
    1787                                                         R2 C =  vertices[iv].r;
    1788                                                         vertices[nbv].r =  C;
    1789                                                         vertices[nbv].m =  vertices[iv].m ;
    1790                                                         // test if the new point is not to close to the 2 opposite vertex
    1791                                                         R2 CC1 = C-vC1 , CC2 = C-vC2;
    1792                                                         if (   (  (vC1.m(CC1) + vertices[nbv].m(CC1)) >  seuil)
    1793                                                                         && (  (vC2.m(CC2) + vertices[nbv].m(CC2)) >  seuil) )
    1794                                                                 nbv++;
    1795                                                 }
    1796 
    1797                                                 EndNewPoint[j] = nbv-1;
    1798                                         } // end loop for each edge
    1799 
    1800 #ifdef TRACETRIANGLE
    1801                                         if(trace) {
    1802                                                 // verification des point cree
    1803                                                 cout << "\n ------------ " << t->link << " " << t->det
    1804                                                         << " b " << BeginNewPoint[0] << " " << BeginNewPoint[1]
    1805                                                         << " " << BeginNewPoint[2] << " "
    1806                                                         << " e " << EndNewPoint[0] << " " << EndNewPoint[1]
    1807                                                         << " " << EndNewPoint[2] << " "
    1808                                                         << " s " << step[0] << " " << step[1] << " " << step[2] << " "
    1809                                                         <<  endl;
    1810                                         }
    1811 #endif
    1812 
    1813                                         if (!t->link) continue;// boundary
    1814                                         if (t->det<=0) continue;// outside
    1815                                         //      continue;
    1816                                         for(int j0=0;j0<3;j0++)
    1817                                                 for (Int4 i0= BeginNewPoint[j0]; i0 <= EndNewPoint[j0];i0++)
    1818                                                 {
    1819                                                         // find the neart  point one the opposite edge
    1820                                                         // to compute i1
    1821                                                         Vertex & vi0 = vertices[i0];
    1822                                                         int kstack = 0;
    1823                                                         Int4 stack[10];
    1824                                                         //   Int4 savRef[10];
    1825                                                         int j1 = j0;
    1826                                                         while (j0 != (j1 = NextEdge[j1])) {//loop on the 2 other edge
    1827                                                                 // computation of the intersection of edge j1 and DOrto
    1828                                                                 // take the good sens
    1829 
    1830                                                                 if (BeginNewPoint[j1]> EndNewPoint[j1])
    1831                                                                         continue; //
    1832                                                                 else if (EndNewPoint[j1] - BeginNewPoint[j1] <1) {
    1833                                                                         for (Int4 ii1= BeginNewPoint[j1];ii1<=EndNewPoint[j1];ii1++)
    1834                                                                                 stack[kstack++] = ii1;
    1835                                                                         continue;}
    1836 
    1837 
    1838                                                                         int k0,k1;
    1839                                                                         if (step[j1]<0) k0=1,k1=0; // reverse
    1840                                                                         else k0=0,k1=1;
    1841                                                                         R2 V10 = (R2)(*t)[VerticesOfTriangularEdge[j1][k0]];
    1842                                                                         R2 V11 = (R2)(*t)[VerticesOfTriangularEdge[j1][k1]];
    1843                                                                         R2 D = V11-V10;
    1844                                                                         Real8 c0 =  vi0.m(D,(R2) vi0);
    1845 
    1846                                                                         Real8 c10 =  vi0.m(D,V10);
    1847                                                                         Real8 c11 =  vi0.m(D,V11);
    1848 
    1849                                                                         Real8 s;
    1850                                                                         //cout << " --i0 = " << i0  << D  << V10 << V11 << endl ;
    1851                                                                         //cout << "   c10 " <<  c10 << " c0 " << c0 << " c11 " << c11 << endl;
    1852                                                                         if (( c10 < c0 ) && (c0 < c11))
    1853                                                                                 s = (c11-c0)/(c11-c10);
    1854                                                                         else if  (( c11 < c0 ) && (c0 < c10))
    1855                                                                                 s = (c11-c0) /(c11-c10);
    1856                                                                         else break;
    1857                                                                         R2 VP = V10*s + V11*(1-s);
    1858                                                                         int sss = (c11-c10) >0 ? 1 : -1;
    1859                                                                         // find the 2 point by dichotomie
    1860                                                                         //cout << "   t =" << Number(t) << " c0 " << c0  ;
    1861                                                                         Int4 ii0 =  BeginNewPoint[j1];
    1862                                                                         Int4 ii1 =  EndNewPoint[j1];         
    1863                                                                         Real8 ciii=-1,cii0=-1,cii1=-1  ;
    1864                                                                         if ( sss * ((cii0=vi0.m(D,(R2) vertices[ii0]))- c0) >0 ) 
    1865                                                                                 stack[kstack++] = ii0;//cout << " add+0 " << ii0;
    1866                                                                         else if ( sss * ((cii1=  vi0.m(D ,(R2) vertices[ii1]))- c0) < 0 ) 
    1867                                                                                 stack[kstack++] = ii1;//cout << " add+1 " << ii1;
    1868                                                                         else {
    1869                                                                                 while ((ii1-ii0)> 1) {
    1870                                                                                         Int4 iii = (ii0+ii1)/2;
    1871                                                                                         ciii = vi0.m( D ,(R2) vertices[iii]);
    1872                                                                                         //cout << " (iii = " << iii << " " <<  ciii << ") ";
    1873                                                                                         if ( sss * (ciii - c0) <0 )  ii0 = iii;
    1874                                                                                         else ii1 = iii;}                             
    1875                                                                                         stack[kstack++] = ii0;// cout << " add0 " << ii0;
    1876                                                                                         if (ii1 != ii0)  stack[kstack++] = ii1;//cout << " add1 " << ii1;
    1877                                                                         }
    1878                                                                         if (kstack >5) // bug ?
    1879                                                                                 cout << "NewPoints: bug????? " << kstack << " stack  " << stack[kstack]<< endl;
    1880                                                         }
    1881 
    1882                                                         stack[kstack++] = -1; // to stop
    1883                                                         Int4 i1;
    1884                                                         kstack =0;
    1885                                                         while( (i1=stack[kstack++]) >= 0)
    1886                                                         { // the two parameter is i0 and i1
    1887                                                                 assert(i1 < nbv && i1 >= 0);
    1888                                                                 assert(i0 < nbv && i0 >= 0);
    1889                                                                 assert(i1 != i0);
    1890                                                                 R2 v01 = (R2) vertices[i1]- (R2) vertices[i0];
    1891                                                                 Real8 d01 = (vertices[i0].m(v01) + vertices[i1].m(v01));
    1892 
    1893 
    1894 #ifdef TRACETRIANGLE
    1895                                                                 if(trace) {
    1896                                                                         cout << "\n test j" << j <<" "  << i0
    1897                                                                                 << " " << i1 << " d01=" << d01 <<endl;}
    1898 #endif
    1899                                                                 assert (i0 >= nbvold);
    1900                                                                 assert (i1 >= nbvold);
    1901                                                                 assert(i0 != i1);
    1902                                                                 if (d01 == 0)
    1903                                                                         break;
    1904                                                                 if ( d01 < seuil)
    1905                                                                         if (i1<nbvold) {
    1906                                                                                 // remove all the points i0;
    1907                                                                                 register Int4 ip,ipp;
    1908                                                                                 for  (ip=i0;i0 != (ipp = vertices[ip].ReferenceNumber);ip=ipp)
    1909                                                                                         vertices[ip].ReferenceNumber = -1;// mark remove
    1910                                                                                 vertices[ip].ReferenceNumber = -1;// mark remove
    1911                                                                         }
    1912                                                                         else {
    1913                                                                                 // remove on of two points
    1914                                                                                 register Int4 ip0, ip1, ipp0,ipp1;
    1915                                                                                 register int kk0=1,kk1=1;
    1916                                                                                 // count the number of common points to compute weight w0,w1
    1917                                                                                 for  (ip0=i0;i0 != (ipp0 = vertices[ip0].ReferenceNumber);ip0=ipp0) kk0++;
    1918                                                                                 for  (ip1=i1;i1 != (ipp1 = vertices[ip1].ReferenceNumber);ip1=ipp1) kk1++;
    1919 
    1920                                                                                 register Real8 w0 = ((Real8) kk0)/(kk0+kk1);
    1921                                                                                 register Real8 w1 = ((Real8) kk1)/(kk0+kk1);
    1922 
    1923                                                                                 // make a circular link
    1924                                                                                 Exchange(vertices[i0].ReferenceNumber,vertices[i1].ReferenceNumber);
    1925                                                                                 // the new coordinate
    1926                                                                                 R2 C //= vertices[i0] ;
    1927                                                                                 =  vertices[i0].r *w0 + vertices[i1].r* w1;
    1928 
    1929 #ifdef TRACETRIANGLE
    1930                                                                                 if(trace) {
    1931                                                                                         cout << "\n ref = "<< vertices[i0].ref << " " <<vertices[i1].ref <<endl;
    1932                                                                                 }
    1933 #endif   
    1934                                                                                 // update the new point points of the list
    1935                                                                                 for  (ip0=i0;i0 != (ipp0 = vertices[ip0].ReferenceNumber);ip0=ipp0)
    1936                                                                                         vertices[ip0].r = C;         
    1937                                                                                 vertices[ip0].r = C;
    1938                                                                         }
    1939                                                         }
    1940                                                 } // for (i0= ....
    1941                                 }// for triangle   
    1942 
    1943                                 // remove of all the double points
    1944 
    1945                                 Int4 ip,ipp,kkk=nbvold;
    1946                                 for (i=nbvold;i<nbv;i++)
    1947                                         if (vertices[i].ReferenceNumber>=0) {// good points
    1948                                                 //  cout <<" i = " << i ;
    1949                                                 for  (ip=i;i != (ipp = vertices[ip].ReferenceNumber);ip=ipp)
    1950                                                         vertices[ip].ReferenceNumber = -1;// mark remove
    1951                                                 vertices[ip].ReferenceNumber = -1;// mark remove
    1952                                                 // cout << i << " ---> " << kkk << endl;       
    1953                                                 vertices[kkk] = vertices[i];
    1954                                                 vertices[kkk].i = toI2(vertices[kkk].r);
    1955                                                 vertices[kkk++].ReferenceNumber = 0;
    1956 
    1957                                         }
    1958 
    1959                                 // insertion part ---
    1960 
    1961                                 const Int4 nbvnew = kkk-nbvold;
    1962 
    1963                                 cout << "    Remove " << nbv - kkk  << " to close  vertex " ;
    1964                                 cout << " and   Insert the " <<nbvnew<< " new points " << endl; 
    1965                                 nbv = kkk;
    1966                                 Int4 NbSwap=0;
    1967                                 Icoor2 dete[3];
    1968 
    1969                                 // construction d'un ordre aleatoire
    1970                                 if (! nbvnew)
    1971                                         break;
    1972                                 if (nbvnew) {
    1973                                         const Int4 PrimeNumber= AGoodNumberPrimeWith(nbv)  ;
    1974                                         Int4 k3 = rand()%nbvnew ;
    1975                                         for (Int4 is3=0; is3<nbvnew; is3++)
    1976                                                 ordre[nbvold+is3]= &vertices[nbvold +(k3 = (k3 + PrimeNumber)% nbvnew)];
    1977 
    1978                                         for (i=nbvold;i<nbv;i++)
    1979                                         { Vertex * vi = ordre[i];
    1980                                                 Triangle *tcvi = FindTriangleContening(vi->i,dete);
    1981                                                 //     Vertex * nv =  quadtree->NearestVertex(vi->i.x,vi->i.y);
    1982                                                 //      cout << " Neart Vertex of "  << Number(vi)<< vi->i << " is "
    1983                                                 //   << Number(nv) << nv->i  << endl;
    1984                                                 // Int4  kt = Number(tcvi);
    1985                                                 //
    1986 
    1987                                                 quadtree->Add(*vi); //
    1988                                                 assert (tcvi->det >= 0) ;// internal
    1989                                                 Add(*vi,tcvi,dete),NbSwap += vi->Optim(1);         
    1990                                         } 
    1991                                 }
    1992                                 cout << " Nb swap = " << NbSwap << " after " ;
    1993 
    1994                                 for (i=nbvold;i<nbv;i++)
    1995                                         NbSwap += vertices[i].Optim(1); 
    1996                                 cout << NbSwap << endl;
    1997 
    1998                                 for (i=nbtold;i<nbt;i++)
    1999                                         first_np_or_next_t[i]=1;
    2000 
    2001                                 Headt = nbt; // empty list
    2002                                 for (i=nbvold;i<nbv;i++)
    2003                                 { // for all the triangle contening the vertex i
    2004                                         Vertex * s  = vertices + i;
    2005                                         TriangleAdjacent ta(s->t, EdgesVertexTriangle[s->vint][1]);
    2006                                         Triangle * tbegin= (Triangle*) ta;
    2007                                         Int4 kt;
    2008                                         do {
    2009                                                 kt = Number((Triangle*) ta);
    2010                                                 if (first_np_or_next_t[kt]>0)
    2011                                                         first_np_or_next_t[kt]=-Headt,Headt=kt;
    2012                                                 assert( ta.EdgeVertex(0) == s);
    2013                                                 ta = Next(Adj(ta));
    2014                                         } while ( (tbegin != (Triangle*) ta));
    2015                                 }
    2016 
    2017 
    2018                         } while (nbv!=nbvold);
    2019                         delete []  first_np_or_next_t;
    2020                         cout << " end :  Triangles::NewPoints old  nbv=" << nbv << endl;
    2021 
    2022                 }
    2023 
    2024                 void Triangles::Insert()
    2025                 {
    2026                         long int verbosity=2;
    2027                         if (verbosity>2) cout << "  -- Insert initial " << nbv << " vertices " << endl ;
    2028                         Triangles * OldCurrentTh =CurrentTh;
    2029 
    2030                         CurrentTh=this;
    2031                         double time0=CPUtime(),time1,time2,time3;
    2032                         SetIntCoor();
    2033                         Int4 i;
    2034                         for (i=0;i<nbv;i++)
    2035                                 ordre[i]= &vertices[i] ;
    2036 
    2037                         // construction d'un ordre aleatoire
    2038                         const Int4 PrimeNumber= AGoodNumberPrimeWith(nbv) ;
    2039                         Int4 k3 = rand()%nbv ;
    2040                         for (int is3=0; is3<nbv; is3++)
    2041                                 ordre[is3]= &vertices[k3 = (k3 + PrimeNumber)% nbv];
    2042 
    2043 
    2044 
    2045 
    2046                         for (i=2 ; det( ordre[0]->i, ordre[1]->i, ordre[i]->i ) == 0;)
    2047                                 if  ( ++i >= nbv) {
    2048                                         cerr << " All the vertices are aline " << endl;
    2049                                         MeshError(998,this); }
    2050 
    2051                                         // echange i et 2 dans ordre afin
    2052                                         // que les 3 premiers ne soit pas aligne
    2053                                         Exchange( ordre[2], ordre[i]);
    2054 
    2055                                         // on ajoute un point a l'infini pour construire le maillage
    2056                                         // afin d'avoir une definition simple des aretes frontieres
    2057                                         nbt = 2;
    2058 
    2059 
    2060                                         // on construit un maillage trivale forme
    2061                                         // d'une arete et de 2 triangles
    2062                                         // construit avec le 2 aretes orientes et
    2063                                         Vertex *  v0=ordre[0], *v1=ordre[1];
    2064 
    2065                                         triangles[0](0) = 0; // sommet pour infini
    2066                                         triangles[0](1) = v0;
    2067                                         triangles[0](2) = v1;
    2068 
    2069                                         triangles[1](0) = 0;// sommet pour infini
    2070                                         triangles[1](2) = v0;
    2071                                         triangles[1](1) = v1;
    2072                                         const int e0 = OppositeEdge[0];
    2073                                         const int e1 = NextEdge[e0];
    2074                                         const int e2 = PreviousEdge[e0];
    2075                                         triangles[0].SetAdj2(e0, &triangles[1] ,e0);
    2076                                         triangles[0].SetAdj2(e1, &triangles[1] ,e2);
    2077                                         triangles[0].SetAdj2(e2, &triangles[1] ,e1);
    2078 
    2079                                         triangles[0].det = -1;  // faux triangles
    2080                                         triangles[1].det = -1;  // faux triangles
    2081 
    2082                                         triangles[0].SetTriangleContainingTheVertex();
    2083                                         triangles[1].SetTriangleContainingTheVertex();
    2084 
    2085                                         triangles[0].link=&triangles[1];
    2086                                         triangles[1].link=&triangles[0];
    2087 
    2088                                         //  nbtf = 2;
    2089                                         if (  !quadtree )  quadtree = new QuadTree(this,0);
    2090                                         quadtree->Add(*v0);
    2091                                         quadtree->Add(*v1);
    2092 
    2093                                         // on ajoute les sommets un Ò un
    2094                                         Int4 NbSwap=0;
    2095 
    2096                                         time1=CPUtime();
    2097 
    2098                                         if (verbosity>3) cout << "  -- Begin of insertion process " << endl;
    2099 
    2100                                         for (Int4 icount=2; icount<nbv; icount++) {
    2101                                                 Vertex *vi  = ordre[icount];
    2102                                                 //    cout << " Insert " << Number(vi) << endl;
    2103                                                 Icoor2 dete[3];
    2104                                                 Triangle *tcvi = FindTriangleContening(vi->i,dete);
    2105                                                 quadtree->Add(*vi);
    2106                                                 Add(*vi,tcvi,dete);
    2107                                                 NbSwap += vi->Optim(1,0);
    2108 
    2109                                         }// fin de boucle en icount
    2110                                         time2=CPUtime();
    2111                                         if (verbosity>3)
    2112                                                 cout << "    NbSwap of insertion " <<    NbSwap
    2113                                                         << " NbSwap/Nbv " <<  (float) NbSwap / (float) nbv
    2114                                                         << " NbUnSwap " << NbUnSwap << " Nb UnSwap/Nbv "
    2115                                                         << (float)NbUnSwap /(float) nbv
    2116                                                         <<endl;
    2117                                         NbUnSwap = 0;
    2118                                         // construction d'un ordre aleatoire
    2119                                         //  const int PrimeNumber= (nbv % 999983) ? 1000003: 999983 ;
    2120 #ifdef NBLOOPOPTIM
    2121 
    2122                                         k3 = rand()%nbv ;
    2123                                         for (int is4=0; is4<nbv; is4++)
    2124                                                 ordre[is4]= &vertices[k3 = (k3 + PrimeNumber)% nbv];
    2125 
    2126                                         double timeloop = time2 ;
    2127                                         for(int Nbloop=0;Nbloop<NBLOOPOPTIM;Nbloop++)
    2128                                         {
    2129                                                 double time000 = timeloop;
    2130                                                 Int4  NbSwap = 0;
    2131                                                 for (int is1=0; is1<nbv; is1++)
    2132                                                         NbSwap += ordre[is1]->Optim(0,0);
    2133                                                 timeloop = CPUtime();
    2134                                                 if (verbosity>3)
    2135                                                         cout << "    Optim Loop "<<Nbloop<<" NbSwap: " <<  NbSwap
    2136                                                                 << " NbSwap/Nbv "          <<  (float) NbSwap / (float) nbv
    2137                                                                 << " CPU=" << timeloop - time000 << "  s, "
    2138                                                                 << " NbUnSwap/Nbv " << (float)NbUnSwap /(float) nbv 
    2139                                                                 <<  endl;
    2140                                                 NbUnSwap = 0;
    2141                                                 if(!NbSwap) break;
    2142                                         }
    2143                                         ReMakeTriangleContainingTheVertex();
    2144                                         // because we break the TriangleContainingTheVertex
    2145 #endif
    2146                                         time3=CPUtime();
    2147                                         if (verbosity>4)
    2148                                                 cout << "    init " << time1 - time0 << " initialisation,  "
    2149                                                         << time2 - time1 << "s, insert point  "
    2150                                                         << time3 -time2 << "s, optim " << endl
    2151                                                         << "     Init Total Cpu Time = " << time3 - time0 << "s " << endl;
    2152 
    2153                                         CurrentTh=OldCurrentTh;
    2154                 }
    2155 
    2156 
    2157                 void Triangles::ForceBoundary()
    2158                 {
    2159                         long int verbosity=2;
    2160                         if (verbosity > 2)
    2161                                 cout << "  -- ForceBoundary  nb of edge " << nbe << endl;
    2162                         int k=0;
    2163                         Int4  nbfe=0,nbswp=0,Nbswap=0;
    2164                         for (Int4 t = 0; t < nbt; t++) 
    2165                                 if (!triangles[t].det)
    2166                                         k++,cerr << " det T" << t << " = " << 0 << endl;
    2167                         if (k!=0) {
    2168                                 cerr << " ther is  " << k << "  triangles of mes = 0 " << endl;
    2169                                 MeshError(11,this);}
    2170 
    2171                                 TriangleAdjacent ta(0,0);
    2172                                 for (Int4 i = 0; i < nbe; i++)
    2173                                 {
    2174                                         nbswp =  ForceEdge(edges[i][0],edges[i][1],ta);
    2175 
    2176                                         if ( nbswp < 0)         k++;
    2177                                         else Nbswap += nbswp;
    2178                                         if (nbswp) nbfe++;
    2179                                         if ( nbswp < 0 && k < 5)
    2180                                         {
    2181                                                 cerr << " Missing  Edge " << i << " v0 =  " << Number(edges[i][0]) << edges[i][0].r
    2182                                                         <<" v1= " << Number(edges[i][1]) << edges[i][1].r << " " << edges[i].on->Cracked() << "  " << (Triangle *) ta ;
    2183                                                 if(ta.t)
    2184                                                 {
    2185                                                         Vertex *aa = ta.EdgeVertex(0), *bb = ta.EdgeVertex(1); 
    2186                                                         cerr << " crossing with  [" << Number(aa) << ", " << Number(bb) << "]\n";
    2187                                                 }
    2188                                                 else cerr << endl;
    2189 
    2190                                         }
    2191                                         if ( nbswp >=0 && edges[i].on->Cracked())
    2192                                                 ta.SetCracked();
    2193                                 }
    2194 
    2195 
    2196                                 if (k!=0) {
    2197                                         cerr << " they is " << k << " lost edges " << endl;
    2198                                         cerr << " The boundary is crossing may be!" << endl;
    2199                                         MeshError(10,this);
    2200                                 }
    2201                                 for (Int4 j=0;j<nbv;j++)
    2202                                         Nbswap +=  vertices[j].Optim(1,0);
    2203                                 if (verbosity > 3)
    2204                                         cout << "     Nb of inforced edge = " << nbfe << " Nb of Swap " << Nbswap << endl;
    2205 
    2206                 }
    2207 
    2208                 void Triangles::FindSubDomain(int OutSide=0)
    2209                 {
    2210                         long int verbosity=0;
    2211 
    2212                         if (verbosity >2)
    2213                         {
    2214                                 if (OutSide)
    2215                                         cout << "  -- Find all external sub-domain ";   
    2216                                 else
    2217                                         cout << "  -- Find all internal sub-domain ";
    2218                                 if(verbosity>99)
    2219                                 {
    2220 
    2221                                         for(int i=0;i<nbt;++i)
    2222                                                 cout << i<< " " << triangles[i] << endl;
    2223                                 }
    2224 
    2225                         }
    2226                         // if (verbosity > 4) cout << " OutSide=" << OutSide << endl;
    2227                         short * HeapArete = new short[nbt];
    2228                         Triangle  **  HeapTriangle = new Triangle*  [nbt];
    2229                         Triangle *t,*t1;
    2230                         Int4 k,it;
    2231 
    2232                         for (Int4 itt=0;itt<nbt;itt++)
    2233                                 triangles[itt].link=0; // par defaut pas de couleur
    2234 
    2235                         Int4  NbSubDomTot =0;
    2236                         for ( it=0;it<nbt;it++)  {
    2237                                 if ( ! triangles[it].link  ) {
    2238                                         t = triangles + it;
    2239                                         NbSubDomTot++;; // new composante connexe
    2240                                         Int4 i = 0; // niveau de la pile
    2241                                         t->link = t ; // sd forme d'un triangle cicular link
    2242 
    2243                                         HeapTriangle[i] =t ;
    2244                                         HeapArete[i] = 3;
    2245 
    2246                                         while (i >= 0) // boucle sur la pile
    2247                                         { while ( HeapArete[i]--) // boucle sur les 3 aretes
    2248                                                 {
    2249                                                         int na =  HeapArete[i];
    2250                                                         Triangle * tc =  HeapTriangle[i]; // triangle courant
    2251                                                         if( ! tc->Locked(na)) // arete non frontiere
    2252                                                         {
    2253                                                                 Triangle * ta = tc->TriangleAdj(na) ; // næ triangle adjacent
    2254                                                                 if (ta->link == 0 ) // non deja chainer => on enpile
    2255                                                                 {
    2256                                                                         i++;
    2257                                                                         ta->link = t->link ;  // on chaine les triangles
    2258                                                                         t->link = ta ;  // d'un meme sous domaine         
    2259                                                                         HeapArete[i] = 3; // pour les 3 triangles adjacents
    2260                                                                         HeapTriangle[i] = ta;
    2261                                                                 }}
    2262                                                 } // deplie fin de boucle sur les 3 adjacences
    2263                                                 i--;
    2264                                         }         
    2265                                 }     
    2266                         }
    2267 
    2268                         // supression de tous les sous domaine infini <=>  contient le sommet NULL
    2269                         it =0;
    2270                         NbOutT = 0;
    2271                         while (it<nbt) {
    2272                                 if (triangles[it].link)
    2273                                 {
    2274                                         if (!( triangles[it](0) &&  triangles[it](1) &&  triangles[it](2) ))
    2275                                         {
    2276                                                 // infini triangle
    2277                                                 NbSubDomTot --;
    2278                                                 //  cout << " triangle infini " << it << triangles[it] << endl;
    2279                                                 t=&triangles[it];
    2280                                                 NbOutT--;  // on fait un coup de trop.
    2281                                                 while  (t){ // cout << Number(t) << " " << endl;
    2282                                                         NbOutT++;
    2283                                                         t1=t;
    2284                                                         t=t->link;
    2285                                                         t1->link=0;}//while (t)
    2286                                         }
    2287                                 }   
    2288                                 it++;} // end while (it<nbt)
    2289                                 if (nbt == NbOutT ||  !NbSubDomTot)
    2290                                 {
    2291                                         cout << "\n error : " <<  NbOutT << " " << NbSubDomTot <<" " << nbt << endl;
    2292                                         cerr << "Error: The boundary is not close => All triangles are outside " << endl;
    2293                                         MeshError(888,this);
    2294                                 }
    2295 
    2296                                 delete [] HeapArete;
    2297                                 delete [] HeapTriangle;
    2298 
    2299 
    2300                                 if (OutSide|| !Gh.subdomains || !Gh.NbSubDomains )
    2301                                 { // No geom sub domain
    2302                                         Int4 i;
    2303                                         if (subdomains) delete [] subdomains;
    2304                                         subdomains = new SubDomain[ NbSubDomTot];
    2305                                         NbSubDomains=  NbSubDomTot;
    2306                                         for ( i=0;i<NbSubDomains;i++) {
    2307                                                 subdomains[i].head=NULL;
    2308                                                 subdomains[i].ref=i+1;
    2309                                         }
    2310                                         Int4 * mark = new Int4[nbt];
    2311                                         for (it=0;it<nbt;it++)
    2312                                                 mark[it]=triangles[it].link ? -1 : -2;
    2313 
    2314                                         it =0;
    2315                                         k = 0;
    2316                                         while (it<nbt) {
    2317                                                 if (mark[it] == -1) {
    2318                                                         t1 = & triangles[it];
    2319                                                         t = t1->link;
    2320                                                         mark[it]=k;
    2321                                                         subdomains[k].head = t1;
    2322                                                         // cout << " New -- " << Number(t1) << " " << it << endl;
    2323                                                         do {// cout << " k " << k << " " << Number(t) << endl;
    2324                                                                 mark[Number(t)]=k;
    2325                                                                 t=t->link;
    2326                                                         } while (t!=t1);
    2327                                                         mark[it]=k++;}
    2328                                                         //    else if(mark[it] == -2 ) triangles[it].Draw(999);
    2329                                                         it++;} // end white (it<nbt)
    2330                                                         assert(k== NbSubDomains);
    2331                                                         if(OutSide)
    2332                                                         {
    2333                                                                 //  to remove all the sub domain by parity adjacents
    2334                                                                 //  because in this case we have only the true boundary edge
    2335                                                                 // so teh boundary is manifold
    2336                                                                 Int4 nbk = NbSubDomains;
    2337                                                                 while (nbk)
    2338                                                                         for (it=0;it<nbt && nbk ;it++)
    2339                                                                                 for (int na=0;na<3 && nbk ;na++)
    2340                                                                                 {
    2341                                                                                         Triangle *ta = triangles[it].TriangleAdj(na);
    2342                                                                                         Int4 kl = ta ? mark[Number(ta)] : -2;
    2343                                                                                         Int4 kr = mark[it];
    2344                                                                                         if(kr !=kl) {
    2345                                                                                                 //cout << kl << " " << kr << " rl "  << subdomains[kl].ref
    2346                                                                                                 // << " rr " << subdomains[kr].ref ;
    2347                                                                                                 if (kl >=0 && subdomains[kl].ref <0 && kr >=0 && subdomains[kr].ref>=0)
    2348                                                                                                         nbk--,subdomains[kr].ref=subdomains[kl].ref-1;
    2349                                                                                                 if (kr >=0 && subdomains[kr].ref <0 && kl >=0 && subdomains[kl].ref>=0)
    2350                                                                                                         nbk--,subdomains[kl].ref=subdomains[kr].ref-1;
    2351                                                                                                 if(kr<0 && kl >=0 && subdomains[kl].ref>=0)
    2352                                                                                                         nbk--,subdomains[kl].ref=-1;
    2353                                                                                                 if(kl<0 && kr >=0 && subdomains[kr].ref>=0)
    2354                                                                                                         nbk--,subdomains[kr].ref=-1;
    2355                                                                                                 //   cout << " after \t "   
    2356                                                                                                 //       << kl << subdomains[kl].ref << " rr " << kr
    2357                                                                                                 // << subdomains[kr].ref << endl;
    2358                                                                                         }
    2359                                                                                 }
    2360                                                                 //  cout << subdomains[0].ref << subdomains[1].ref << endl;
    2361                                                                 Int4  j=0;
    2362                                                                 for ( i=0;i<NbSubDomains;i++)
    2363                                                                         if((-subdomains[i].ref) %2) { // good
    2364                                                                                 //cout << " sudom ok  = " << i << " " << subdomains[i].ref
    2365                                                                                 // << " " << (-subdomains[i].ref) %2 << endl;
    2366                                                                                 if(i != j)
    2367                                                                                         Exchange(subdomains[i],subdomains[j]);
    2368                                                                                 j++;}
    2369                                                                         else
    2370                                                                         { //cout << " remove sub domain " << i << endl;
    2371                                                                                 t= subdomains[i].head;
    2372                                                                                 while  (t){// cout << Number(t) << " " << endl;
    2373                                                                                         NbOutT++;
    2374                                                                                         t1=t;
    2375                                                                                         t=t->link;
    2376                                                                                         t1->link=0;}//while (t)
    2377                                                                         }
    2378 
    2379                                                                 if(verbosity>4)
    2380                                                                         cout << " Number of remove sub domain (OutSideMesh) =" << NbSubDomains-j << endl;
    2381                                                                 NbSubDomains=j;
    2382                                                         }
    2383 
    2384                                                         delete []  mark;
    2385 
    2386                                 }
    2387                                 else
    2388                                 { // find the head for all sub domaine
    2389                                         if (Gh.NbSubDomains != NbSubDomains && subdomains)
    2390                                                 delete [] subdomains, subdomains=0;
    2391                                         if (! subdomains  )
    2392                                                 subdomains = new SubDomain[ Gh.NbSubDomains];
    2393                                         NbSubDomains =Gh.NbSubDomains;
    2394                                         if(verbosity>4)
    2395                                                 cout << "     find the " << NbSubDomains << " sub domain " << endl;
    2396                                         Int4 err=0;
    2397                                         ReMakeTriangleContainingTheVertex();
    2398                                         Int4 * mark = new Int4[nbt];
    2399                                         Edge **GeometricalEdgetoEdge = MakeGeometricalEdgeToEdge();
    2400 
    2401                                         for (it=0;it<nbt;it++)
    2402                                                 mark[it]=triangles[it].link ? -1 : -2;
    2403                                         Int4 inew =0;
    2404                                         for (Int4 i=0;i<NbSubDomains;i++)
    2405                                         {
    2406                                                 GeometricalEdge &eg = *Gh.subdomains[i].edge;
    2407                                                 subdomains[i].ref = Gh.subdomains[i].ref;
    2408                                                 int ssdlab = subdomains[i].ref;
    2409                                                 // by carefull is not easy to find a edge create from a GeometricalEdge
    2410                                                 // see routine MakeGeometricalEdgeToEdge
    2411                                                 Edge &e = *GeometricalEdgetoEdge[Gh.Number(eg)];
    2412                                                 assert(&e);
    2413                                                 Vertex * v0 =  e(0),*v1 = e(1);
    2414                                                 Triangle *t  = v0->t;
    2415                                                 int sens = Gh.subdomains[i].sens;
    2416                                                 // test if ge and e is in the same sens
    2417                                                 //      cout << " geom edge = " <<  Gh.Number(eg) <<" @" << &eg << " ref = " << subdomains[i].ref
    2418                                                 //     << " ref edge =" << eg.ref << " sens " << sens ;
    2419                                                 if (((eg[0].r-eg[1].r),(e[0].r-e[1].r))<0)
    2420                                                         sens = -sens ;
    2421                                                 subdomains[i].sens = sens;
    2422                                                 subdomains[i].edge = &e;
    2423                                                 //      cout << " sens " << sens << " in geom " << eg[0].r << eg[1].r << " in mesh  " << e[0].r << e[1].r << endl;
    2424                                                 //      cout << "  v0 , v1 = " << Number(v0) << " "  << Number(v1) << endl;
    2425                                                 assert(t && sens);
    2426 
    2427                                                 TriangleAdjacent  ta(t,EdgesVertexTriangle[v0->vint][0]);// previous edges
    2428 
    2429                                                 while (1)
    2430                                                 {
    2431                                                         assert( v0 == ta.EdgeVertex(1) );
    2432                                                         //       cout << " recherche " << Number( ta.EdgeVertex(0)) << endl;
    2433                                                         if (ta.EdgeVertex(0) == v1) { // ok we find the edge
    2434                                                                 if (sens>0) 
    2435                                                                         subdomains[i].head=t=Adj(ta);
    2436                                                                 else
    2437                                                                         subdomains[i].head=t=ta;
    2438                                                                 //cout << "      triangle  =" << Number(t) << " = " << (*t)[0].r <<  (*t)[1].r <<  (*t)[2].r << endl;
    2439                                                                 if(t<triangles || t >= triangles+nbt || t->det < 0
    2440                                                                                 || t->link == 0) // Ajoute aout 200
    2441                                                                 {
    2442                                                                         cerr << " Error in the def of sub domain "<<i
    2443                                                                                 << " form border " << NbSubDomains - i  << "/" << NbSubDomains
    2444                                                                                 << ": Bad sens  " << Gh.Number(eg) <<" "<< sens <<  endl; 
    2445                                                                         err++;
    2446                                                                         break;}
    2447                                                                         Int4 it = Number(t);
    2448                                                                         if (mark[it] >=0) {
    2449                                                                                 if(verbosity>10)
    2450                                                                                         cerr << "     Warning: the sub domain " << i << " ref = " << subdomains[i].ref
    2451                                                                                                 << " is previouly defined with "  <<mark[it] << " ref = " << subdomains[mark[it]].ref
    2452                                                                                                 << " skip this def " << endl;
    2453                                                                                 break;}
    2454                                                                                 if(i != inew)
    2455                                                                                         Exchange(subdomains[i],subdomains[inew]);
    2456                                                                                 inew++;
    2457                                                                                 Triangle *tt=t;
    2458                                                                                 Int4 kkk=0;
    2459                                                                                 do
    2460                                                                                 {
    2461                                                                                         kkk++;
    2462                                                                                         assert(mark[Number(tt)]<0);
    2463                                                                                         mark[Number(tt)]=i;
    2464                                                                                         tt=tt->link;
    2465                                                                                 } while (tt!=t);
    2466                                                                                 if(verbosity>7)
    2467                                                                                         cout << "     Nb de triangles dans le sous domaine " << i << " de ref " << subdomains[i].ref << " = " << kkk << endl;
    2468                                                                                 break;}
    2469                                                                                 ta = Previous(Adj(ta));         
    2470                                                                                 if(t == (Triangle *) ta) {
    2471                                                                                         err++;
    2472                                                                                         cerr << " Error in the def of sub domain " << i
    2473                                                                                                 << " edge=" << Gh.Number(eg) << " " << sens << endl;
    2474                                                                                         break;}
    2475                                                                                         //         cout << " NB of remove subdomain " << NbSubDomTot-NbSubDomains<< endl;
    2476 
    2477                                                 }
    2478 
    2479                                         }
    2480                                         if (err) MeshError(777,this);
    2481 
    2482                                         if (inew < NbSubDomains) {
    2483                                                 if (verbosity>5)
    2484                                                         cout << "     Warning: We remove " << NbSubDomains-inew << " SubDomains " << endl;
    2485                                                 NbSubDomains=inew;}
    2486 
    2487 
    2488                                                 for (it=0;it<nbt;it++)
    2489                                                         if ( mark[it] ==-1 )
    2490                                                                 NbOutT++,triangles[it].link =0;
    2491                                                 delete [] GeometricalEdgetoEdge;
    2492                                                 delete [] mark;
    2493 
    2494                                 }
    2495                                 NbOutT=0;
    2496                                 for (it=0;it<nbt;it++)
    2497                                         if(!triangles[it].link)  NbOutT++;
    2498                                 if (verbosity> 4)
    2499                                         cout << "    " ;
    2500                                 if (verbosity> 2)
    2501                                         cout << " Nb of Sub borned Domain  = " <<  NbSubDomTot << " NbOutTriangles = " << NbOutT <<endl;
    2502 
    2503 
    2504                 }
    2505                 void Triangles::ReNumberingVertex(Int4 * renu)
    2506                 {
    2507                         // warning be carfull because pointeur
    2508                         // from on mesh to over mesh
    2509                         //  --  so do ReNumbering a the beginning
    2510                         Vertex * ve = vertices+nbv;
    2511                         Int4 it,ie,i;
    2512 
    2513                         for ( it=0;it<nbt;it++)
    2514                                 triangles[it].ReNumbering(vertices,ve,renu);
    2515 
    2516                         for ( ie=0;ie<nbe;ie++)
    2517                                 edges[ie].ReNumbering(vertices,ve,renu);
    2518 
    2519                         for (i=0;i< NbVerticesOnGeomVertex;i++)
    2520                         {
    2521                                 Vertex *v = VerticesOnGeomVertex[i].mv;
    2522                                 if (v>=vertices && v < ve)
    2523                                         VerticesOnGeomVertex[i].mv=vertices+renu[Number(v)];
    2524                         }
    2525 
    2526                         for (i=0;i< NbVerticesOnGeomEdge;i++)
    2527                         {
    2528                                 Vertex *v =VerticesOnGeomEdge[i].mv;
    2529                                 if (v>=vertices && v < ve)
    2530                                         VerticesOnGeomEdge[i].mv=vertices+renu[Number(v)];
    2531                         }
    2532 
    2533                         for (i=0;i< NbVertexOnBThVertex;i++)
    2534                         {
    2535                                 Vertex *v=VertexOnBThVertex[i].v;
    2536                                 if (v>=vertices && v < ve)
    2537                                         VertexOnBThVertex[i].v=vertices+renu[Number(v)];
    2538                         }
    2539 
    2540                         for (i=0;i< NbVertexOnBThEdge;i++)
    2541                         {
    2542                                 Vertex *v=VertexOnBThEdge[i].v;
    2543                                 if (v>=vertices && v < ve)
    2544                                         VertexOnBThEdge[i].v=vertices+renu[Number(v)];
    2545                         }
    2546 
    2547                         // move the Vertices without a copy of the array
    2548                         // be carefull not trivial code
    2549                         Int4 j;
    2550                         for ( it=0;it<nbv;it++) // for all sub cycles of the permutation renu
    2551                                 if (renu[it] >= 0) // a new sub cycle
    2552                                 {
    2553                                         i=it;
    2554                                         Vertex ti=vertices[i],tj;
    2555                                         while ( (j=renu[i]) >= 0)
    2556                                         { // i is old, and j is new
    2557                                                 renu[i] = -1-renu[i]; // mark
    2558                                                 tj = vertices[j]; // save new
    2559                                                 vertices[j]= ti; // new <- old
    2560                                                 i=j;     // next
    2561                                                 ti = tj;
    2562                                         } 
    2563                                 }
    2564                         if (quadtree)
    2565                         {  delete quadtree;
    2566                                 quadtree = new QuadTree(this);
    2567                         }
    2568                         for ( it=0;it<nbv;it++)
    2569                                 renu[i]= -renu[i]-1;
    2570 
    2571                 }
    2572                 void Triangles::ReNumberingTheTriangleBySubDomain(bool justcompress)
    2573                 {
    2574                         long int verbosity=0;
    2575                         Int4 *renu= new Int4[nbt];
    2576                         register Triangle *t0,*t,*te=triangles+nbt;
    2577                         register Int4 k=0,it,i,j;
    2578 
    2579                         for ( it=0;it<nbt;it++)
    2580                                 renu[it]=-1; // outside triangle
    2581                         for ( i=0;i<NbSubDomains;i++)
    2582                         {
    2583                                 t=t0=subdomains[i].head;
    2584                                 assert(t0); // no empty sub domain
    2585                                 do {
    2586                                         Int4 kt = Number(t);
    2587                                         assert(kt>=0 && kt < nbt );
    2588                                         assert(renu[kt]==-1);
    2589                                         renu[kt]=k++;
    2590                                 }
    2591                                 while (t0 != (t=t->link));
    2592                         }
    2593                         if (verbosity>9)
    2594                                 cout << " number of inside triangles " << k << " nbt = " << nbt << endl;
    2595                         // take is same numbering if possible   
    2596                         if(justcompress)
    2597                                 for ( k=0,it=0;it<nbt;it++)
    2598                                         if(renu[it] >=0 )
    2599                                                 renu[it]=k++;
    2600 
    2601                         // put the outside triangles at the end
    2602                         for ( it=0;it<nbt;it++)
    2603                                 if (renu[it]==-1)
    2604                                         renu[it]=k++;
    2605 
    2606                         assert(k == nbt);
    2607                         // do the change on all the pointeur
    2608                         for ( it=0;it<nbt;it++)
    2609                                 triangles[it].ReNumbering(triangles,te,renu);
    2610 
    2611                         for ( i=0;i<NbSubDomains;i++)
    2612                                 subdomains[i].head=triangles+renu[Number(subdomains[i].head)];
    2613 
    2614                         // move the Triangles  without a copy of the array
    2615                         // be carefull not trivial code
    2616                         for ( it=0;it<nbt;it++) // for all sub cycles of the permutation renu
    2617                                 if (renu[it] >= 0) // a new sub cycle
    2618                                 {
    2619                                         i=it;
    2620                                         Triangle ti=triangles[i],tj;
    2621                                         while ( (j=renu[i]) >= 0)
    2622                                         { // i is old, and j is new
    2623                                                 renu[i] = -1; // mark
    2624                                                 tj = triangles[j]; // save new
    2625                                                 triangles[j]= ti; // new <- old
    2626                                                 i=j;     // next
    2627                                                 ti = tj;
    2628                                         } 
    2629                                 }
    2630                         delete [] renu;
    2631                         nt = nbt - NbOutT;
    2632 
    2633                 }
    2634                 Int4  Triangles::ConsRefTriangle(Int4 *reft) const
    2635                 {
    2636                         long int verbosity=0;
    2637                         assert(reft);
    2638                         register Triangle *t0,*t;
    2639                         register Int4 k=0, num;   
    2640                         for (Int4 it=0;it<nbt;it++)
    2641                                 reft[it]=-1; // outside triangle
    2642                         for (Int4 i=0;i<NbSubDomains;i++)
    2643                         {
    2644                                 t=t0=subdomains[i].head;
    2645                                 assert(t0); // no empty sub domain
    2646                                 // register Int4 color=i+1;// because the color 0 is outside triangle
    2647                                 do { k++;
    2648                                         num = Number(t);
    2649                                         assert(num>=0 &&num < nbt);
    2650                                         reft[num]=i;
    2651                                         //  cout << Number(t0) << " " <<Number(t)<< " "  << i << endl;
    2652                                 }
    2653                                 while (t0 != (t=t->link));
    2654                         }
    2655                         //  NbOutT = nbt - k;
    2656                         if (verbosity>5)
    2657                                 cout << " Nb of Sub Domain =" << NbSubDomains  << " Nb of In Triangles " << k
    2658                                         << " Nbt = " << nbt << " Out Triangles = " << nbt - k <<  endl;
    2659 
    2660                         return k;   
    2661 
    2662                 }
    2663 
    2664                 /*
    2665                    void Triangles::ConsLinkTriangle()
    2666                    {
    2667                    for (Int4 i=0;i<NbSubDomains;i++)
    2668                    subdomains[i].head=0;
    2669                    register Triangle * t=triangles,*tend = triangles+nbt,*hst;
    2670                    for (;t<tend;t++)
    2671                    { 
    2672                    if (t->link)
    2673                    {
    2674                    register Int4 color = t->color-1;
    2675                    assert(color<NbSubDomains && color>=0);
    2676                    if (hst=subdomains[color].head) {
    2677                    t->link=hst->link;
    2678                    hst->link=t; }
    2679                    else {
    2680                    subdomains[color].head = t;
    2681                    t->link=t;}// circular link         
    2682                    }
    2683                    }
    2684                    {
    2685                    for (Int4 i=0;i<NbSubDomains;i++)
    2686                    assert(subdomains[i].head);
    2687                    }
    2688 
    2689                    }
    2690                    */
    2691                 /* void Triangles::RandomInit()
    2692                    {
    2693                 //  Meshbegin = vertices;
    2694                 //  Meshend  = vertices + nbvx;
    2695                 nbv = nbvx;
    2696                 for (int i = 0; i < nbv; i++)
    2697                 {
    2698                 vertices[i].r.x= rand();
    2699                 vertices[i].r.y= rand();
    2700                 vertices[i].ref = 0;
    2701                 }
    2702                 }
    2703                 void Triangles::CubeInit(int n,int m)
    2704                 {
    2705                 //  nbvx = n*m;
    2706                 //  Meshbegin = vertices;
    2707                 // Meshend  = vertices + nbvx;
    2708                 nbv = n*m;
    2709                 assert(nbv <= nbvx);
    2710                 int k =0;
    2711                 for (int i = 0; i < n; i++)
    2712                 for (int j = 0; j < m; j++)
    2713                 {
    2714                 vertices[k].r.x= i;
    2715                 vertices[k].r.y= j;
    2716                 vertices[k++].ref = 0;
    2717                 }
    2718                 }
    2719                 */
    27201076                Vertex * Triangles::NearestVertex(Icoor1 i,Icoor1 j)
    27211077                { return  quadtree->NearestVertex(i,j); }
     
    28041160                                        << " " << vertices
    28051161                                        << " " << ordre << " " <<  triangles <<endl;
    2806 
    28071162                }
    28081163
    2809                 void Triangles::GeomToTriangles1(Int4 inbvx,int KeepBackVertices)
    2810                 {
    2811                         Gh.NbRef++;// add a ref to Gh
    2812 
    2813 
    2814                         /*************************************************************************
    2815                         // methode in 2 step
    2816                         // 1 - compute the number of new edge to allocate
    2817                         // 2 - construct the edge
    2818 remark:
    2819 in this part we suppose to have a background mesh with the same
    2820 geometry
    2821 
    2822 To construct the discretisation of the new mesh we have to
    2823 rediscretize the boundary of background Mesh
    2824 because we have only the pointeur from the background mesh to the geometry.
    2825 We need the abcisse of the background mesh vertices on geometry
    2826 so a vertex is
    2827 0 on GeometricalVertex ;
    2828 1 on GeometricalEdge + abcisse
    2829 2 internal
    2830 
    2831                          *************************************************************************/
    2832                         assert(&BTh.Gh == &Gh);
    2833 
    2834                         long int verbosity=0;
    2835                         BTh.NbRef++; // add a ref to BackGround Mesh
    2836                         PreInit(inbvx);
    2837                         BTh.SetVertexFieldOn();
    2838                                 int * bcurve = new int[Gh.NbOfCurves]; //
    2839 
    2840                                 // we have 2 ways to make the loop
    2841                                 // 1) on the geometry
    2842                                 // 2) on the background mesh
    2843                                 //  if you do the loop on geometry, we don't have the pointeur on background,
    2844                                 //  and if you do the loop in background we have the pointeur on geometry
    2845                                 // so do the walk on  background
    2846                                 //  Int4 NbVerticesOnGeomVertex;
    2847                                 //  VertexOnGeom * VerticesOnGeomVertex; 
    2848                                 //  Int4 NbVerticesOnGeomEdge;
    2849                                 //  VertexOnGeom * VerticesOnGeomEdge;
    2850 
    2851 
    2852                                 NbVerticesOnGeomVertex=0;
    2853                                 NbVerticesOnGeomEdge=0;
    2854                                 //1 copy of the  Required vertex
    2855                                 int i;
    2856                                 for ( i=0;i<Gh.nbv;i++)
    2857                                         if (Gh[i].Required()) NbVerticesOnGeomVertex++;
    2858 
    2859                                 VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];
    2860                                 VertexOnBThVertex = new VertexOnVertex[NbVerticesOnGeomVertex];
    2861                                 //
    2862                                 if( NbVerticesOnGeomVertex >= nbvx)
    2863                                 {
    2864                                         cerr << " Too much vertices on geometry " << NbVerticesOnGeomVertex << " >= " << nbvx << endl;
    2865                                         MeshError(1,this);
    2866                                 }
    2867                                 assert(vertices);
    2868                                 for (i=0;i<Gh.nbv;i++)
    2869                                         if (Gh[i].Required()) {//Gh  vertices Required
    2870                                                 vertices[nbv] =  Gh[i];
    2871                                                 vertices[nbv].i = I2(0,0);
    2872                                                 Gh[i].to = vertices + nbv;// save Geom -> Th
    2873                                                 VerticesOnGeomVertex[nbv]= VertexOnGeom(vertices[nbv],Gh[i]);
    2874                                                 // cout << "--------- "  <<Number(Gh[i].to) << " " << Gh[i].to << " " << i << endl;
    2875                                                 nbv++;}
    2876                                         else Gh[i].to=0;
    2877                                 //
    2878                                 for (i=0;i<BTh.NbVerticesOnGeomVertex;i++)
    2879                                 {
    2880                                         VertexOnGeom & vog = BTh.VerticesOnGeomVertex[i];
    2881                                         if (vog.IsRequiredVertex()) {
    2882                                                 GeometricalVertex * gv = vog;
    2883                                                 Vertex *bv = vog;
    2884                                                 assert(gv->to);// use of Geom -> Th
    2885                                                 VertexOnBThVertex[NbVertexOnBThVertex++] = VertexOnVertex(gv->to,bv);
    2886                                                 gv->to->m = bv->m; // for taking the metrix of the background mesh
    2887                                                 ;}
    2888                                 }
    2889                                 assert(NbVertexOnBThVertex == NbVerticesOnGeomVertex);
    2890                                 // new stuff FH with curve
    2891                                 //  find the begin of the curve in BTh
    2892                                 {
    2893                                         Gh.UnMarkEdges();       
    2894                                         int bfind=0;
    2895                                         /*
    2896                                            cout << " nb curves = " << Gh.NbOfCurves << endl;
    2897                                            for(int i=0;i<Gh.NbOfCurves ;i++)
    2898                                            {
    2899                                            cout << " Curve " << i << " begin e=" << Gh.Number(Gh.curves[i].be) << " k=" << Gh.curves[i].kb
    2900                                            << "  end e= " << Gh.Number(Gh.curves[i].ee) << " k=" << Gh.curves[i].ke << endl;
    2901                                            }*/
    2902                                         for (int i=0;i<Gh.NbOfCurves;i++)
    2903                                         {
    2904                                                 bcurve[i]=-1;
    2905                                         }
    2906 
    2907                                         for (int iedge=0;iedge<BTh.nbe;iedge++)
    2908                                         {     
    2909                                                 Edge & ei = BTh.edges[iedge];
    2910                                                 for(int je=0;je<2;je++) // for the 2 extremites
    2911                                                         if (!ei.on->Mark() && ei[je].on->IsRequiredVertex() )
    2912                                                         {
    2913                                                                 // a begin of curve
    2914                                                                 int nc = ei.on->CurveNumber;
    2915 
    2916                                                                 //cout << "curve " <<  nc << " v " << Gh.Number((GeometricalVertex *) *ei[je].on) << " "
    2917                                                                 //     << " e "  << " " << Gh.Number(ei.on) << " vc " << Gh.Number((*Gh.curves[nc].be)[Gh.curves[nc].kb]) << endl;
    2918                                                                 if(
    2919                                                                                 ei.on==Gh.curves[nc].be    &&
    2920                                                                                 (GeometricalVertex *) *ei[je].on == &(*Gh.curves[nc].be)[Gh.curves[nc].kb] //  same extremity
    2921                                                                   )     
    2922                                                                 {
    2923                                                                         // cout << " find " << endl;
    2924                                                                         bcurve[nc]=iedge*2+je;
    2925                                                                         bfind++;       
    2926                                                                 }     
    2927                                                         }
    2928                                         }
    2929                                         assert( bfind==Gh.NbOfCurves);
    2930                                 }         
    2931                                 // method in 2 + 1 step
    2932                                 //  0.0) compute the length and the number of vertex to do allocation
    2933                                 //  1.0)  recompute the length
    2934                                 //  1.1)   compute the  vertex
    2935                                 Int4 nbex=0,NbVerticesOnGeomEdgex=0;
    2936                                 for (int step=0; step <2;step++)
    2937                                 {
    2938                                         Int4 NbOfNewPoints=0;
    2939                                         Int4 NbOfNewEdge=0;
    2940                                         Int4 iedge;
    2941                                         Gh.UnMarkEdges();       
    2942                                         /*   add Curve loop  FH   
    2943                                         // find a starting back groud edges to walk
    2944                                         for (iedge=0;iedge<BTh.nbe;iedge++) {     
    2945                                         Edge & ei = BTh.edges[iedge];
    2946                                         for(int jedge=0;jedge<2;jedge++) // for the 2 extremites
    2947                                         if (!ei.on->Mark() && ei[jedge].on->IsRequiredVertex() )
    2948                                         {
    2949                                         */ 
    2950                                         // new code FH 2004
    2951                                         Real8 L=0;
    2952                                         for (int icurve=0;icurve<Gh.NbOfCurves;icurve++)
    2953                                         {
    2954                                                 iedge=bcurve[icurve]/2;
    2955                                                 int jedge=bcurve[icurve]%2;
    2956                                                 if( ! Gh.curves[icurve].master) continue; // we skip all equi curve
    2957                                                 Edge & ei = BTh.edges[iedge];
    2958                                                 // warning: ei.on->Mark() can be change in
    2959                                                 // loop for(jedge=0;jedge<2;jedge++)
    2960                                                 // new curve 
    2961                                                 // good the find a starting edge
    2962                                                 Real8 Lstep=0,Lcurve=0;// step between two points   (phase==1)
    2963                                                 Int4 NbCreatePointOnCurve=0;// Nb of new points on curve     (phase==1)
    2964 
    2965 
    2966                                                 //    cout.precision(16);
    2967                                                 for(int phase=0;phase<=step;phase++)
    2968                                                 {
    2969 
    2970                                                         for(Curve * curve= Gh.curves+icurve;curve;curve= curve->next)
    2971                                                         {
    2972 
    2973                                                                 int icurveequi= Gh.Number(curve);
    2974 
    2975                                                                 if( phase == 0 &&  icurveequi != icurve)  continue;
    2976 
    2977                                                                 int k0=jedge,k1;
    2978                                                                 Edge * pe=  BTh.edges+iedge;
    2979                                                                 //GeometricalEdge *ong = ei.on;
    2980                                                                 int iedgeequi=bcurve[icurveequi]/2;
    2981                                                                 int jedgeequi=bcurve[icurveequi]%2;
    2982 
    2983                                                                 int k0equi=jedgeequi,k1equi;             
    2984                                                                 Edge * peequi= BTh.edges+iedgeequi;
    2985                                                                 GeometricalEdge *ongequi = peequi->on;
    2986 
    2987                                                                 Real8 sNew=Lstep;// abcisse of the new points (phase==1)
    2988                                                                 L=0;// length of the curve
    2989                                                                 Int4 i=0;// index of new points on the curve
    2990                                                                 register GeometricalVertex * GA0 = *(*peequi)[k0equi].on;
    2991                                                                 Vertex *A0;
    2992                                                                 A0 = GA0->to;  // the vertex in new mesh
    2993                                                                 Vertex *A1;
    2994                                                                 VertexOnGeom *GA1;
    2995                                                                 Edge * PreviousNewEdge = 0;
    2996                                                                 //  cout << "  --------------New Curve phase " << phase
    2997                                                                 //       << "---------- A0=" << *A0 << ei[k0]  <<endl;
    2998                                                                 assert (A0-vertices>=0 && A0-vertices <nbv);
    2999                                                                 if(ongequi->Required() )
    3000                                                                 {
    3001                                                                         GeometricalVertex *GA1 = *(*peequi)[1-k0equi].on;
    3002                                                                         A1 = GA1->to;  //
    3003                                                                 }       
    3004                                                                 else
    3005                                                                         for(;;)
    3006                                                                         {
    3007                                                                                 //   assert(pe && BTh.Number(pe)>=0 && BTh.Number(pe)<=BTh.nbe);
    3008                                                                                 Edge &ee=*pe;
    3009                                                                                 Edge &eeequi=*peequi;
    3010                                                                                 k1 = 1-k0; // next vertex of the edge
    3011                                                                                 k1equi= 1 - k0equi;
    3012 
    3013                                                                                 assert(pe  && ee.on);
    3014                                                                                 ee.on->SetMark();
    3015                                                                                 Vertex & v0=ee[0], & v1=ee[1];
    3016                                                                                 R2 AB= (R2) v1 - (R2) v0;
    3017                                                                                 Real8 L0=L,LAB;
    3018                                                                                 LAB =  LengthInterpole(v0.m,v1.m,AB);
    3019                                                                                 L+= LAB;   
    3020                                                                                 if (phase) {// computation of the new points
    3021                                                                                         while ((i!=NbCreatePointOnCurve) && sNew <= L) {
    3022                                                                                                 //    cout  << " L0= " << L0 << " L " << L << " sN="
    3023                                                                                                 //         << sNew << " LAB=" << LAB << " NBPC =" <<NbCreatePointOnCurve<< " i " << i  << endl;
    3024                                                                                                 assert (sNew >= L0);
    3025                                                                                                 assert(LAB);
    3026 
    3027 
    3028                                                                                                 assert(vertices && nbv<nbvx);
    3029                                                                                                 assert(edges && nbe < nbex);
    3030                                                                                                 assert(VerticesOnGeomEdge && NbVerticesOnGeomEdge < NbVerticesOnGeomEdgex);
    3031                                                                                                 // new vertex on edge
    3032                                                                                                 A1=vertices+nbv++;
    3033                                                                                                 GA1=VerticesOnGeomEdge+NbVerticesOnGeomEdge;
    3034                                                                                                 Edge *e = edges + nbe++;
    3035                                                                                                 Real8 se= (sNew-L0)/LAB;
    3036                                                                                                 assert(se>=0 && se < 1.000000001);
    3037                                                                                                 se =  abscisseInterpole(v0.m,v1.m,AB,se,1);
    3038                                                                                                 assert(se>=0 && se <= 1);
    3039                                                                                                 //((k1==1) != (k1==k1equi))
    3040                                                                                                 se = k1 ? se : 1. - se;
    3041                                                                                                 se = k1==k1equi ? se : 1. - se;
    3042                                                                                                 VertexOnBThEdge[NbVerticesOnGeomEdge++] = VertexOnEdge(A1,&eeequi,se); // save
    3043                                                                                                 ongequi = Gh.ProjectOnCurve(eeequi,se,*A1,*GA1);
    3044                                                                                                 A1->ReferenceNumber = eeequi.ref;
    3045                                                                                                 A1->DirOfSearch =NoDirOfSearch;
    3046                                                                                                 //cout << icurveequi << " " << i << " " <<  *A1 << endl;
    3047                                                                                                 e->on = ongequi;
    3048                                                                                                 e->v[0]=  A0;
    3049                                                                                                 e->v[1]=  A1;
    3050                                                                                                 if(verbosity>99)
    3051                                                                                                         cout << i << "+ New P "<< nbv-1 << " "  <<sNew<< " L0=" << L0
    3052                                                                                                                 << " AB=" << LAB << " s=" << (sNew-L0)/LAB << " se= " 
    3053                                                                                                                 << se <<" B edge " << BTh.Number(ee) << " signe = " << k1 <<" " << A1->r <<endl;
    3054 
    3055                                                                                                 e->ref = eeequi.ref;
    3056                                                                                                 e->adj[0]=PreviousNewEdge;
    3057 
    3058                                                                                                 if (PreviousNewEdge)
    3059                                                                                                         PreviousNewEdge->adj[1] =  e;
    3060                                                                                                 PreviousNewEdge = e;
    3061                                                                                                 A0=A1;
    3062                                                                                                 sNew += Lstep;
    3063                                                                                                 //   cout << " sNew = " << sNew << " L = " << L
    3064                                                                                                 //        << "  ------" <<NbCreatePointOnCurve << " " << i <<  endl;
    3065                                                                                                 if (++i== NbCreatePointOnCurve) break;
    3066                                                                                         }
    3067 
    3068                                                                                 }               
    3069                                                                                 assert(ee.on->CurveNumber==ei.on->CurveNumber);
    3070                                                                                 if(verbosity>98) cout <<  BTh.Number(ee) << " " << " on=" << *ee[k1].on << " "<< ee[k1].on->IsRequiredVertex() <<  endl;
    3071                                                                                 if ( ee[k1].on->IsRequiredVertex()) {
    3072                                                                                         assert(eeequi[k1equi].on->IsRequiredVertex());
    3073                                                                                         register GeometricalVertex * GA1 = *eeequi[k1equi].on;
    3074                                                                                         A1=GA1->to;// the vertex in new mesh
    3075                                                                                         assert (A1-vertices>=0 && A1-vertices <nbv);
    3076                                                                                         break;}
    3077                                                                                         if (!ee.adj[k1])
    3078                                                                                         {cerr << "Error adj edge " << BTh.Number(ee) << ", nbe = "  << nbe
    3079                                                                                                 << " Gh.vertices " << Gh.vertices
    3080                                                                                                         << " k1 = " << k1 << " on=" << *ee[k1].on << endl;
    3081                                                                                                 cerr << ee[k1].on->gv-Gh.vertices << endl;
    3082                                                                                         }
    3083                                                                                         pe = ee.adj[k1]; // next edge
    3084                                                                                         k0 = pe->Intersection(ee);
    3085                                                                                         peequi= eeequi.adj[k1equi];  // next edge
    3086                                                                                         k0equi=peequi->Intersection(eeequi);           
    3087                                                                         }// for(;;) end of the curve
    3088 
    3089 
    3090                                                                 if (phase) // construction of the last edge
    3091                                                                 {
    3092                                                                         Edge *e = edges + nbe++;
    3093                                                                         if (verbosity>10)
    3094                                                                                 cout << " Fin curve A1" << *A1 << " " << icurve << " <=> " << icurveequi <<"-----" <<
    3095                                                                                         NbCreatePointOnCurve << " == " <<i<<endl;
    3096                                                                         e->on  = ongequi;
    3097                                                                         e->v[0]=  A0;
    3098                                                                         e->v[1]=        A1;
    3099                                                                         e->ref = peequi->ref;
    3100                                                                         e->adj[0]=PreviousNewEdge;
    3101                                                                         e->adj[1]=0;
    3102                                                                         if (PreviousNewEdge)
    3103                                                                                 PreviousNewEdge->adj[1] =  e;
    3104                                                                         PreviousNewEdge = e;
    3105 
    3106                                                                         assert(i==NbCreatePointOnCurve);
    3107 
    3108                                                                 }
    3109                                                         } //  end loop on equi curve
    3110 
    3111                                                         if (!phase)  { //
    3112                                                                 Int4 NbSegOnCurve = Max((Int4)(L+0.5),(Int4) 1);// nb of seg
    3113                                                                 Lstep = L/NbSegOnCurve;
    3114                                                                 Lcurve = L;
    3115                                                                 NbCreatePointOnCurve = NbSegOnCurve-1;
    3116 
    3117                                                                 for(Curve * curve= Gh.curves+icurve;curve;curve= curve->next)
    3118                                                                 {
    3119                                                                         NbOfNewEdge += NbSegOnCurve;
    3120                                                                         NbOfNewPoints += NbCreatePointOnCurve;
    3121                                                                 }
    3122                                                                 if(verbosity>5)
    3123                                                                         cout << icurve << " NbSegOnCurve = " <<  NbSegOnCurve << " Lstep="
    3124                                                                                 << Lstep <<" " << NbOfNewPoints<< " NBPC= " << NbCreatePointOnCurve <<endl;
    3125                                                                 // do'nt
    3126                                                                 //  if(NbCreatePointOnCurve<1) break;
    3127                                                         }
    3128                                                 }//for(phase;;)
    3129                                                 /*  modif FH add Curve class             
    3130                                                         }}//for (iedge=0;iedge<BTh.nbe;iedge++)
    3131                                                         */
    3132                                                 // new code Curve class         
    3133                                 } //  end of curve loop
    3134                                 // end new code     
    3135                                 // do the allocation
    3136                                 if(step==0)
    3137                                 {
    3138                                         //if(!NbOfNewPoints) break;// nothing ????? bug
    3139                                         if(nbv+NbOfNewPoints > nbvx)
    3140                                         {
    3141                                                 cerr << " Too much vertices on geometry " << nbv+NbOfNewPoints  << " >= " << nbvx << endl;
    3142                                                 MeshError(3,this);
    3143                                         }
    3144                                         //cout << " NbOfNewEdge" << NbOfNewEdge << " NbOfNewPoints " << NbOfNewPoints << endl;
    3145                                         edges = new Edge[NbOfNewEdge];
    3146                                         nbex = NbOfNewEdge;
    3147                                         if(NbOfNewPoints) { //
    3148                                                 VerticesOnGeomEdge = new VertexOnGeom[NbOfNewPoints];
    3149                                                 NbVertexOnBThEdge =NbOfNewPoints;
    3150                                                 VertexOnBThEdge = new  VertexOnEdge[NbOfNewPoints];
    3151                                                 NbVerticesOnGeomEdgex = NbOfNewPoints; }
    3152                                                 NbOfNewPoints =0;
    3153                                                 NbOfNewEdge = 0;
    3154                                 }
    3155                                 } // for(step;;)
    3156                                 assert(nbe);
    3157 
    3158                                 delete [] bcurve;
    3159 
    3160 
    3161                                 Insert();
    3162                                 ForceBoundary();
    3163                                 FindSubDomain();
    3164 
    3165                                 NewPoints(BTh,KeepBackVertices) ;
    3166                                 CurrentTh = 0;
    3167                 }
    3168 
    3169                 void Triangles::GeomToTriangles0(Int4 inbvx)
    3170                 {
    3171                         Gh.NbRef++;// add a ref to GH
    3172 
    3173 
    3174                         Int4 i,NbOfCurves=0,NbNewPoints,NbEdgeCurve;
    3175                         Real8 lcurve, lstep,s;
    3176 
    3177                                 R2 AB;
    3178                                 GeometricalVertex *a,*b;
    3179                                 Vertex *va,*vb;
    3180                                 GeometricalEdge * e;
    3181                                 PreInit(inbvx);
    3182                                 int  background = &BTh != this;
    3183                                 //  int  SameGeom = background && (&BTh.Gh == &Gh);
    3184                                 nbv = 0;
    3185                                 NbVerticesOnGeomVertex=0;
    3186                                 NbVerticesOnGeomEdge=0;
    3187                                 for (i=0;i<Gh.nbv;i++)
    3188                                         if (Gh[i].Required() && Gh[i].IsThe() ) NbVerticesOnGeomVertex++;
    3189                                 VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex]; 
    3190                                 //
    3191                                 if( NbVerticesOnGeomVertex >= nbvx)
    3192                                 {
    3193                                         cerr << " Too much vertices on geometry " << NbVerticesOnGeomVertex << " >= " << nbvx << endl;
    3194                                         MeshError(1,this);
    3195                                 }
    3196                                 for (i=0;i<Gh.nbv;i++)
    3197                                         if (Gh[i].Required()&& Gh[i].IsThe()  ) {//Gh  vertices Required
    3198                                                 if (nbv < nbvx)
    3199                                                         vertices[nbv] = Gh[i];
    3200                                                 Gh[i].to = vertices + nbv;// save Geom -> Th
    3201                                                 VerticesOnGeomVertex[nbv]= VertexOnGeom(*Gh[i].to,Gh[i]);
    3202                                                 //  cout << "--------- "  <<Number(Gh[i].to) << " " << Gh[i].to << " " << i << endl;
    3203                                                 nbv++;
    3204                                         }
    3205                                 //  assert( Gh.nbv < nbvx);
    3206 
    3207                                 // Method in 2 step:  0 and 1
    3208                                 // 1) compute de nb of edge
    3209                                 // 2) construct the edge   
    3210                                 // generation of the curves
    3211                                 assert(! edges);
    3212                                 // 2 step
    3213                                 // --step=0 to compute the number of edges + alloc at end
    3214                                 // --step=1 to construct the edges
    3215                                 for (int step=0;step<2;step++)
    3216                                 {//  for (int step=0;step<2;step++)
    3217                                         Int4 nbex = 0;
    3218                                         nbe = 0;
    3219                                         Int4 NbVerticesOnGeomEdge0=NbVerticesOnGeomEdge;
    3220                                         //  cout <<  "  -------------- step =" << step << endl;
    3221                                         Gh.UnMarkEdges();       
    3222                                         NbOfCurves = 0;
    3223                                         for (i=0;i<Gh.nbe;i++) {
    3224                                                 GeometricalEdge & ei = Gh.edges[i];   
    3225                                                 if (!ei.Dup()) // a good curve (not dup )
    3226                                                         for(int j=0;j<2;j++)
    3227                                                                 if (!ei.Mark() && ei[j].Required()) {
    3228                                                                         // warning ei.Mark() can be change in loop for(j=0;j<2;j++)
    3229                                                                         //  cout << " New curve = " << NbOfCurves << endl;
    3230                                                                         Int4 nbvend  =0;
    3231 
    3232                                                                         Edge * PreviousNewEdge=0;
    3233 
    3234                                                                         lstep = -1;//to do not create points
    3235                                                                         if(ei.Required())
    3236                                                                         {
    3237                                                                                 if (j==0)
    3238                                                                                         if(step==0)
    3239                                                                                                 nbe++;
    3240                                                                                         else
    3241                                                                                         {
    3242                                                                                                 e = & ei;
    3243                                                                                                 a=ei(0)->The();
    3244                                                                                                 b=ei(1)->The();
    3245                                                                                                 assert(edges);
    3246                                                                                                 edges[nbe].v[0]=a->to;
    3247                                                                                                 edges[nbe].v[1]=b->to;;
    3248                                                                                                 edges[nbe].ref = e->ref;
    3249                                                                                                 edges[nbe].on = e;
    3250                                                                                                 edges[nbe].adj[0] = 0;
    3251                                                                                                 edges[nbe].adj[1] = 0;
    3252                                                                                                 nbe++;}
    3253                                                                         }
    3254                                                                         else
    3255                                                                         { // on curve ------
    3256                                                                                 for ( int kstep=0;kstep<= step;kstep++)
    3257                                                                                 { // begin  for ( int kstep=0;kstep<= step;kstep++)
    3258                                                                                         // if 2nd step where 2 step
    3259                                                                                         // -- 1 compute le length of the curve
    3260                                                                                         // -- create the points and edge
    3261                                                                                         PreviousNewEdge=0;
    3262                                                                                         NbNewPoints=0;
    3263                                                                                         NbEdgeCurve=0;
    3264                                                                                         assert(nbvend < nbvx);
    3265                                                                                         lcurve =0;
    3266                                                                                         s = lstep;
    3267                                                                                         int k=j;
    3268                                                                                         e = & ei;
    3269                                                                                         a=ei(k)->The();
    3270                                                                                         va = a->to;
    3271                                                                                         e->SetMark();
    3272                                                                                         //  cout << " New curve " ;
    3273 
    3274                                                                                         // if SameGeo  We have go in the background geometry
    3275                                                                                         // to find the discretisation of the curve
    3276 
    3277                                                                                         for(;;)
    3278                                                                                         {
    3279                                                                                                 k = 1-k;
    3280                                                                                                 b= (*e)(k)->The();
    3281                                                                                                 AB = b->r - a->r;
    3282                                                                                                 Metric MA = background ? BTh.MetricAt(a->r) :a->m ;
    3283                                                                                                 Metric MB =  background ? BTh.MetricAt(b->r) :b->m ;
    3284                                                                                                 Real8 ledge = (MA(AB) + MB(AB))/2;
    3285                                                                                                 //
    3286                                                                                                 const int MaxSubEdge = 10;
    3287                                                                                                 int NbSubEdge = 1;
    3288                                                                                                 Real8 lSubEdge[MaxSubEdge];
    3289                                                                                                 R2 A,B;
    3290                                                                                                 if (ledge < 1.5)
    3291                                                                                                         lSubEdge[0] = ledge;
    3292                                                                                                 else {
    3293                                                                                                         NbSubEdge = Min( MaxSubEdge, (int) (ledge +0.5));
    3294                                                                                                         A= a->r;
    3295                                                                                                         Metric MAs =MA,MBs;
    3296                                                                                                         // cout << " lSubEdge old=" << ledge
    3297                                                                                                         //      << " new " << A << MA << endl;
    3298                                                                                                         ledge = 0;
    3299                                                                                                         Real8 x =0, xstep= 1. /  NbSubEdge;
    3300                                                                                                         for (int kk=0; kk < NbSubEdge; kk++,A=B,MAs=MBs ) {
    3301                                                                                                                 x += xstep;
    3302                                                                                                                 B =  e->F(k ? x : 1-x);
    3303                                                                                                                 MBs= background ? BTh.MetricAt(B) :Metric(1-x, MA, x ,MB);
    3304                                                                                                                 AB = A-B;
    3305                                                                                                                 lSubEdge[kk]= (ledge += (MAs(AB)+MBs(AB))/2);
    3306                                                                                                                 // cout << "     " << lSubEdge[kk] << " x " << x 
    3307                                                                                                                 //      << " " << A << B << MA << MB<< endl ;
    3308                                                                                                         }
    3309                                                                                                         //  cout << endl;
    3310                                                                                                 }
    3311 
    3312                                                                                                 Real8 lcurveb = lcurve+ ledge ;
    3313                                                                                                 while (lcurve<=s && s <= lcurveb && nbv < nbvend)
    3314                                                                                                 {
    3315                                                                                                         // New points
    3316 
    3317                                                                                                         // Real8 aa=(lcurveb-s)/ledge;
    3318                                                                                                         // Real8 bb=(s-lcurve)/ledge;
    3319 
    3320                                                                                                         Real8 ss = s-lcurve;
    3321                                                                                                         // 1) find the SubEdge containing ss by dichotomie
    3322                                                                                                         int kk0=-1,kk1=NbSubEdge-1,kkk;
    3323                                                                                                         Real8 ll0=0,ll1=ledge,llk;
    3324                                                                                                         while (kk1-kk0>1)
    3325                                                                                                         {
    3326                                                                                                                 if (ss < (llk=lSubEdge[kkk=(kk0+kk1)/2]))
    3327                                                                                                                         kk1=kkk,ll1=llk;
    3328                                                                                                                 else
    3329                                                                                                                         kk0=kkk,ll0=llk;}
    3330                                                                                                                 assert(kk1 != kk0);
    3331 
    3332                                                                                                                 Real8 sbb = (ss-ll0  )/(ll1-ll0);
    3333                                                                                                                 Real8 bb = (kk1+sbb)/NbSubEdge, aa=1-bb;
    3334 
    3335                                                                                                                 // new vertex on edge
    3336                                                                                                                 vb = &vertices[nbv++];
    3337                                                                                                                 vb->m = Metric(aa,a->m,bb,b->m);
    3338                                                                                                                 vb->ReferenceNumber = e->ref;
    3339                                                                                                                 vb->DirOfSearch =NoDirOfSearch;
    3340                                                                                                                 Real8 abcisse = k ? bb : aa;
    3341                                                                                                                 vb->r =  e->F( abcisse );
    3342                                                                                                                 VerticesOnGeomEdge[NbVerticesOnGeomEdge++]= VertexOnGeom(*vb,*e,abcisse);       
    3343 
    3344                                                                                                                 // to take in account the sens of the edge
    3345 
    3346                                                                                                                 s += lstep;
    3347                                                                                                                 edges[nbe].v[0]=va;
    3348                                                                                                                 edges[nbe].v[1]=vb;
    3349                                                                                                                 edges[nbe].ref = e->ref;
    3350                                                                                                                 edges[nbe].on = e;
    3351                                                                                                                 edges[nbe].adj[0] = PreviousNewEdge;
    3352                                                                                                                 if(PreviousNewEdge)
    3353                                                                                                                         PreviousNewEdge->adj[1] = &edges[nbe];
    3354                                                                                                                 PreviousNewEdge = edges + nbe;
    3355                                                                                                                 nbe++;
    3356                                                                                                                 va = vb;
    3357                                                                                                 }
    3358                                                                                                 lcurve = lcurveb;
    3359                                                                                                 e->SetMark();
    3360                                                                                                 // cout << e-Gh.edges << ", " << k << " "
    3361                                                                                                 //      <<(*e)[k].r <<" " <<(*e)[1-k].r <<" "
    3362                                                                                                 //      << lcurve<< ";; " ;                         
    3363                                                                                                 a=b;
    3364                                                                                                 if (b->Required() ) break;
    3365                                                                                                 int kprev=k;
    3366                                                                                                 k = e->SensAdj[kprev];// next vertices
    3367                                                                                                 e = e->Adj[kprev];
    3368                                                                                                 assert(e);
    3369                                                                                         }// for(;;)
    3370                                                                                         vb = b->to;
    3371                                                                                         //            cout << endl;
    3372                                                                                         NbEdgeCurve = Max((Int4) (lcurve +0.5), (Int4) 1);
    3373                                                                                         NbNewPoints = NbEdgeCurve-1;
    3374                                                                                         if(!kstep)
    3375                                                                                         { NbVerticesOnGeomEdge0 += NbNewPoints;
    3376                                                                                                 NbOfCurves++;}
    3377 
    3378                                                                                                 nbvend=nbv+NbNewPoints;
    3379 
    3380                                                                                                 lstep = lcurve / NbEdgeCurve;
    3381                                                                                                 //   cout <<"lstep " << lstep << " lcurve "
    3382                                                                                                 //    << lcurve << " NbEdgeCurve " << NbEdgeCurve << " " <<NbVerticesOnGeomEdge0<<" " <<NbVerticesOnGeomEdge<<" step =" <<step<<  endl;
    3383                                                                                 }
    3384                                                                                 // end of curve --
    3385                                                                                 if (edges) { // last edges of the curves
    3386                                                                                         edges[nbe].v[0]=va;
    3387                                                                                         edges[nbe].v[1]=vb;
    3388                                                                                         edges[nbe].ref = e->ref;
    3389                                                                                         edges[nbe].on = e;
    3390                                                                                         edges[nbe].adj[0] = PreviousNewEdge;
    3391                                                                                         edges[nbe].adj[1] = 0;
    3392                                                                                         if(PreviousNewEdge)
    3393                                                                                                 PreviousNewEdge->adj[1] = & edges[nbe];
    3394 
    3395                                                                                         nbe++;}
    3396                                                                                 else
    3397                                                                                         nbe += NbEdgeCurve;
    3398                                                                         } // end on  curve ---
    3399                                                                 } // if (edges[i][j].Corner()) 
    3400                                         } // for (i=0;i<nbe;i++)
    3401                                         if(!step) {
    3402                                                 // cout << "edges " << edges << " VerticesOnGeomEdge " <<VerticesOnGeomEdge << endl;
    3403                                                 assert(!edges);
    3404                                                 assert(!VerticesOnGeomEdge);
    3405                                                 edges = new Edge[nbex=nbe];
    3406                                                 if(NbVerticesOnGeomEdge0)
    3407                                                         VerticesOnGeomEdge = new VertexOnGeom[NbVerticesOnGeomEdge0];
    3408                                                 assert(edges);
    3409                                                 assert(VerticesOnGeomEdge || NbVerticesOnGeomEdge0 ==0);
    3410                                                 // do the vertex on a geometrical vertex
    3411                                                 NbVerticesOnGeomEdge0 = NbVerticesOnGeomEdge;       
    3412                                         }
    3413                                         else
    3414                                                 assert(NbVerticesOnGeomEdge == NbVerticesOnGeomEdge0);
    3415                                         //     cout << " Nb of Curves = " << NbOfCurves << "nbe = " << nbe
    3416                                         //        << "== " << nbex << "  nbv = " << nbv <<  endl;
    3417                                         assert(nbex=nbe);
    3418                                 } // for (step=0;step<2;step++)
    3419 
    3420                                 Insert();
    3421                                 ForceBoundary();
    3422                                 FindSubDomain();
    3423 
    3424                                 // NewPointsOld(*this) ;
    3425                                 NewPoints(*this,0) ;
    3426                                 CurrentTh = 0;
    3427                 }
    3428 
    3429                 Edge** Triangles::MakeGeometricalEdgeToEdge()
    3430                 {
    3431                         assert(Gh.nbe);
    3432                         Edge **e= new (Edge* [Gh.nbe]);
    3433 
    3434                         Int4 i;
    3435                         for ( i=0;i<Gh.nbe ; i++)
    3436                                 e[i]=NULL;
    3437                         for ( i=0;i<nbe ; i++)
    3438                         {
    3439                                 Edge * ei = edges+i;
    3440                                 GeometricalEdge *on = ei->on;
    3441                                 e[Gh.Number(on)] = ei;   
    3442                         }
    3443                         for ( i=0;i<nbe ; i++)
    3444                                 for (int ii=0;ii<2;ii++) {
    3445                                         Edge * ei = edges+i;
    3446                                         GeometricalEdge *on = ei->on;
    3447                                         int j= ii;
    3448                                         while (!(*on)[j].Required()) {
    3449                                                 //      cout << i << " " << ii << " j= " << j << " curve = "
    3450                                                 //           <<  on->CurveNumber << "  " << Gh.Number(on) << " on " << j
    3451                                                 //   << " s0 " << Gh.Number( (*on)[0]) << " s1  " << Gh.Number( (*on)[1])
    3452                                                 //   << " ->  " ;
    3453                                                 Adj(on,j); // next geom edge
    3454                                                 j=1-j;
    3455                                                 //       cout << Gh.Number(on) << "  " << j  << " e[ON] =  " <<  e[Gh.Number(on)]
    3456                                                 //    << " s0 " << Gh.Number( (*on)[0]) << " s1  " << Gh.Number( (*on)[1]) << endl;
    3457                                                 if (e[Gh.Number(on)])  break; // optimisation     
    3458                                                 e[Gh.Number(on)] = ei;
    3459                                         }
    3460                                 }
    3461 
    3462                         int kk=0;
    3463                         for ( i=0;i<Gh.nbe ; i++)
    3464                                 if (!e[i])
    3465                                         if(kk++<10) {
    3466                                                 cerr << " Bug -- the geometrical edge " << i << " is on no edge curve = " << Gh.edges[i].CurveNumber
    3467                                                         << " s0 " << Gh.Number( Gh.edges[i][0]) << " s1  " << Gh.Number( Gh.edges[i][1]) << endl;
    3468                                                 //       assert( e[i]);
    3469                                         }
    3470                         if(kk) MeshError(997,this);
    3471 
    3472                         return e;
    3473                 }
    3474 
    3475                 Triangles::~Triangles() {
    3476                         long int verbosity=2;
    3477                         //assert(NbRef<=0);
    3478                         if (CurrentTh == this) CurrentTh=0;
    3479                         //if(vertices)  delete [] vertices; //TEST  crash if not commented
    3480                         if(edges)     delete [] edges;
    3481                         if(triangles) delete [] triangles;
    3482                         if(quadtree)  delete  quadtree;
    3483                         //if(ordre)     delete [] ordre; //TEST  crash if not commented
    3484                         if( subdomains) delete []  subdomains;
    3485                         if (VerticesOnGeomEdge) delete [] VerticesOnGeomEdge;
    3486                         if (VerticesOnGeomVertex) delete [] VerticesOnGeomVertex;
    3487                         //if (name) delete [] name; //TEST crash if not commented
    3488                         if (identity) delete [] identity;
    3489                         if (VertexOnBThVertex) delete [] VertexOnBThVertex;
    3490                         if (VertexOnBThEdge) delete [] VertexOnBThEdge;
    3491 
    3492                         if (&Gh) {
    3493                                 if (Gh.NbRef>0) Gh.NbRef--;
    3494                                 else if (Gh.NbRef==0) delete &Gh;
    3495                         }
    3496                         if (&BTh && (&BTh != this)) {
    3497                                 if (BTh.NbRef>0) BTh.NbRef--;
    3498                                 else if (BTh.NbRef==0) delete &BTh;
    3499                         }
    3500                         PreInit(0); // set all to zero
    3501                 }
    3502 
    3503                 void Triangles::SetIntCoor(const char * strfrom)
    3504                 {
    3505                         pmin =  vertices[0].r;
    3506                         pmax =  vertices[0].r;
    3507 
    3508                         // recherche des extrema des vertices pmin,pmax
    3509                         Int4 i;
    3510                         for (i=0;i<nbv;i++) {
    3511                                 pmin.x = Min(pmin.x,vertices[i].r.x);
    3512                                 pmin.y = Min(pmin.y,vertices[i].r.y);
    3513                                 pmax.x = Max(pmax.x,vertices[i].r.x);
    3514                                 pmax.y = Max(pmax.y,vertices[i].r.y);
    3515                         }
    3516                         R2 DD = (pmax-pmin)*0.05;
    3517                         pmin = pmin-DD;
    3518                         pmax = pmax+DD;
    3519                         coefIcoor= (MaxICoor)/(Max(pmax.x-pmin.x,pmax.y-pmin.y));
    3520                         assert(coefIcoor >0);
    3521 
    3522                         // generation of integer coord 
    3523                         for (i=0;i<nbv;i++) {
    3524                                 vertices[i].i = toI2(vertices[i].r);   
    3525                         }
    3526 
    3527                         // computation of the det
    3528                         int Nberr=0;
    3529                         for (i=0;i<nbt;i++)
    3530                         {
    3531                                 Vertex & v0 = triangles[i][0];
    3532                                 Vertex & v1 = triangles[i][1];
    3533                                 Vertex & v2 = triangles[i][2];
    3534                                 if ( &v0 && &v1 &&  &v2 ) // a good triangles;
    3535                                 {
    3536                                         triangles[i].det= det(v0,v1,v2);
    3537                                         if (triangles[i].det <=0 && Nberr++ <10)
    3538                                         {
    3539                                                 if(Nberr==1)
    3540                                                         if (strfrom)
    3541                                                                 cerr << "+++ Fatal Error " << strfrom << "(SetInCoor)  Error :  area of Triangle < 0 " << endl;
    3542                                                         else
    3543                                                                 cerr << "+++  Fatal Error Triangle (in SetInCoor) area of Triangle < 0" << endl;
    3544                                                 cerr << " Triangle " << i << "  det  (I2) = " << triangles[i].det ;
    3545                                                 cerr << " (R2) " << Det(v1.r-v0.r,v2.r-v0.r);
    3546                                                 cerr << "; The 3  vertices " << endl;
    3547                                                 cerr << Number(v0) << " "  << Number(v1) << " "
    3548                                                         << Number(v2) << " : " ;
    3549                                                 cerr << v0.r << v1.r << v2.r << " ; ";
    3550                                                 cerr << v0.i << v1.i << v2.i << endl;
    3551                                         }
    3552                                 }
    3553                                 else
    3554                                         triangles[i].det= -1; // Null triangle;
    3555                         }
    3556                         if (Nberr) MeshError(899,this);
    3557 
    3558                 }
    3559 
    3560                 void Triangles::FillHoleInMesh() {
    3561 
    3562                         Triangles* OldCurrentTh =CurrentTh;
    3563                         CurrentTh=this;
    3564 
    3565                         int verbosity=0;
    3566 
    3567                         // generation of the integer coordinate
    3568                           {
    3569 
    3570                                 // find extrema coordinates of vertices pmin,pmax
    3571                                 Int4 i;
    3572                                 if(verbosity>2) printf("      Filling holes in mesh of %i vertices\n",nbv);
    3573 
    3574                                 //initialize ordre
    3575                                 assert(ordre);
    3576                                 for (i=0;i<nbv;i++) ordre[i]=0;
    3577 
    3578                                 NbSubDomains =0;
    3579 
    3580                                 /* generation of the adjacence of the triangles*/
    3581 
    3582                                 SetOfEdges4* edge4= new SetOfEdges4(nbt*3,nbv);
    3583 
    3584                                 //initialize st
    3585                                 Int4* st = new Int4[nbt*3];
    3586                                 for (i=0;i<nbt*3;i++) st[i]=-1;
    3587 
    3588                                 //check number of edges
    3589                                 Int4 kk =0;
    3590                                 for (i=0;i<nbe;i++){
    3591                                         kk=kk+(i == edge4->addtrie(Number(edges[i][0]),Number(edges[i][1])));
    3592                                 }
    3593                                 if (kk != nbe) {
    3594                                         throw ErrorException(__FUNCT__,exprintf("Some Double edge in the mesh, the number is %i",kk-nbe));
    3595                                 }
    3596 
    3597                                 //
    3598                                 for (i=0;i<nbt;i++){
    3599                                         for (int j=0;j<3;j++) {
    3600                                                 Int4 k =edge4->addtrie(Number(triangles[i][VerticesOfTriangularEdge[j][0]]),
    3601                                                                         Number(triangles[i][VerticesOfTriangularEdge[j][1]]));
    3602                                                 Int4 invisible = triangles[i].Hidden(j);
    3603                                                 if(st[k]==-1){
    3604                                                         st[k]=3*i+j;
    3605                                                 }
    3606                                                 else if(st[k]>=0) {
    3607                                                         assert( ! triangles[i].TriangleAdj(j) && !triangles[st[k] / 3].TriangleAdj((int) (st[k]%3)));
    3608 
    3609                                                         triangles[i].SetAdj2(j,triangles + st[k] / 3,(int) (st[k]%3));
    3610                                                         if (invisible)  triangles[i].SetHidden(j);
    3611                                                         if (k<nbe) {
    3612                                                                 triangles[i].SetLocked(j);
    3613                                                         }
    3614                                                         st[k]=-2-st[k];
    3615                                                 }
    3616                                                 else {
    3617                                                         throw ErrorException(__FUNCT__,exprintf("The edge (%i , %i) belongs to more than 2 triangles",
    3618                                                                                         Number(triangles[i][VerticesOfTriangularEdge[j][0]]),Number(triangles[i][VerticesOfTriangularEdge[j][1]])));
    3619                                                 }
    3620                                         }
    3621                                 }
    3622                                 if(verbosity>5) {
    3623                                         printf("         info on Mesh %s:\n",name);
    3624                                         printf("            - number of vertices    = %i \n",nbv);
    3625                                         printf("            - number of triangles   = %i \n",nbt);
    3626                                         printf("            - number of given edges = %i \n",nbe);
    3627                                         printf("            - number of all edges   = %i \n"  ,edge4->nb());
    3628                                         printf("            - Euler number 1 - nb of holes = %i \n"  ,nbt-edge4->nb()+nbv);
    3629                                 }
    3630 
    3631                                 // check the consistant of edge[].adj and the geometrical required  vertex
    3632                                 Int4 k=0;
    3633                                 for (i=0;i<edge4->nb();i++){
    3634                                         if (st[i] >=0){ // edge alone
    3635                                                 if (i < nbe) {
    3636                                                         Int4 i0=edge4->i(i);
    3637                                                         ordre[i0] = vertices+i0;
    3638                                                         Int4 i1=edge4->j(i);
    3639                                                         ordre[i1] = vertices+i1;
    3640                                                 }
    3641                                                 else {
    3642                                                         k=k+1;
    3643                                                         if (k <20) {
    3644                                                                 throw ErrorException(__FUNCT__,exprintf("Lost boundary edges %i : %i %i",i,edge4->i(i),edge4->j(i)));
    3645                                                         }
    3646                                                 }
    3647                                         }
    3648                                 }
    3649                                 if(k != 0) {
    3650                                         throw ErrorException(__FUNCT__,exprintf("%i boundary edges  are not defined as edges",k));
    3651                                 }
    3652 
    3653                                 /* mesh generation with boundary points*/
    3654                                 Int4 nbvb = 0;
    3655                                 for (i=0;i<nbv;i++){
    3656                                         vertices[i].t=0;
    3657                                         vertices[i].vint=0;
    3658                                         if (ordre[i]){
    3659                                                 ordre[nbvb++] = ordre[i];
    3660                                         }
    3661                                 }
    3662 
    3663                                 Triangle* savetriangles= triangles;
    3664                                 Int4 savenbt=nbt;
    3665                                 Int4 savenbtx=nbtx;
    3666                                 SubDomain * savesubdomains = subdomains;
    3667                                 subdomains = 0;
    3668 
    3669                                 Int4  Nbtriafillhole = 2*nbvb;
    3670                                 Triangle* triafillhole =new Triangle[Nbtriafillhole];
    3671                                 triangles =  triafillhole;
    3672 
    3673                                 nbt=2;
    3674                                 nbtx= Nbtriafillhole;
    3675 
    3676                                 for (i=2 ; det( ordre[0]->i, ordre[1]->i, ordre[i]->i ) == 0;)
    3677                                  if  ( ++i >= nbvb) {
    3678                                          cerr << "FillHoleInMesh: All the vertices are aline " << nbvb << endl;
    3679                                          MeshError(998,this); }
    3680                                          Exchange( ordre[2], ordre[i]);
    3681 
    3682                                          Vertex *  v0=ordre[0], *v1=ordre[1];
    3683 
    3684 
    3685                                          triangles[0](0) = 0; // sommet pour infini
    3686                                          triangles[0](1) = v0;
    3687                                          triangles[0](2) = v1;
    3688 
    3689                                          triangles[1](0) = 0;// sommet pour infini
    3690                                          triangles[1](2) = v0;
    3691                                          triangles[1](1) = v1;
    3692                                          const int e0 = OppositeEdge[0];
    3693                                          const int e1 = NextEdge[e0];
    3694                                          const int e2 = PreviousEdge[e0];
    3695                                          triangles[0].SetAdj2(e0, &triangles[1] ,e0);
    3696                                          triangles[0].SetAdj2(e1, &triangles[1] ,e2);
    3697                                          triangles[0].SetAdj2(e2, &triangles[1] ,e1);
    3698 
    3699                                          triangles[0].det = -1;  // faux triangles
    3700                                          triangles[1].det = -1;  // faux triangles
    3701 
    3702                                          triangles[0].SetTriangleContainingTheVertex();
    3703                                          triangles[1].SetTriangleContainingTheVertex();
    3704 
    3705                                          triangles[0].link=&triangles[1];
    3706                                          triangles[1].link=&triangles[0];
    3707 
    3708                                          if (!quadtree )
    3709                                           delete  quadtree; // ->ReInitialise();
    3710 
    3711                                          quadtree = new QuadTree(this,0);
    3712                                          quadtree->Add(*v0);
    3713                                          quadtree->Add(*v1);
    3714 
    3715                                          // We add the vertices one by one
    3716                                          Int4 NbSwap=0;
    3717                                          for (Int4 icount=2; icount<nbvb; icount++) {
    3718                                                  Vertex *vi  = ordre[icount];
    3719                                                  //       cout << " Add vertex " <<  Number(vi) << endl;
    3720                                                  Icoor2 dete[3];
    3721                                                  Triangle *tcvi = FindTriangleContening(vi->i,dete);
    3722                                                  quadtree->Add(*vi);
    3723                                                  Add(*vi,tcvi,dete);
    3724                                                  NbSwap += vi->Optim(1,1);
    3725                                          }
    3726 
    3727                                          // inforce the boundary
    3728                                          TriangleAdjacent ta(0,0);
    3729                                          Int4 nbloss = 0,knbe=0;
    3730                                          for ( i = 0; i < nbe; i++){
    3731                                                  if (st[i] >=0){  // edge alone => on border ...  FH oct 2009
    3732                                                          Vertex & a=edges[i][0], & b =    edges[i][1];
    3733                                                          if (a.t && b.t) // le bug est la si maillage avec des bod non raffine 1.
    3734                                                                 {
    3735                                                                  knbe++;
    3736                                                                  if (ForceEdge(a,b,ta)<0)
    3737                                                                   nbloss++;
    3738                                                                 }
    3739                                                  }
    3740                                          }
    3741                                          if(nbloss) {
    3742                                                  cerr << " we loss some  " << nbloss << " "  << " edges other " << knbe << endl;
    3743                                                  MeshError(1100,this);
    3744                                          }
    3745 
    3746                                          FindSubDomain(1);
    3747                                          // remove all the hole
    3748                                          // remove all the good sub domain
    3749                                          Int4 krm =0;
    3750                                          for (i=0;i<nbt;i++){
    3751                                                  if (triangles[i].link){ // remove triangles
    3752                                                          krm++;
    3753                                                          for (int j=0;j<3;j++)
    3754                                                                 {
    3755                                                                  TriangleAdjacent ta =  triangles[i].Adj(j);
    3756                                                                  Triangle & tta = * (Triangle *) ta;
    3757                                                                  if(! tta.link) // edge between remove and not remove
    3758                                                                         { // change the link of ta;
    3759                                                                          int ja = ta;
    3760                                                                          Vertex *v0= ta.EdgeVertex(0);
    3761                                                                          Vertex *v1= ta.EdgeVertex(1);
    3762                                                                          Int4 k =edge4->addtrie(v0?Number(v0):nbv,v1? Number(v1):nbv);
    3763                                                                          assert(st[k] >=0);
    3764                                                                          tta.SetAdj2(ja,savetriangles + st[k] / 3,(int) (st[k]%3));
    3765                                                                          ta.SetLock();
    3766                                                                          st[k]=-2-st[k];
    3767                                                                         }
    3768                                                                 }
    3769                                                  }
    3770                                          }
    3771                                                  Int4 NbTfillHoll =0;
    3772                                                  for (i=0;i<nbt;i++){
    3773                                                          if (triangles[i].link) {
    3774                                                                  triangles[i]=Triangle((Vertex *) NULL,(Vertex *) NULL,(Vertex *) NULL);
    3775                                                                  triangles[i].color=-1;
    3776                                                          }
    3777                                                          else
    3778                                                                 {
    3779                                                                  triangles[i].color= savenbt+ NbTfillHoll++;
    3780                                                                 }
    3781                                                  }
    3782                                                  // cout <<      savenbt+NbTfillHoll << " " <<  savenbtx  << endl;
    3783                                                  assert(savenbt+NbTfillHoll <= savenbtx );
    3784                                                  // copy of the outside triangles in saveTriangles
    3785                                                  for (i=0;i<nbt;i++){
    3786                                                          if(triangles[i].color>=0) {
    3787                                                                  savetriangles[savenbt]=triangles[i];
    3788                                                                  savetriangles[savenbt].link=0;
    3789                                                                  savenbt++;
    3790                                                          }
    3791                                                  }
    3792                                                  // gestion of the adj
    3793                                                  k =0;
    3794                                                  Triangle * tmax = triangles + nbt;
    3795                                                  for (i=0;i<savenbt;i++) 
    3796                                                         {
    3797                                                          Triangle & ti = savetriangles[i];
    3798                                                          for (int j=0;j<3;j++)
    3799                                                                 {
    3800                                                                  Triangle * ta = ti.TriangleAdj(j);
    3801                                                                  int aa = ti.NuEdgeTriangleAdj(j);
    3802                                                                  int lck = ti.Locked(j);
    3803                                                                  if (!ta) k++; // bug
    3804                                                                  else if ( ta >= triangles && ta < tmax)
    3805                                                                         {
    3806                                                                          ta= savetriangles + ta->color;
    3807                                                                          ti.SetAdj2(j,ta,aa);
    3808                                                                          if(lck) ti.SetLocked(j);
    3809                                                                         }
    3810                                                                 }
    3811                                                         }
    3812                                                  //      OutSidesTriangles = triangles;
    3813                                                  //     Int4 NbOutSidesTriangles = nbt;
    3814 
    3815                                                  // restore triangles;
    3816                                                  nbt=savenbt;
    3817                                                  nbtx=savenbtx;
    3818                                                  delete [] triangles;
    3819                                                  delete [] subdomains;
    3820                                                  triangles = savetriangles;
    3821                                                  subdomains = savesubdomains;
    3822                                                  //      cout <<  triangles << " <> " << OutSidesTriangles << endl;
    3823                                                  /*      k=0;
    3824                                                                  for (i=0;i<nbt;i++)
    3825                                                                  for (int j=0;j<3;j++)
    3826                                                                  if (!triangles[i].TriangleAdj(j))
    3827                                                                  k++;
    3828                                                                  */
    3829                                                  if (k) {
    3830                                                          cerr << "Error Nb of triangles edge alone = " << k << endl;
    3831                                                          MeshError(9997,this);
    3832                                                  }
    3833                                                  FindSubDomain();
    3834                                                  // cout << " NbTOld = " << NbTold << " ==  " << nbt - NbOutT << " " << nbt << endl;
    3835 
    3836                                                  delete edge4;
    3837                                                  delete [] st;
    3838                                                  for (i=0;i<nbv;i++)
    3839                                                   quadtree->Add(vertices[i]);
    3840 
    3841                                                  SetVertexFieldOn();
    3842 
    3843                                                  for (i=0;i<nbe;i++)
    3844                                                   if(edges[i].on)
    3845                                                         for(int j=0;j<2;j++)
    3846                                                          if (!edges[i].adj[j])
    3847                                                           if(!edges[i][j].on->IsRequiredVertex()) {
    3848                                                                   cerr << " Erreur adj et sommet requis edges [" << i <<  "][ " << j << "]= "
    3849                                                                          <<  Number(edges[i][j]) << " : "  << " on = " << Gh.Number(edges[i].on) ;
    3850                                                                   if (edges[i][j].on->OnGeomVertex())
    3851                                                                         cerr << " vertex " << Gh.Number(edges[i][j].on->gv);
    3852                                                                   else if (edges[i][j].on->OnGeomEdge())
    3853                                                                         cerr << "Edges " << Gh.Number(edges[i][j].on->ge);
    3854                                                                   else
    3855                                                                         cerr << " = " << edges[i][j].on ;
    3856                                                                   cerr << endl;
    3857                                                           }
    3858                           }
    3859                         CurrentTh=OldCurrentTh;
    3860                 }
    3861 
    3862                 Triangles::Triangles(Triangles & Th,Geometry * pGh,Triangles * pBth,Int4 nbvxx) // COPY OPERATOR
    3863                         : Gh(*(pGh?pGh:&Th.Gh)), BTh(*(pBth?pBth:this))
    3864                         {
    3865                                 Gh.NbRef++;
    3866                                 nbvxx = Max(nbvxx,Th.nbv);
    3867                                 Int4 i;
    3868                                 // do all the allocation to be sure all the pointer existe
    3869 
    3870                                 char * cname = 0;
    3871                                 if (Th.name)
    3872                                 {
    3873                                         cname = new char[strlen(Th.name)+1];
    3874                                         strcpy(cname,Th.name);
    3875                                 }
    3876                                 PreInit(nbvxx,cname);// to make the allocation
    3877                                 // copy of triangles
    3878                                 nt=Th.nt;
    3879                                 nbv = Th.nbv;
    3880                                 nbt = Th.nbt;
    3881                                 nbiv = Th.nbiv;
    3882                                 nbe = Th.nbe;
    3883                                 NbSubDomains = Th.NbSubDomains;
    3884                                 NbOutT = Th.NbOutT;
    3885                                 NbOfQuad =  Th.NbOfQuad ;
    3886                                 NbOfSwapTriangle =0;
    3887                                 NbVerticesOnGeomVertex = Th.NbVerticesOnGeomVertex;
    3888                                 if(NbVerticesOnGeomVertex)
    3889                                         VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];
    3890                                 NbVerticesOnGeomEdge = Th.NbVerticesOnGeomEdge;
    3891                                 if (NbVerticesOnGeomEdge)
    3892                                         VerticesOnGeomEdge = new VertexOnGeom[NbVerticesOnGeomEdge] ;
    3893                                 if (& BTh == & Th.BTh) // same back ground
    3894                                 {
    3895                                         BTh.NbRef++;
    3896                                         NbVertexOnBThVertex = Th.NbVertexOnBThVertex;
    3897                                         if(NbVertexOnBThVertex)
    3898                                                 VertexOnBThVertex = new VertexOnVertex[NbVertexOnBThVertex];
    3899                                         NbVertexOnBThEdge = Th.NbVertexOnBThEdge;
    3900                                         if(NbVertexOnBThEdge)
    3901                                                 VertexOnBThEdge = new VertexOnEdge[NbVertexOnBThEdge];
    3902                                 }
    3903                                 else
    3904                                 { // no add on back ground mesh
    3905                                         BTh.NbRef++;
    3906                                         NbVertexOnBThVertex=0;
    3907                                         VertexOnBThVertex=0;
    3908                                         NbVertexOnBThEdge=0;
    3909                                         VertexOnBThEdge=0;
    3910                                         //       assert (& BTh == this); // --- a voir
    3911 
    3912                                 }
    3913 
    3914 
    3915                                 if(nbe)
    3916                                         edges = new Edge[nbe];
    3917                                 if(NbSubDomains)
    3918                                         subdomains = new SubDomain[NbSubDomains];
    3919                                 pmin = Th.pmin;
    3920                                 pmax = Th.pmax;
    3921                                 coefIcoor = Th.coefIcoor;
    3922                                 for(i=0;i<nbt;i++)
    3923                                         triangles[i].Set(Th.triangles[i],Th,*this);
    3924                                 for(i=0;i<nbe;i++)
    3925                                         edges[i].Set(Th,i,*this);
    3926                                 for(i=0;i<nbv;i++)
    3927                                         vertices[i].Set(Th.vertices[i],Th,*this);
    3928                                 for(i=0;i<NbSubDomains;i++) 
    3929                                         subdomains[i].Set(Th,i,*this);
    3930                                 for (i=0;i<NbVerticesOnGeomVertex;i++)
    3931                                         VerticesOnGeomVertex[i].Set(Th.VerticesOnGeomVertex[i],Th,*this);
    3932                                 for (i=0;i<NbVerticesOnGeomEdge;i++)
    3933                                         VerticesOnGeomEdge[i].Set(Th.VerticesOnGeomEdge[i],Th,*this);
    3934                                 quadtree=0;
    3935 
    3936 
    3937                                 //  assert(!OutSidesTriangles);
    3938                         }
    3939 
    3940 Int4  Triangle::Optim(Int2 i,int koption)
    3941 {
    3942         // turne around in positif sens
    3943         Int4 NbSwap =0;
    3944         Triangle  *t = this;
    3945         int k=0,j =OppositeEdge[i];
    3946         int jp = PreviousEdge[j];
    3947         // initialise   tp, jp the previous triangle & edge
    3948         Triangle *tp= at[jp];
    3949         jp = aa[jp]&3;
    3950         do {
    3951                 //    cout << *t << " " <<  j  << "\n\t try swap " ;
    3952                 while (t->swap(j,koption))
    3953                 {
    3954                         NbSwap++;
    3955                         assert(k++<20000);
    3956                         t=  tp->at[jp];      // set unchange t qnd j for previous triangles
    3957                         j=  NextEdge[tp->aa[jp]&3];
    3958                         //   cout << "\n\t s  " <<  *t << " " << j << endl;
    3959                 }
    3960                 // end on this  Triangle
    3961                 tp = t;
    3962                 jp = NextEdge[j];
    3963 
    3964                 t=  tp->at[jp];      // set unchange t qnd j for previous triangles
    3965                 j=  NextEdge[tp->aa[jp]&3];
    3966 
    3967         } while( t != this);
    3968         return NbSwap;
    3969 }
    3970 
    3971 void Triangles::SmoothingVertex(int nbiter,Real8 omega )
    3972 {
    3973         long int verbosity=0;
    3974         //  if quatree exist remove it end reconstruct
    3975         if (quadtree) delete quadtree;
    3976         quadtree=0;
    3977         ReMakeTriangleContainingTheVertex();
    3978         Triangle vide; // a triangle to mark the boundary vertex
    3979         Triangle   ** tstart= new Triangle* [nbv];
    3980         Int4 i,j,k;
    3981         //   attention si Background == Triangle alors on ne peut pas utiliser la rechech rapide
    3982         if ( this == & BTh)
    3983                 for ( i=0;i<nbv;i++)
    3984                         tstart[i]=vertices[i].t;     
    3985         else
    3986                 for ( i=0;i<nbv;i++)
    3987                         tstart[i]=0;
    3988         for ( j=0;j<NbVerticesOnGeomVertex;j++ )
    3989                 tstart[ Number(VerticesOnGeomVertex[j].mv)]=&vide;
    3990         for ( k=0;k<NbVerticesOnGeomEdge;k++ )
    3991                 tstart[ Number(VerticesOnGeomEdge[k].mv)]=&vide;
    3992         if(verbosity>2)
    3993                 cout << "  -- SmoothingVertex: nb Iteration = " << nbiter << " Omega = " << omega << endl;
    3994         for (k=0;k<nbiter;k++)
    3995         {
    3996                 Int4 i,NbSwap =0;
    3997                 Real8 delta =0;
    3998                 for ( i=0;i<nbv;i++)
    3999                         if (tstart[i] != &vide) // not a boundary vertex
    4000                                 delta=Max(delta,vertices[i].Smoothing(*this,BTh,tstart[i],omega));
    4001                 if (!NbOfQuad)
    4002                         for ( i=0;i<nbv;i++)
    4003                                 if (tstart[i] != &vide) // not a boundary vertex
    4004                                         NbSwap += vertices[i].Optim(1);
    4005                 if (verbosity>3)
    4006                         cout << "    Move max = " <<  sqrt(delta) << " iteration = "
    4007                                 << k << " Nb of Swap = " << NbSwap << endl;
    4008         }
    4009 
    4010         delete [] tstart;
    4011         if (quadtree) quadtree= new QuadTree(this);
    4012 }
    4013 void Triangles::MakeQuadTree()
    4014 
    4015         long int verbosity=0;
    4016         if(verbosity>8)
    4017                 cout << "      MakeQuadTree" << endl;
    4018         if (  !quadtree )  quadtree = new QuadTree(this);
    4019 
    4020 }
    4021 void  Triangles::ShowRegulaty() const// Add FH avril 2007
    4022 {
    4023         const  Real8  sqrt32=sqrt(3.)*0.5;
    4024         const Real8  aireKh=sqrt32*0.5;
    4025         D2  Beq(1,0),Heq(0.5,sqrt32);
    4026         D2xD2 Br(D2xD2(Beq,Heq).t());
    4027         D2xD2 B1r(Br.inv());
    4028         /*   D2xD2 BB = Br.t()*Br;
    4029                  cout << " BB = " << BB << " " << Br*B1r <<  endl;
    4030                  MetricAnIso MMM(BB.x.x,BB.x.y,BB.y.y);
    4031                  MatVVP2x2 VMM(MMM);
    4032                  cout << " " << VMM.lambda1 << " " << VMM.lambda2 <<  endl;
    4033                  */
    4034         double gammamn=1e100,hmin=1e100;
    4035         double gammamx=0,hmax=0;
    4036         double beta=1e100;
    4037         double beta0=0;
    4038         double  alpha2=0;
    4039         double area=0,Marea=0;
    4040         // Real8 cf= Real8(coefIcoor);
    4041         // Real8 cf2= 6.*cf*cf;
    4042         int nt=0;
    4043         for (int it=0;it<nbt;it++)
    4044                 if ( triangles[it].link)
    4045                 {
    4046                         nt++;
    4047                         Triangle &K=triangles[it];
    4048                         Real8  area3= Area2((R2) K[0],(R2) K[1],(R2) K[2])/6.;
    4049                         area+= area3;
    4050                         D2xD2 B_Kt(K[0],K[1],K[2]);
    4051                         D2xD2 B_K(B_Kt.t());
    4052                         D2xD2 B1K = Br*B_K.inv();
    4053                         D2xD2 BK =  B_K*B1r;
    4054                         D2xD2 B1B1 = B1K.t()*B1K;
    4055                         MetricAnIso MK(B1B1.x.x,B1B1.x.y,B1B1.y.y);
    4056                         MatVVP2x2 VMK(MK);
    4057                         alpha2 = Max(alpha2,Max(VMK.lambda1/VMK.lambda2,VMK.lambda2/VMK.lambda1));
    4058                         // cout << B_K << " * " << B1r << " == " << BK << " " << B_K*B_K.inv() << endl;
    4059                         Real8 betaK=0;
    4060 
    4061                         for (int j=0;j<3;j++)
    4062                         {
    4063                                 Real8 he= Norme2(R2(K[j],K[(j+1)%3]));
    4064                                 hmin=Min(hmin,he);
    4065                                 hmax=Max(hmax,he);
    4066                                 Vertex & v=K[j];
    4067                                 D2xD2 M((MetricAnIso)v);
    4068                                 betaK += sqrt(M.det());
    4069 
    4070                                 D2xD2 BMB = BK.t()*M*BK;
    4071                                 MetricAnIso M1(BMB.x.x,BMB.x.y,BMB.y.y);
    4072                                 MatVVP2x2 VM1(M1);
    4073                                 //cout << B_K <<" " <<  M << " " <<  he << " " << BMB << " " << VM1.lambda1 << " " << VM1.lambda2<<   endl;
    4074                                 gammamn=Min3(gammamn,VM1.lambda1,VM1.lambda2);
    4075                                 gammamx=Max3(gammamx,VM1.lambda1,VM1.lambda2);         
    4076                         }
    4077                         betaK *= area3;//  1/2 (somme sqrt(det))* area(K)
    4078                         Marea+= betaK;
    4079                         // cout << betaK << " " << area3 << " " << beta << " " << beta0 << " " << area3*3*3*3 <<endl;
    4080                         beta=min(beta,betaK);
    4081                         beta0=max(beta0,betaK);
    4082                 }   
    4083         area*=3;
    4084         gammamn=sqrt(gammamn);
    4085         gammamx=sqrt(gammamx);   
    4086         cout << "  -- adaptmesh Regulary:  Nb triangles " << nt <<  " , h  min " << hmin  << " , h max " << hmax << endl; 
    4087         cout << "     area =  " << area << " , M area = " << Marea << " , M area/( |Khat| nt) " << Marea/(aireKh*nt) << endl;
    4088         cout << "     infiny-regulaty:  min " << gammamn << "  max " << gammamx << endl; 
    4089         cout << "     anisomax  "<< sqrt(alpha2) << ", beta max = " << 1./sqrt(beta/aireKh)
    4090                 << " min  "<<  1./sqrt(beta0/aireKh)  << endl;
    4091 }
    4092 void  Triangles::ShowHistogram() const
    4093 {
    4094 
    4095         const Int4 kmax=10;
    4096         const Real8 llmin = 0.5,llmax=2;
    4097         const Real8 lmin=log(llmin),lmax=log(llmax),delta= kmax/(lmax-lmin);
    4098         Int4 histo[kmax+1];
    4099         Int4 i,it,k, nbedges =0;
    4100         for (i=0;i<=kmax;i++) histo[i]=0;
    4101         for (it=0;it<nbt;it++)
    4102                 if ( triangles[it].link)
    4103                 {
    4104 
    4105                         for (int j=0;j<3;j++)
    4106                         {
    4107                                 Triangle *ta = triangles[it].TriangleAdj(j);
    4108                                 if ( !ta || !ta->link || Number(ta) >= it)
    4109                                 {
    4110                                         Vertex & vP = triangles[it][VerticesOfTriangularEdge[j][0]];
    4111                                         Vertex & vQ = triangles[it][VerticesOfTriangularEdge[j][1]];
    4112                                         if ( !& vP || !&vQ) continue;
    4113                                         R2 PQ = vQ.r - vP.r;
    4114                                         Real8 l = log(LengthInterpole(vP,vQ,PQ));
    4115                                         nbedges++;
    4116                                         k = (int) ((l - lmin)*delta);
    4117                                         k = Min(Max(k,0L),kmax);
    4118                                         histo[k]++;
    4119                                 }
    4120                         }
    4121                 } 
    4122         cout << "  -- Histogram of the unit mesh,  nb of edges" << nbedges << endl <<endl;
    4123 
    4124         cout << "        length of edge in   | % of edge  | Nb of edges " << endl;
    4125         cout << "        ------------------- | ---------- | ----------- " << endl;
    4126         for   (i=0;i<=kmax;i++)
    4127         {
    4128                 cout << "    " ;
    4129                 cout.width(10);
    4130                 if (i==0) cout  << " 0 " ;
    4131                 else cout  << exp(lmin+i/delta) ;
    4132                 cout.width(); cout << "," ;
    4133                 cout.width(10);
    4134                 if (i==kmax) cout << " +infty " ;
    4135                 else cout  << exp(lmin+(i+1)/delta) ;
    4136                 cout.width();cout << "   |   " ;
    4137 
    4138                 cout.precision(4);
    4139                 cout.width(6);
    4140                 cout <<  ((long)  ((10000.0 * histo[i])/ nbedges))/100.0 ;
    4141                 cout.width();
    4142                 cout.precision();
    4143                 cout <<  "   |   " << histo[i] <<endl;
    4144         }
    4145         cout << "        ------------------- | ---------- | ----------- " << endl <<endl;
    4146 
    4147 }
    4148 
    4149 int  Triangles::Crack()
    4150 {
    4151         assert(NbCrackedEdges ==0 || NbCrackedVertices >0);
    4152         for (int i=0;i<NbCrackedEdges;i++)
    4153                 CrackedEdges[i].Crack();
    4154         return NbCrackedEdges;
    4155 }
    4156 
    4157 int Triangles::UnCrack()
    4158 {
    4159         assert(NbCrackedEdges ==0 || NbCrackedVertices >0);
    4160         for (int i=0;i<NbCrackedEdges;i++)
    4161                 CrackedEdges[i].UnCrack();
    4162         return NbCrackedEdges;
    4163 }
    4164 
    4165 int Triangles::CrackMesh()
    4166 {
    4167         long int verbosity=0;
    4168         Triangles *CurrentThOld = CurrentTh;
    4169         //  computed the number of cracked edge
    4170         int i,k;
    4171         for (k=i=0;i<nbe;i++)
    4172                 if(edges[i].on->Cracked()) k++;
    4173         if( k==0) return 0;
    4174         CurrentTh = this;
    4175         cout << " Nb of Cracked Edges = " << k << endl;
    4176         NbCrackedEdges =k;
    4177         CrackedEdges = new  CrackedEdge[k];
    4178         //  new edge
    4179         Edge * e = new Edge[ nbe + k];
    4180 
    4181         // copy
    4182         for (i=0;i<nbe;i++)
    4183                 e[i] = edges[i];
    4184         delete edges;
    4185         edges = e;
    4186 
    4187         const int  nbe0  = nbe;
    4188         for (k=i=0;i<nbe0;i++) // on double les arete cracked
    4189                 if(edges[i].on->Cracked())
    4190                 {
    4191                         e[nbe] = e[i];
    4192                         //  return the edge
    4193                         e[nbe].v[0] =  e[i].v[1];
    4194                         e[nbe].v[1] =  e[i].v[0];
    4195                         e[nbe].on = e[i].on->link ; // fqux
    4196                         CrackedEdges[k++]=CrackedEdge(edges,i,nbe);
    4197                         nbe++;
    4198                 }
    4199         ReMakeTriangleContainingTheVertex() ;
    4200         // 
    4201         int nbcrakev  =0;
    4202         Vertex *vlast = vertices + nbv;
    4203         Vertex *vend = vertices + nbvx; // end of array
    4204         for (int iv=0;iv<nbv;iv++) // vertex
    4205         {
    4206                 Vertex & v= vertices[iv];
    4207                 Vertex * vv = & v; 
    4208                 int kk=0; // nb cracked
    4209                 int kc=0;
    4210                 int kkk =0; // nb triangle  with same number
    4211                 Triangle * tbegin = v.t;
    4212                 int i  = v.vint;       
    4213                 assert(tbegin && (i >= 0 ) && (i <3));
    4214                 // turn around the vertex v
    4215                 TriangleAdjacent ta(tbegin,EdgesVertexTriangle[i][0]);// previous edge
    4216                 int k=0;
    4217                 do {
    4218                         int kv = VerticesOfTriangularEdge[ta][1];
    4219                         k++;
    4220                         Triangle * tt (ta);
    4221                         if ( ta.Cracked() )
    4222                         {   
    4223                                 TriangleAdjacent tta=(ta.Adj());
    4224                                 assert(tta.Cracked());
    4225                                 if ( kk == 0) tbegin=ta,kkk=0;  //  begin by a cracked edge  => restart               
    4226                                 if (  kkk ) { kc =1;vv = vlast++;  kkk = 0; } // new vertex if use
    4227                                 kk++;// number of cracked edge view                 
    4228                         }
    4229                         if ( tt->link ) { // if good triangles store the value
    4230                                 int it = Number(tt);
    4231                                 assert(it < nt);
    4232                                 (*tt)(kv)= vv; //   Change the vertex of triangle
    4233                                 if(vv<vend) {*vv= v;vv->ReferenceNumber=iv;} // copy the vertex value + store the old vertex number in ref
    4234                                 //        tt->SetTriangleContainingTheVertex();
    4235                                 kkk++;
    4236                         } else if (kk) { // crack + boundary
    4237                                 if (  kkk ) { kc =1;vv = vlast++;  kkk = 0; } // new vertex if use
    4238                         }
    4239 
    4240                         ta = Next(ta).Adj();
    4241                 } while ( (tbegin != ta));
    4242                 assert(k);
    4243                 if (kc)  nbcrakev++;
    4244         }
    4245 
    4246         if ( nbcrakev )
    4247                 for (int iec =0;iec < NbCrackedEdges; iec ++)
    4248                         CrackedEdges[iec].Set();
    4249 
    4250         //  set the ref
    4251         cout << " set the ref " <<  endl ;
    4252         NbCrackedVertices =   nbcrakev;
    4253         // int nbvo = nbv;
    4254         nbv = vlast - vertices;
    4255         int nbnewv =  nbv - nbv; // nb of new vrtices
    4256         if (nbcrakev && verbosity > 1 )
    4257                 cout << " Nb of craked vertices = " << nbcrakev << " Nb of created vertices " <<   nbnewv<< endl;
    4258         // all the new vertices are on geometry
    4259         //  BOFBO--  A VOIR
    4260         if (nbnewv)
    4261         { //
    4262                 Int4 n = nbnewv+NbVerticesOnGeomVertex;
    4263                 Int4 i,j,k;
    4264                 VertexOnGeom * vog = new VertexOnGeom[n];
    4265                 for ( i =0; i<NbVerticesOnGeomVertex;i++)
    4266                         vog[i]=VerticesOnGeomVertex[i];
    4267                 delete [] VerticesOnGeomVertex;
    4268                 VerticesOnGeomVertex = vog;
    4269                 // loop on cracked edge
    4270                 Vertex * LastOld = vertices + nbv - nbnewv;
    4271                 for (int iec =0;iec < NbCrackedEdges; iec ++)
    4272                         for (k=0;k<2;k++)
    4273                         {
    4274                                 Edge & e = *( k ? CrackedEdges[iec].a.edge : CrackedEdges[iec].b.edge);
    4275                                 for (j=0;j<2;j++)
    4276                                 {
    4277                                         Vertex * v = e(j);
    4278                                         if ( v >=  LastOld)
    4279                                         { // a new vertex
    4280                                                 Int4 old = v->ReferenceNumber ; // the old same vertex
    4281                                                 Int4 i  = ( v - LastOld);
    4282                                                 //  if the old is on vertex => warning
    4283                                                 // else the old is on edge => ok
    4284                                                 vog[i] = vog[old];
    4285                                                 //                  vog[i].mv = v;
    4286                                                 //g[i].ge = ;
    4287                                                 //og[i].abcisse = ;
    4288                                         }
    4289 
    4290                                 }
    4291                         }
    4292 
    4293                 NbVerticesOnGeomVertex = n;
    4294         }
    4295         SetVertexFieldOn();
    4296 
    4297 
    4298         if (vlast >= vend)
    4299         { 
    4300                 cerr << " Not enougth vertices to crack the mesh we need " << nbv << " vertices " << endl;
    4301                 MeshError(555,this);
    4302         }
    4303         cout << "  NbCrackedVertices " <<  NbCrackedVertices << endl;
    4304         CurrentTh = CurrentThOld;
    4305         return  NbCrackedVertices;
    4306 }
    4307 
    4308         Triangles::Triangles(const Triangles & Tho,const int *flag ,const int *bb)
    4309 : Gh(*(new Geometry())), BTh(*this)
    4310 { // truncature
    4311         //
    4312 
    4313         char cname[] = "trunc";
    4314 
    4315         int i,k,itadj;
    4316         int kt=0;
    4317         int * kk    = new int [Tho.nbv];
    4318         Int4 * reft = new Int4[Tho.nbt];
    4319         Int4 nbInT =    Tho.ConsRefTriangle(reft);
    4320         Int4 * refv = new Int4[Tho.nbv];
    4321 
    4322         for (i=0;i<Tho.nbv;i++)
    4323                 kk[i]=-1;
    4324         for (i=0;i<Tho.nbv;i++)
    4325                 refv[i]=0;
    4326         int nbNewBedge =0;
    4327         //  int nbOldBedge =0; 
    4328         for (i=0;i<Tho.nbt;i++)
    4329                 if(  reft[i] >=0 && flag[i])
    4330                 {
    4331                         const Triangle & t = Tho.triangles[i];
    4332                         kt++;
    4333                         kk[Tho.Number(t[0])]=1;
    4334                         kk[Tho.Number(t[1])]=1;
    4335                         kk[Tho.Number(t[2])]=1;
    4336                         itadj=Tho.Number(t.TriangleAdj(0));
    4337                         if (  reft[itadj] >=0 && !flag[itadj])
    4338                         { nbNewBedge++;
    4339                                 refv[Tho.Number(t[VerticesOfTriangularEdge[0][0]])]=bb[i];
    4340                                 refv[Tho.Number(t[VerticesOfTriangularEdge[0][1]])]=bb[i];
    4341                         }
    4342                         itadj=Tho.Number(t.TriangleAdj(1));
    4343                         if (  reft[itadj] >=0 && !flag[itadj])
    4344                         { nbNewBedge++;
    4345                                 refv[Tho.Number(t[VerticesOfTriangularEdge[1][0]])]=bb[i];
    4346                                 refv[Tho.Number(t[VerticesOfTriangularEdge[1][1]])]=bb[i];}
    4347                                 itadj=Tho.Number(t.TriangleAdj(2));
    4348                                 if (  reft[itadj] >=0 && !flag[itadj])
    4349                                 { nbNewBedge++;
    4350                                         refv[Tho.Number(t[VerticesOfTriangularEdge[2][0]])]=bb[i];
    4351                                         refv[Tho.Number(t[VerticesOfTriangularEdge[2][1]])]=bb[i];}
    4352                 }
    4353         k=0;
    4354         for (i=0;i<Tho.nbv;i++)
    4355                 if (kk[i]>=0)
    4356                         kk[i]=k++;
    4357         cout << " number of vertices " << k << " remove = " << Tho.nbv - k << endl;
    4358         cout << " number of triangles " << kt << " remove = " << nbInT-kt << endl;
    4359         cout << " number of New boundary edge " << nbNewBedge << endl;
    4360         Int4 inbvx =k;
    4361         PreInit(inbvx,cname);
    4362         for (i=0;i<Tho.nbv;i++)
    4363                 if (kk[i]>=0)
    4364                 {
    4365                         vertices[nbv] = Tho.vertices[i];
    4366                         if (!vertices[nbv].ref())
    4367                                 vertices[nbv].ReferenceNumber = refv[i];
    4368                         nbv++;
    4369                 }
    4370         assert(inbvx == nbv);
    4371         for (i=0;i<Tho.nbt;i++)
    4372                 if(  reft[i] >=0 && flag[i])
    4373                 {
    4374                         const Triangle & t = Tho.triangles[i];
    4375                         int i0 = Tho.Number(t[0]);
    4376                         int i1 = Tho.Number(t[1]);
    4377                         int i2 = Tho.Number(t[2]);
    4378                         assert(i0>=0 && i1 >= 0 && i2  >= 0);
    4379                         assert(i0<Tho.nbv && i1 <Tho.nbv && i2  <Tho.nbv);
    4380                         // cout <<i<< " F" <<  flag[i] << " T " << nbt << "   = " <<  kk[i0] << " " << kk[i1] << " " << kk[i2] ;
    4381                         // cout << " OT  " <<  i0 << " "  << i1 << " " << i2  << " " << reft[i] << endl;
    4382                         triangles[nbt] = Triangle(this,kk[i0],kk[i1],kk[i2]);
    4383                         triangles[nbt].color = Tho.subdomains[reft[i]].ref;
    4384                         nbt++;           
    4385                 }
    4386         assert(kt==nbt);
    4387         if (nbt ==0 && nbv ==0) {
    4388                 cout << "Error all triangles was remove " << endl;
    4389                 MeshError(999,this);
    4390         }
    4391         delete [] kk;
    4392         delete [] reft;
    4393         delete [] refv;
    4394         double cutoffradian = 10.0/180.0*Pi;
    4395         ConsGeometry(cutoffradian);
    4396         Gh.AfterRead();
    4397         SetIntCoor();
    4398         FillHoleInMesh();
    4399 
    4400         assert(NbSubDomains);
    4401         assert(subdomains[0].head && subdomains[0].head->link);
    4402 
    4403 }
    4404 
    4405 Triangle * Triangles::FindTriangleContening(const I2 & B,Icoor2 dete[3], Triangle *tstart) const { // in: B
    4406         // out: t
    4407         // out : dete[3]
    4408         // t the triangle and s0,s1,s2 the 3 vertices of t
    4409         // in dete[3] = { det(B,s1,s2) , det(s0,B,s2), det(s0,s1,B)}
    4410         // with det(a,b,c ) = -1 if one of 3 vertices a,b,c is NULL
    4411         Triangle * t=0;
    4412         int j,jp,jn,jj;
    4413         if (tstart)
    4414                 t=tstart;
    4415         else
    4416         {
    4417                 assert(quadtree);
    4418                 Vertex *a = quadtree->NearestVertex(B.x,B.y) ;
    4419 
    4420                 if (! a || !a->t ) {
    4421                         if (a)
    4422                         {cerr << " Attention PB TriangleConteningTheVertex  vertex number=" << Number(a) << endl;
    4423                                 cerr  << "We forget a call to ReMakeTriangleContainingTheVertex" << endl;}
    4424                                 cerr << " Pb with " << B << toR2(B) << endl;
    4425                                 MeshError(7777);
    4426                 }
    4427                 assert(a>= vertices && a < vertices+nbv);
    4428                 //  int k=0;
    4429                 t = a->t;
    4430                 assert(t>= triangles && t < triangles+nbt);
    4431 
    4432         }
    4433         Icoor2  detop ;
    4434         int kkkk =0; // number of test triangle
    4435 
    4436         while ( t->det < 0)
    4437         { // the initial triangles is outside 
    4438                 int k0=(*t)(0) ?  ((  (*t)(1) ? ( (*t)(2) ? -1 : 2) : 1  )) : 0;
    4439                 assert(k0>=0); // k0 the NULL  vertex
    4440                 int k1=NextVertex[k0],k2=PreviousVertex[k0];
    4441                 dete[k0]=det(B,(*t)[k1],(*t)[k2]);
    4442                 dete[k1]=dete[k2]=-1;     
    4443                 if (dete[k0] > 0) // outside B
    4444                         return t;
    4445                 t = t->TriangleAdj(OppositeEdge[k0]);
    4446                 assert(kkkk++ < 2);
    4447         }
    4448 
    4449         jj=0;
    4450         detop = det(*(*t)(VerticesOfTriangularEdge[jj][0]),*(*t)(VerticesOfTriangularEdge[jj][1]),B);
    4451 
    4452         while(t->det  > 0 )
    4453         {
    4454                 assert( kkkk++ < 2000 );
    4455                 j= OppositeVertex[jj];
    4456                 dete[j] = detop;  //det(*b,*s1,*s2);
    4457                 jn = NextVertex[j];
    4458                 jp = PreviousVertex[j];
    4459                 dete[jp]= det(*(*t)(j),*(*t)(jn),B);
    4460                 dete[jn] = t->det-dete[j] -dete[jp];
    4461 
    4462                 // count the number k of  dete <0
    4463                 int k=0,ii[3];
    4464                 if (dete[0] < 0 ) ii[k++]=0;
    4465                 if (dete[1] < 0 ) ii[k++]=1;
    4466                 if (dete[2] < 0 ) ii[k++]=2;
    4467                 // 0 => ok
    4468                 // 1 => go in way 1
    4469                 // 2 => two way go in way 1 or 2 randomly
    4470 
    4471                 if (k==0)
    4472                         break;
    4473                 if (k == 2 && BinaryRand())
    4474                         Exchange(ii[0],ii[1]);
    4475                 assert ( k  < 3);
    4476                 TriangleAdjacent t1 = t->Adj(jj=ii[0]);
    4477                 if ((t1.det() < 0 ) && (k == 2))
    4478                         t1 = t->Adj(jj=ii[1]);
    4479                 t=t1;
    4480                 j=t1;// for optimisation we now the -det[OppositeVertex[j]];
    4481                 detop = -dete[OppositeVertex[jj]];
    4482                 jj = j;
    4483         }
    4484 
    4485         if (t->det<0) // outside triangle
    4486                 dete[0]=dete[1]=dete[2]=-1,dete[OppositeVertex[jj]]=detop;
    4487         //  NbOfTriangleSearchFind += kkkk; 
    4488         return t;
    4489 }
    44901164
    44911165double QuadQuality(const Vertex & a,const Vertex &b,const Vertex &c,const Vertex &d) {
  • issm/trunk/src/c/Bamgx/Triangles.cpp

    r2810 r2811  
    1414
    1515        static const  Direction NoDirOfSearch=Direction();
     16        long NbUnSwap =0;
    1617
    1718        /*Constructors/Destructors*/
     
    2627                FillHoleInMesh();
    2728        }
     29        /*}}}1*/
     30        /*FUNCTION Triangles::Triangles(const Triangles & Tho,const int *flag ,const int *bb){{{1*/
     31        Triangles::Triangles(const Triangles & Tho,const int *flag ,const int *bb)
     32          : Gh(*(new Geometry())), BTh(*this) {
     33
     34                  char cname[] = "trunc";
     35
     36                  int i,k,itadj;
     37                  int kt=0;
     38                  int * kk    = new int [Tho.nbv];
     39                  Int4 * reft = new Int4[Tho.nbt];
     40                  Int4 nbInT =    Tho.ConsRefTriangle(reft);
     41                  Int4 * refv = new Int4[Tho.nbv];
     42
     43                  for (i=0;i<Tho.nbv;i++)
     44                        kk[i]=-1;
     45                  for (i=0;i<Tho.nbv;i++)
     46                        refv[i]=0;
     47                  int nbNewBedge =0;
     48                  //  int nbOldBedge =0; 
     49                  for (i=0;i<Tho.nbt;i++)
     50                        if(  reft[i] >=0 && flag[i])
     51                          {
     52                                const Triangle & t = Tho.triangles[i];
     53                                kt++;
     54                                kk[Tho.Number(t[0])]=1;
     55                                kk[Tho.Number(t[1])]=1;
     56                                kk[Tho.Number(t[2])]=1;
     57                                itadj=Tho.Number(t.TriangleAdj(0));
     58                                if (  reft[itadj] >=0 && !flag[itadj])
     59                                  { nbNewBedge++;
     60                                        refv[Tho.Number(t[VerticesOfTriangularEdge[0][0]])]=bb[i];
     61                                        refv[Tho.Number(t[VerticesOfTriangularEdge[0][1]])]=bb[i];
     62                                  }
     63                                itadj=Tho.Number(t.TriangleAdj(1));
     64                                if (  reft[itadj] >=0 && !flag[itadj])
     65                                  { nbNewBedge++;
     66                                        refv[Tho.Number(t[VerticesOfTriangularEdge[1][0]])]=bb[i];
     67                                        refv[Tho.Number(t[VerticesOfTriangularEdge[1][1]])]=bb[i];}
     68                                        itadj=Tho.Number(t.TriangleAdj(2));
     69                                        if (  reft[itadj] >=0 && !flag[itadj])
     70                                          { nbNewBedge++;
     71                                                refv[Tho.Number(t[VerticesOfTriangularEdge[2][0]])]=bb[i];
     72                                                refv[Tho.Number(t[VerticesOfTriangularEdge[2][1]])]=bb[i];}
     73                          }
     74                  k=0;
     75                  for (i=0;i<Tho.nbv;i++)
     76                        if (kk[i]>=0)
     77                         kk[i]=k++;
     78                  cout << " number of vertices " << k << " remove = " << Tho.nbv - k << endl;
     79                  cout << " number of triangles " << kt << " remove = " << nbInT-kt << endl;
     80                  cout << " number of New boundary edge " << nbNewBedge << endl;
     81                  Int4 inbvx =k;
     82                  PreInit(inbvx,cname);
     83                  for (i=0;i<Tho.nbv;i++)
     84                        if (kk[i]>=0)
     85                          {
     86                                vertices[nbv] = Tho.vertices[i];
     87                                if (!vertices[nbv].ref())
     88                                 vertices[nbv].ReferenceNumber = refv[i];
     89                                nbv++;
     90                          }
     91                  assert(inbvx == nbv);
     92                  for (i=0;i<Tho.nbt;i++)
     93                        if(  reft[i] >=0 && flag[i])
     94                          {
     95                                const Triangle & t = Tho.triangles[i];
     96                                int i0 = Tho.Number(t[0]);
     97                                int i1 = Tho.Number(t[1]);
     98                                int i2 = Tho.Number(t[2]);
     99                                assert(i0>=0 && i1 >= 0 && i2  >= 0);
     100                                assert(i0<Tho.nbv && i1 <Tho.nbv && i2  <Tho.nbv);
     101                                // cout <<i<< " F" <<  flag[i] << " T " << nbt << "   = " <<  kk[i0] << " " << kk[i1] << " " << kk[i2] ;
     102                                // cout << " OT  " <<  i0 << " "  << i1 << " " << i2  << " " << reft[i] << endl;
     103                                triangles[nbt] = Triangle(this,kk[i0],kk[i1],kk[i2]);
     104                                triangles[nbt].color = Tho.subdomains[reft[i]].ref;
     105                                nbt++;           
     106                          }
     107                  assert(kt==nbt);
     108                  if (nbt ==0 && nbv ==0) {
     109                          cout << "Error all triangles was remove " << endl;
     110                          MeshError(999,this);
     111                  }
     112                  delete [] kk;
     113                  delete [] reft;
     114                  delete [] refv;
     115                  double cutoffradian = 10.0/180.0*Pi;
     116                  ConsGeometry(cutoffradian);
     117                  Gh.AfterRead();
     118                  SetIntCoor();
     119                  FillHoleInMesh();
     120
     121                  assert(NbSubDomains);
     122                  assert(subdomains[0].head && subdomains[0].head->link);
     123
     124          }
     125        /*}}}1*/
     126        /*FUNCTION Triangles::~Triangles(){{{1*/
     127        Triangles::~Triangles() {
     128                long int verbosity=2;
     129                //assert(NbRef<=0);
     130                if (CurrentTh == this) CurrentTh=0;
     131                //if(vertices)  delete [] vertices; //TEST  crash if not commented
     132                if(edges)     delete [] edges;
     133                if(triangles) delete [] triangles;
     134                if(quadtree)  delete  quadtree;
     135                //if(ordre)     delete [] ordre; //TEST  crash if not commented
     136                if( subdomains) delete []  subdomains;
     137                if (VerticesOnGeomEdge) delete [] VerticesOnGeomEdge;
     138                if (VerticesOnGeomVertex) delete [] VerticesOnGeomVertex;
     139                //if (name) delete [] name; //TEST crash if not commented
     140                if (identity) delete [] identity;
     141                if (VertexOnBThVertex) delete [] VertexOnBThVertex;
     142                if (VertexOnBThEdge) delete [] VertexOnBThEdge;
     143
     144                if (&Gh) {
     145                        if (Gh.NbRef>0) Gh.NbRef--;
     146                        else if (Gh.NbRef==0) delete &Gh;
     147                }
     148                if (&BTh && (&BTh != this)) {
     149                        if (BTh.NbRef>0) BTh.NbRef--;
     150                        else if (BTh.NbRef==0) delete &BTh;
     151                }
     152                PreInit(0); // set all to zero
     153        }
     154        /*}}}1*/
     155        /*FUNCTION Triangles::Triangles(Triangles & Th,Geometry * pGh,Triangles * pBth,Int4 nbvxx) COPY{{{1*/
     156        Triangles::Triangles(Triangles & Th,Geometry * pGh,Triangles * pBth,Int4 nbvxx)
     157          : Gh(*(pGh?pGh:&Th.Gh)), BTh(*(pBth?pBth:this)) {
     158                  Gh.NbRef++;
     159                  nbvxx = Max(nbvxx,Th.nbv);
     160                  Int4 i;
     161                  // do all the allocation to be sure all the pointer existe
     162
     163                  char * cname = 0;
     164                  if (Th.name)
     165                         {
     166                          cname = new char[strlen(Th.name)+1];
     167                          strcpy(cname,Th.name);
     168                         }
     169                  PreInit(nbvxx,cname);// to make the allocation
     170                  // copy of triangles
     171                  nt=Th.nt;
     172                  nbv = Th.nbv;
     173                  nbt = Th.nbt;
     174                  nbiv = Th.nbiv;
     175                  nbe = Th.nbe;
     176                  NbSubDomains = Th.NbSubDomains;
     177                  NbOutT = Th.NbOutT;
     178                  NbOfQuad =  Th.NbOfQuad ;
     179                  NbOfSwapTriangle =0;
     180                  NbVerticesOnGeomVertex = Th.NbVerticesOnGeomVertex;
     181                  if(NbVerticesOnGeomVertex)
     182                        VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];
     183                  NbVerticesOnGeomEdge = Th.NbVerticesOnGeomEdge;
     184                  if (NbVerticesOnGeomEdge)
     185                        VerticesOnGeomEdge = new VertexOnGeom[NbVerticesOnGeomEdge] ;
     186                  if (& BTh == & Th.BTh) // same back ground
     187                         {
     188                          BTh.NbRef++;
     189                          NbVertexOnBThVertex = Th.NbVertexOnBThVertex;
     190                          if(NbVertexOnBThVertex)
     191                                VertexOnBThVertex = new VertexOnVertex[NbVertexOnBThVertex];
     192                          NbVertexOnBThEdge = Th.NbVertexOnBThEdge;
     193                          if(NbVertexOnBThEdge)
     194                                VertexOnBThEdge = new VertexOnEdge[NbVertexOnBThEdge];
     195                         }
     196                  else
     197                         { // no add on back ground mesh
     198                          BTh.NbRef++;
     199                          NbVertexOnBThVertex=0;
     200                          VertexOnBThVertex=0;
     201                          NbVertexOnBThEdge=0;
     202                          VertexOnBThEdge=0;
     203                          //       assert (& BTh == this); // --- a voir
     204
     205                         }
     206
     207
     208                  if(nbe)
     209                        edges = new Edge[nbe];
     210                  if(NbSubDomains)
     211                        subdomains = new SubDomain[NbSubDomains];
     212                  pmin = Th.pmin;
     213                  pmax = Th.pmax;
     214                  coefIcoor = Th.coefIcoor;
     215                  for(i=0;i<nbt;i++)
     216                        triangles[i].Set(Th.triangles[i],Th,*this);
     217                  for(i=0;i<nbe;i++)
     218                        edges[i].Set(Th,i,*this);
     219                  for(i=0;i<nbv;i++)
     220                        vertices[i].Set(Th.vertices[i],Th,*this);
     221                  for(i=0;i<NbSubDomains;i++) 
     222                        subdomains[i].Set(Th,i,*this);
     223                  for (i=0;i<NbVerticesOnGeomVertex;i++)
     224                        VerticesOnGeomVertex[i].Set(Th.VerticesOnGeomVertex[i],Th,*this);
     225                  for (i=0;i<NbVerticesOnGeomEdge;i++)
     226                        VerticesOnGeomEdge[i].Set(Th.VerticesOnGeomEdge[i],Th,*this);
     227                  quadtree=0;
     228
     229
     230                  //  assert(!OutSidesTriangles);
     231          }
    28232        /*}}}1*/
    29233
     
    16481852        }
    16491853        /*}}}1*/
     1854        /*FUNCTION Triangles::swap{{{1*/
     1855        int Triangle::swap(Int2 a,int koption){
     1856                if(a/4 !=0) return 0;// arete lock or MarkUnSwap
     1857
     1858                register Triangle *t1=this,*t2=at[a];// les 2 triangles adjacent
     1859                register Int1 a1=a,a2=aa[a];// les 2 numero de l arete dans les 2 triangles
     1860                if(a2/4 !=0) return 0; // arete lock or MarkUnSwap
     1861
     1862                register Vertex  *sa=t1->ns[VerticesOfTriangularEdge[a1][0]];
     1863                register Vertex  *sb=t1->ns[VerticesOfTriangularEdge[a1][1]];
     1864                register Vertex  *s1=t1->ns[OppositeVertex[a1]];
     1865                register Vertex  *s2=t2->ns[OppositeVertex[a2]];
     1866
     1867                Icoor2 det1=t1->det , det2=t2->det ;
     1868                Icoor2 detT = det1+det2;
     1869                Icoor2 detA = Abs(det1) + Abs(det2);
     1870                Icoor2 detMin = Min(det1,det2);
     1871
     1872                int OnSwap = 0;       
     1873                // si 2 triangle infini (bord) => detT = -2;
     1874                if (sa == 0) {// les deux triangles sont frontieres
     1875                        det2=bamg::det(s2->i,sb->i,s1->i);
     1876                        OnSwap = det2 >0;}
     1877                else if (sb == 0) { // les deux triangles sont frontieres
     1878                        det1=bamg::det(s1->i,sa->i,s2->i);
     1879                        OnSwap = det1 >0;}
     1880                else if(( s1 != 0) && (s2 != 0) ) {
     1881                        det1 = bamg::det(s1->i,sa->i,s2->i);
     1882                        det2 = detT - det1;
     1883                        OnSwap = (Abs(det1) + Abs(det2)) < detA;
     1884
     1885                        Icoor2 detMinNew=Min(det1,det2);
     1886                        //     if (detMin<0 && (Abs(det1) + Abs(det2) == detA)) OnSwap=BinaryRand();// just for test   
     1887                        if (! OnSwap &&(detMinNew>0)) {
     1888                                OnSwap = detMin ==0;
     1889                                if (! OnSwap) {
     1890                                        int  kopt = koption;
     1891                                        while (1)
     1892                                         if(kopt) {
     1893                                                 // critere de Delaunay pure isotrope
     1894                                                 register Icoor2 xb1 = sb->i.x - s1->i.x,
     1895                                                                         x21 = s2->i.x - s1->i.x,
     1896                                                                         yb1 = sb->i.y - s1->i.y,
     1897                                                                         y21 = s2->i.y - s1->i.y,
     1898                                                                         xba = sb->i.x - sa->i.x,
     1899                                                                         x2a = s2->i.x - sa->i.x,
     1900                                                                         yba = sb->i.y - sa->i.y,
     1901                                                                         y2a = s2->i.y - sa->i.y;
     1902                                                 register double
     1903                                                        cosb12 =  double(xb1*x21 + yb1*y21),
     1904                                                                         cosba2 =  double(xba*x2a + yba*y2a) ,
     1905                                                                         sinb12 = double(det2),
     1906                                                                         sinba2 = double(t2->det);
     1907
     1908
     1909                                                 // angle b12 > angle ba2 => cotg(angle b12) < cotg(angle ba2)
     1910                                                 OnSwap =  ((double) cosb12 * (double)  sinba2) <  ((double) cosba2 * (double) sinb12);
     1911                                                 //      if(CurrentTh)
     1912                                                 //        cout << "swap " << CurrentTh->Number(sa) << " " << CurrentTh->Number(sb) << " " ;
     1913                                                 //      cout <<  cosb12 << " " <<  sinba2 << " "  <<  cosba2 << " " << sinb12
     1914                                                 //           << " Onswap = " <<  OnSwap << endl;
     1915                                                 break;
     1916                                         }
     1917                                         else
     1918                                                {       
     1919                                                 // critere de Delaunay anisotrope
     1920                                                 Real8 som;
     1921                                                 I2 AB=(I2) *sb - (I2) *sa;
     1922                                                 I2 MAB2=((I2) *sb + (I2) *sa);
     1923                                                 R2 MAB(MAB2.x*0.5,MAB2.y*0.5);
     1924                                                 I2 A1=(I2) *s1 - (I2) *sa;
     1925                                                 I2 D = (I2) * s1 - (I2) * sb ;
     1926                                                 R2 S2(s2->i.x,s2->i.y);
     1927                                                 R2 S1(s1->i.x,s1->i.y);
     1928                                                        {
     1929                                                         Metric M=s1->m;
     1930                                                         R2 ABo = M.Orthogonal(AB);
     1931                                                         R2 A1o = M.Orthogonal(A1);
     1932                                                         // (A+B)+ x ABo = (S1+B)/2+ y A1
     1933                                                         // ABo x - A1o y =  (S1+B)/2-(A+B)/2 = (S1-B)/2 = D/2
     1934                                                         double dd = Abs(ABo.x*A1o.y)+Abs(ABo.y*A1o.x);
     1935                                                         double d = (ABo.x*A1o.y - ABo.y*A1o.x)*2; // because D/2
     1936                                                         if (Abs(d) > dd*1.e-3) {
     1937                                                                 R2 C(MAB+ABo*((D.x*A1o.y - D.y*A1o.x)/d));
     1938                                                                 som  = M(C - S2)/M(C - S1);
     1939                                                         } else
     1940                                                                {kopt=1;continue;}
     1941
     1942                                                        }
     1943                                                        {
     1944                                                         Metric M=s2->m;
     1945                                                         R2 ABo = M.Orthogonal(AB);
     1946                                                         R2 A1o = M.Orthogonal(A1);
     1947                                                         // (A+B)+ x ABo = (S1+B)/2+ y A1
     1948                                                         // ABo x - A1o y =  (S1+B)/2-(A+B)/2 = (S1-B)/2 = D/2
     1949                                                         double dd = Abs(ABo.x*A1o.y)+Abs(ABo.y*A1o.x);
     1950                                                         double d = (ABo.x*A1o.y - ABo.y*A1o.x)*2; // because D/2
     1951                                                         if(Abs(d) > dd*1.e-3) {
     1952                                                                 R2 C(MAB+ABo*((D.x*A1o.y - D.y*A1o.x)/d));
     1953                                                                 som  += M(C - S2)/M(C -  S1);
     1954                                                         } else
     1955                                                                {kopt=1;continue;}
     1956                                                        }
     1957                                                 OnSwap = som < 2;
     1958                                                 break;
     1959                                                }
     1960
     1961                                } // OnSwap
     1962                        } // (! OnSwap &&(det1 > 0) && (det2 > 0) )
     1963                }
     1964                if( OnSwap )
     1965                 bamg::swap(t1,a1,t2,a2,s1,s2,det1,det2);
     1966                else {
     1967                        NbUnSwap ++;
     1968                        t1->SetMarkUnSwap(a1);     
     1969                }
     1970                return OnSwap;
     1971        }
     1972        /*}}}1*/
     1973        /*FUNCTION Triangles::MetricAt{{{1*/
     1974        Metric Triangles::MetricAt(const R2 & A) const {
     1975                I2 a = toI2(A);
     1976                Icoor2 deta[3];
     1977                Triangle * t =FindTriangleContening(a,deta);
     1978                if (t->det <0) { // outside
     1979                        double ba,bb;
     1980                        TriangleAdjacent edge= CloseBoundaryEdge(a,t,ba,bb) ;
     1981                        return Metric(ba,*edge.EdgeVertex(0),bb,*edge.EdgeVertex(1));}
     1982                else { // inside
     1983                        Real8   aa[3];
     1984                        Real8 s = deta[0]+deta[1]+deta[2];
     1985                        aa[0]=deta[0]/s;
     1986                        aa[1]=deta[1]/s;
     1987                        aa[2]=deta[2]/s;
     1988                        return Metric(aa,(*t)[0],(*t)[1],(*t)[2]);
     1989                }
     1990        }
     1991        /*}}}1*/
     1992        /*FUNCTION Triangles::Add{{{1*/
     1993        void Triangles::Add( Vertex & s,Triangle * t, Icoor2 * det3) {
     1994                // -------------------------------------------
     1995                //             s2
     1996                //                                            !
     1997                //             /|\                            !
     1998                //            / | \                           !
     1999                //           /  |  \                          !
     2000                //    tt1   /   |   \ tt0                     !
     2001                //         /    |s   \                        !
     2002                //        /     .     \                       !
     2003                //       /  .      `   \                      !
     2004                //      / .           ` \                     !
     2005                //      ----------------                      !
     2006                //   s0       tt2       s1
     2007                //--------------------------------------------
     2008
     2009                Triangle * tt[3]; // the 3 new Triangles
     2010                Vertex &s0 = (* t)[0], &s1=(* t)[1], &s2=(* t)[2];
     2011                Icoor2  det3local[3];
     2012                int infv = &s0 ?  ((  &s1 ? ( &s2  ? -1 : 2) : 1  )) : 0;
     2013                // infv = ordre of the infini vertex (null)
     2014                register int nbd0 =0; // number of zero det3
     2015                register int izerodet=-1,iedge; // izerodet = egde contening the vertex s
     2016                Icoor2 detOld = t->det;
     2017
     2018                if ( ( infv <0 ) && (detOld <0) ||  ( infv >=0  ) && (detOld >0) )
     2019                  {
     2020                        cerr << "  infv " << infv << " det = " << detOld << endl;
     2021                        cerr << Number(s) << " "<< Number(s0) << " " 
     2022                          << Number(s1) << " "  << Number(s2) << endl;
     2023                        MeshError(3);
     2024                  }
     2025
     2026                // if det3 do not exist then constuct det3
     2027                if (!det3) {
     2028                        det3 = det3local; // alloc
     2029                        if ( infv<0 ) {
     2030                                det3[0]=bamg::det(s ,s1,s2);
     2031                                det3[1]=bamg::det(s0,s ,s2);
     2032                                det3[2]=bamg::det(s0,s1,s );}
     2033                        else {
     2034                                // one of &s1  &s2  &s0 is NULL so (&si || &sj) <=> !&sk
     2035                                det3[0]=  &s0 ? -1  : bamg::det(s ,s1,s2) ;
     2036                                det3[1]=  &s1 ? -1 : bamg::det(s0,s ,s2) ;
     2037                                det3[2]=  &s2 ? -1 : bamg::det(s0,s1,s ) ;}}
     2038
     2039
     2040                                if (!det3[0]) izerodet=0,nbd0++;
     2041                                if (!det3[1]) izerodet=1,nbd0++;
     2042                                if (!det3[2]) izerodet=2,nbd0++;
     2043
     2044                                if  (nbd0 >0 ) // point s on a egde or on a vertex
     2045                                 if (nbd0 == 1) {
     2046                                         iedge = OppositeEdge[izerodet];
     2047                                         TriangleAdjacent ta = t->Adj(iedge);
     2048
     2049                                         // the point is on the edge
     2050                                         // if the point is one the boundary
     2051                                         // add the point in outside part
     2052                                         if ( t->det >=0) { // inside triangle
     2053                                                 if ((( Triangle *) ta)->det < 0 ) {
     2054                                                         // add in outside triangle
     2055                                                         Add(s,( Triangle *) ta);
     2056                                                         return;}
     2057                                         }}
     2058                                 else {
     2059                                         cerr << " bug  " << nbd0 <<endl;
     2060                                         cerr << " Bug double points in " << endl ;
     2061                                         cerr << " s = " << Number(s) << " " <<  s << endl;
     2062                                         cerr << " s0 = "<< Number(s0) << " "  << s0 << endl;
     2063                                         cerr << " s1 = "<< Number(s1) << " "  << s1 << endl;
     2064                                         cerr << " s2 = "<< Number(s2) << " "  << s2 << endl;
     2065                                         MeshError(5,this);}
     2066
     2067                                         // remove de MarkUnSwap edge
     2068                                         t->SetUnMarkUnSwap(0);     
     2069                                         t->SetUnMarkUnSwap(1);     
     2070                                         t->SetUnMarkUnSwap(2);
     2071
     2072                                         tt[0]= t;
     2073                                         tt[1]= &triangles[nbt++];
     2074                                         tt[2]= &triangles[nbt++];
     2075
     2076                                         if (nbt>nbtx) {
     2077                                                 cerr << " No enougth triangles " << endl;
     2078                                                 MeshError(999,this);
     2079                                         }
     2080
     2081                                         *tt[1]=   *tt[2]= *t;
     2082                                         // gestion of the link
     2083                                         tt[0]->link=tt[1];
     2084                                         tt[1]->link=tt[2];
     2085
     2086                                         (* tt[0])(OppositeVertex[0])=&s;
     2087                                         (* tt[1])(OppositeVertex[1])=&s;
     2088                                         (* tt[2])(OppositeVertex[2])=&s;
     2089
     2090                                         tt[0]->det=det3[0];
     2091                                         tt[1]->det=det3[1];
     2092                                         tt[2]->det=det3[2];         
     2093
     2094                                         //  update adj des triangles externe
     2095                                         tt[0]->SetAdjAdj(0);
     2096                                         tt[1]->SetAdjAdj(1);
     2097                                         tt[2]->SetAdjAdj(2);
     2098                                         //  update des adj des 3 triangle interne
     2099                                         const int i0 = 0;
     2100                                         const int i1= NextEdge[i0];
     2101                                         const int i2 = PreviousEdge[i0];
     2102
     2103                                         tt[i0]->SetAdj2(i2,tt[i2],i0);
     2104                                         tt[i1]->SetAdj2(i0,tt[i0],i1);
     2105                                         tt[i2]->SetAdj2(i1,tt[i1],i2);
     2106
     2107                                         tt[0]->SetTriangleContainingTheVertex();
     2108                                         tt[1]->SetTriangleContainingTheVertex();
     2109                                         tt[2]->SetTriangleContainingTheVertex();
     2110
     2111
     2112                                         // swap if the point s is on a edge
     2113                                         if(izerodet>=0) {
     2114                                                 //  cout << " the point s is on a edge =>swap " << iedge << " "  << *tt[izerodet] << endl;
     2115                                                 int rswap =tt[izerodet]->swap(iedge);
     2116
     2117                                                 if (!rswap)
     2118                                                        {
     2119                                                         cout << " Pb swap the point s is on a edge =>swap " << iedge << " "  << *tt[izerodet] << endl;
     2120                                                        }
     2121                                                 assert(rswap);
     2122                                         }
     2123        }
     2124        /*}}}1*/
     2125        /*FUNCTION Triangles::SplitInternalEdgeWithBorderVertices{{{1*/
     2126        Int4  Triangles::SplitInternalEdgeWithBorderVertices(){
     2127                Int4 NbSplitEdge=0;
     2128                SetVertexFieldOn(); 
     2129                Int4 it;
     2130                Int4 nbvold=nbv;
     2131                long int verbosity=2;
     2132                for (it=0;it<nbt;it++)
     2133                  {
     2134                        Triangle &t=triangles[it];
     2135                        if (t.link)
     2136                         for (int j=0;j<3;j++)
     2137                          if(!t.Locked(j) && !t.Hidden(j)){
     2138                                  Triangle &tt = *t.TriangleAdj(j);
     2139                                  if ( &tt && tt.link && it < Number(tt))
     2140                                         { // an internal edge
     2141                                          Vertex &v0 = t[VerticesOfTriangularEdge[j][0]];
     2142                                          Vertex &v1 = t[VerticesOfTriangularEdge[j][1]];
     2143                                          if (v0.on && v1.on)
     2144                                                 {
     2145                                                  R2 P= ((R2) v0 + (R2) v1)*0.5;
     2146                                                  if ( nbv<nbvx) {
     2147                                                          vertices[nbv].r = P;
     2148                                                          vertices[nbv++].m = Metric(0.5,v0.m,0.5,v1.m);
     2149                                                          vertices[nbv].ReferenceNumber=0;
     2150                                                          vertices[nbv].DirOfSearch = NoDirOfSearch ;
     2151                                                  }
     2152                                                  NbSplitEdge++;
     2153                                                  if (verbosity>7)
     2154                                                        cout <<" Internal edge with two vertices on boundary"
     2155                                                          << Number(v0) << " " << Number(v1) << " by " <<  endl;
     2156                                                 }
     2157                                         }
     2158                          }
     2159                  }
     2160                ReMakeTriangleContainingTheVertex();   
     2161                if (nbvold!=nbv)
     2162                  {
     2163                        Int4  iv = nbvold;
     2164                        Int4 NbSwap = 0;
     2165                        Icoor2 dete[3]; 
     2166                        for (Int4 i=nbvold;i<nbv;i++)
     2167                          {// for all the new point
     2168                                Vertex & vi = vertices[i];
     2169                                vi.i = toI2(vi.r);
     2170                                vi.r = toR2(vi.i);
     2171                                //      if (!quadtree->ToClose(vi,seuil,hi,hj)) {
     2172                                // a good new point
     2173                                vi.ReferenceNumber=0;
     2174                                vi.DirOfSearch =NoDirOfSearch;
     2175                                //      cout << " Add " << Number(vi) << " " << vi
     2176                                // << "   " <<  Number(vi) << " <--> " << Number(vi) <<endl;
     2177                                Triangle *tcvi = FindTriangleContening(vi.i,dete);
     2178                                if (tcvi && !tcvi->link) {
     2179                                        cout << i <<  " PB insert point " << Number(vi) << vi << Number(vi)
     2180                                          << " tcvi = " << tcvi << " " << tcvi->link << endl;
     2181                                        cout << (*tcvi)[1] <<  (*tcvi)[2] << endl;
     2182                                        tcvi = FindTriangleContening(vi.i,dete);
     2183                                        cout << (*tcvi)[1] <<  (*tcvi)[2] << endl;
     2184                                        MeshError(1001,this);
     2185                                }
     2186
     2187
     2188                                quadtree->Add(vi);
     2189                                assert (tcvi && tcvi->det >= 0) ;// internal
     2190                                Add(vi,tcvi,dete);
     2191                                NbSwap += vi.Optim(1);         
     2192                                iv++;
     2193                                //      }
     2194                          }
     2195                        if (verbosity>3)
     2196                          {
     2197                                cout << "    Nb Of New Point " << iv ;
     2198                                cout << " Nb swap = " << NbSwap << " to  split internal edges with border vertices" ;}
     2199
     2200                                nbv = iv;
     2201                  }
     2202                if (NbSplitEdge >  nbv-nbvold)
     2203                 cout << " Warning not enough vertices  to split all internal edges "  << endl
     2204                        << "    we lost " << NbSplitEdge - ( nbv-nbvold) << " Edges Sorry " << endl;
     2205                if (verbosity>2)
     2206                 cout << "SplitInternalEdgeWithBorderVertices: Number of splited edge " << NbSplitEdge << endl;
     2207                return  NbSplitEdge;
     2208        }
     2209        /*}}}1*/
     2210        /*FUNCTION Triangles::InsertNewPoints{{{1*/
     2211        Int4 Triangles::InsertNewPoints(Int4 nbvold,Int4 & NbTSwap) {
     2212                long int verbosity=2;
     2213                Real8 seuil= 1.414/2 ;// for two close point
     2214                Int4 i;
     2215                // insertion part ---
     2216
     2217                const Int4 nbvnew = nbv-nbvold;
     2218                if (verbosity>5)
     2219                 cout << "    Try to Insert the " <<nbvnew<< " new points " << endl; 
     2220                Int4 NbSwap=0;
     2221                Icoor2 dete[3];
     2222
     2223                // construction d'un ordre aleatoire
     2224                if (! nbvnew)
     2225                 return 0;
     2226                if (nbvnew) {
     2227                        const Int4 PrimeNumber= AGoodNumberPrimeWith(nbv)  ;
     2228                        Int4 k3 = rand()%nbvnew ;
     2229                        for (Int4 is3=0; is3<nbvnew; is3++) {
     2230                                register Int4 j = nbvold +(k3 = (k3 + PrimeNumber)% nbvnew);
     2231                                register Int4 i = nbvold+is3;
     2232                                ordre[i]= vertices + j;
     2233                                ordre[i]->ReferenceNumber=i;
     2234                        }
     2235                        // be carefull
     2236                        Int4  iv = nbvold;
     2237                        for (i=nbvold;i<nbv;i++)
     2238                          {// for all the new point
     2239                                Vertex & vi = *ordre[i];
     2240                                vi.i = toI2(vi.r);
     2241                                vi.r = toR2(vi.i);
     2242                                Real4 hx,hy;
     2243                                vi.m.Box(hx,hy);
     2244                                Icoor1 hi=(Icoor1) (hx*coefIcoor),hj=(Icoor1) (hy*coefIcoor);
     2245                                if (!quadtree->ToClose(vi,seuil,hi,hj))
     2246                                  {
     2247                                        // a good new point
     2248                                        Vertex & vj = vertices[iv];
     2249                                        Int4 j = vj.ReferenceNumber;
     2250                                        assert( &vj== ordre[j]);
     2251                                        if(i!=j)
     2252                                          { //  for valgring
     2253                                                Exchange(vi,vj);
     2254                                                Exchange(ordre[j],ordre[i]);
     2255                                          }
     2256                                        vj.ReferenceNumber=0;
     2257                                        //      cout << " Add " << Number(vj) << " " << vj
     2258                                        // << "   " <<  Number(vi) << " <--> " << Number(vj) <<endl;
     2259                                        Triangle *tcvj = FindTriangleContening(vj.i,dete);
     2260                                        if (tcvj && !tcvj->link)
     2261                                          {
     2262                                                cerr << i <<  " PB insert point " << Number(vj) << vj << Number(vi)
     2263                                                  << " tcvj = " << tcvj << " " << tcvj->link << endl;
     2264                                                cerr << (*tcvj)[1] <<  (*tcvj)[2] << endl;
     2265                                                tcvj = FindTriangleContening(vj.i,dete);
     2266                                                cout << (*tcvj)[1] <<  (*tcvj)[2] << endl;
     2267                                                MeshError(1001,this);
     2268                                          }
     2269
     2270
     2271                                        quadtree->Add(vj);
     2272                                        assert (tcvj && tcvj->det >= 0) ;// internal
     2273                                        Add(vj,tcvj,dete);
     2274                                        NbSwap += vj.Optim(1);         
     2275                                        iv++;
     2276                                  }
     2277                          }
     2278                        if (verbosity>3) {
     2279                                cout << "    Nb Of New Point " << iv << " Nb Of To close Points " << nbv-iv ;
     2280                                cout << " Nb swap = " << NbSwap << " after " ;}
     2281
     2282                                nbv = iv;
     2283                }
     2284
     2285                for (i=nbvold;i<nbv;i++)
     2286                 NbSwap += vertices[i].Optim(1); 
     2287                if (verbosity>3)
     2288                 cout << " NbSwap = " <<  NbSwap << endl;
     2289
     2290
     2291                NbTSwap +=  NbSwap ;
     2292                return nbv-nbvold;
     2293
     2294        }
     2295        /*}}}1*/
     2296        /*FUNCTION Triangles::NewPoints{{{1*/
     2297        void  Triangles::NewPoints(Triangles & Bh,int KeepBackVertex) {
     2298                long int verbosity=2;
     2299                Int4 nbtold(nbt),nbvold(nbv);
     2300                if (verbosity>2)
     2301                 cout << "  -- Triangles::NewPoints ";
     2302                if (verbosity>3)cout <<  " nbv (in)  on Boundary  = " << nbv  <<endl;
     2303                Int4 i,k;
     2304                int j;
     2305                Int4 *first_np_or_next_t = new Int4[nbtx];
     2306                Int4 NbTSwap =0;
     2307                //    insert old point
     2308                nbtold = nbt;
     2309
     2310                if (KeepBackVertex && (&Bh != this) && (nbv+Bh.nbv< nbvx))
     2311                  {
     2312                        //   Bh.SetVertexFieldOn();
     2313                        for (i=0;i<Bh.nbv;i++)
     2314                          {
     2315                                Vertex & bv = Bh[i];
     2316                                if (!bv.on) {
     2317                                        vertices[nbv].r = bv.r;
     2318                                        vertices[nbv++].m = bv.m;}
     2319                          }
     2320                        int nbv1=nbv;
     2321                        Bh.ReMakeTriangleContainingTheVertex();     
     2322                        InsertNewPoints(nbvold,NbTSwap)   ;           
     2323                        if (verbosity>2)
     2324                         cout <<  "      (Nb of Points from background mesh  = "
     2325                                << nbv-nbvold  << " / " << nbv1-nbvold << ")" << endl;
     2326                  } 
     2327                else
     2328                 Bh.ReMakeTriangleContainingTheVertex();     
     2329
     2330                Triangle *t;
     2331                // generation of the list of next Triangle
     2332                // at 1 time we test all the triangles
     2333                Int4 Headt =0,next_t;
     2334                for(i=0;i<nbt;i++)
     2335                 first_np_or_next_t[i]=-(i+1);
     2336                // end list i >= nbt
     2337                // the list of test triangle is
     2338                // the next traingle on i is  -first_np_or_next_t[i]
     2339                int iter=0;
     2340                // Big loop
     2341                do {
     2342                        iter++;
     2343                        nbtold = nbt;
     2344                        nbvold = nbv;
     2345
     2346                        // default size of  IntersectionTriangle
     2347
     2348                        i=Headt;
     2349                        next_t=-first_np_or_next_t[i];
     2350                        for(t=&triangles[i];i<nbt;t=&triangles[i=next_t],next_t=-first_np_or_next_t[i])
     2351                          { // for each triangle  t
     2352                                // we can change first_np_or_next_t[i]
     2353                                //      cout << " Do the triangle " << i << " Next_t=" << next_t << endl;
     2354                                assert(i>=0 && i < nbt );
     2355                                first_np_or_next_t[i] = iter;
     2356                                for(j=0;j<3;j++)
     2357                                  { // for each edge
     2358                                        TriangleAdjacent tj(t,j);
     2359                                        Vertex & vA = * tj.EdgeVertex(0);
     2360                                        Vertex & vB = * tj.EdgeVertex(1);
     2361
     2362                                        if (!t->link) continue;// boundary
     2363                                        if (t->det <0) continue;
     2364                                        if (t->Locked(j)) continue;
     2365
     2366                                        TriangleAdjacent tadjj = t->Adj(j);       
     2367                                        Triangle * ta= tadjj;
     2368
     2369                                        if (ta->det <0) continue;         
     2370
     2371                                        R2 A = vA;
     2372                                        R2 B = vB;
     2373
     2374                                        k=Number(ta);
     2375
     2376                                        if(first_np_or_next_t[k]==iter)  // this edge is done before
     2377                                         continue; // next edge of the triangle
     2378
     2379                                        //const Int4 NbvOld = nbv;
     2380                                        lIntTria.SplitEdge(Bh,A,B);
     2381                                        lIntTria.NewPoints(vertices,nbv,nbvx);
     2382                                  } // end loop for each edge
     2383
     2384                          }// for triangle   
     2385
     2386                        if (!InsertNewPoints(nbvold,NbTSwap))
     2387                         break;
     2388
     2389                        for (i=nbtold;i<nbt;i++)
     2390                         first_np_or_next_t[i]=iter;
     2391
     2392                        Headt = nbt; // empty list
     2393                        for (i=nbvold;i<nbv;i++)
     2394                          { // for all the triangle contening the vertex i
     2395                                Vertex * s  = vertices + i;
     2396                                TriangleAdjacent ta(s->t, EdgesVertexTriangle[s->vint][1]);
     2397                                Triangle * tbegin= (Triangle*) ta;
     2398                                Int4 kt;
     2399                                do {
     2400                                        kt = Number((Triangle*) ta);
     2401                                        if (first_np_or_next_t[kt]>0)
     2402                                         first_np_or_next_t[kt]=-Headt,Headt=kt;
     2403                                        assert( ta.EdgeVertex(0) == s);
     2404                                        ta = Next(Adj(ta));
     2405                                } while ( (tbegin != (Triangle*) ta));
     2406                          }   
     2407
     2408                } while (nbv!=nbvold);
     2409
     2410                delete []  first_np_or_next_t;
     2411
     2412                Int4 NbSwapf =0,NbSwp;
     2413
     2414                // bofbof
     2415
     2416
     2417                NbSwp = NbSwapf;
     2418                for (i=0;i<nbv;i++)
     2419                 NbSwapf += vertices[i].Optim(0);
     2420                /*
     2421                        for (i=0;i<nbv;i++)
     2422                        NbSwapf += vertices[i].Optim(0);
     2423                        for (i=0;i<nbv;i++)
     2424                        NbSwapf += vertices[i].Optim(0);
     2425                        for (i=0;i<nbv;i++)
     2426                        NbSwapf += vertices[i].Optim(0);
     2427                        for (i=0;i<nbv;i++)
     2428                        NbSwapf += vertices[i].Optim(0);
     2429                        */
     2430                NbTSwap +=  NbSwapf ;
     2431                if (verbosity>3) cout << "   " ;
     2432                if (verbosity>2)
     2433                 cout << " Nb Of Vertices =" << nbv << " Nb of triangles = " << nbt-NbOutT
     2434                        << " NbSwap final = " << NbSwapf << " Nb Total Of Swap = " << NbTSwap << endl;
     2435
     2436
     2437        }
     2438        /*}}}1*/
     2439        /*FUNCTION Triangles::NewPointsOld{{{1*/
     2440        void  Triangles::NewPointsOld(Triangles & Bh) {
     2441                long int verbosity=2;
     2442                Real8 seuil= 0.7 ;// for two neart point
     2443                if (verbosity>1)
     2444                 cout << " begin :  Triangles::NewPointsOld " << endl;
     2445                Int4 i,k;
     2446                int j;
     2447                Int4 BeginNewPoint[3];
     2448                Int4 EndNewPoint[3];
     2449#ifdef TRACETRIANGLE
     2450                Int4 trace=0;
     2451#endif
     2452                int step[3];
     2453                Int4 *first_np_or_next_t = new Int4[nbtx];
     2454                Int4 ColorEdge[3];
     2455                Int4 color=-1;
     2456                Triangle *t;
     2457                // generation of the list of next Triangle
     2458                // at 1 time we test all the triangles
     2459                Int4 Headt =0,next_t;
     2460                for(i=0;i<nbt;i++)
     2461                 first_np_or_next_t[i]=-(i+1);
     2462                // end list i >= nbt
     2463                // the list of test triangle is
     2464                // the next Triangle on i is  -first_np_or_next_t[i]
     2465                Int4 nbtold,nbvold;
     2466
     2467                // Big loop
     2468                do {
     2469                        nbtold = nbt;
     2470                        nbvold = nbv;
     2471                        // default size of  IntersectionTriangle
     2472
     2473                        i=Headt;
     2474                        next_t=-first_np_or_next_t[i];
     2475                        for(t=&triangles[i];i<nbt;t=&triangles[i=next_t],next_t=-first_np_or_next_t[i])
     2476                          { // for each triangle  t
     2477                                // we can change first_np_or_next_t[i]
     2478#ifdef TRACETRIANGLE
     2479                                trace =  TRACETRIANGLE <0 ? 1 : i == TRACETRIANGLE;
     2480#endif
     2481                                //      cout << " Do the triangle " << i << " Next_t=" << next_t << endl;
     2482                                assert(i>=0 && i < nbt );
     2483                                first_np_or_next_t[i] = nbv; // to save the fist new point of triangle
     2484                                for(j=0;j<3;j++)
     2485                                  { // for each edge
     2486                                        TriangleAdjacent tj(t,j);
     2487                                        // color++;// the color is 3i+j
     2488                                        color = 3*i + j ;;
     2489                                        ColorEdge[j]=color;
     2490                                        BeginNewPoint[j]=nbv;
     2491                                        EndNewPoint[j]=nbv-1;
     2492                                        step[j]=1;// right sens
     2493                                        Vertex & vA = * tj.EdgeVertex(0);
     2494                                        Vertex & vB = * tj.EdgeVertex(1);
     2495
     2496#ifdef TRACETRIANGLE
     2497                                        if(trace) {
     2498                                                cout << " i " << Number(vA) <<" j "<<  Number(vB)
     2499                                                  << " "  << t->Locked(j) ;
     2500                                        }
     2501#endif
     2502                                        if (!t->link) continue;// boundary
     2503                                        if (t->det <0) continue;
     2504                                        if (t->Locked(j)) continue;
     2505
     2506                                        TriangleAdjacent tadjj = t->Adj(j);       
     2507                                        Triangle * ta= tadjj;
     2508
     2509                                        if (ta->det <0) continue;         
     2510
     2511                                        R2 A = vA;
     2512                                        R2 B = vB;
     2513
     2514                                        k=Number(ta);
     2515                                        // the 2 opposite vertices
     2516                                        const Vertex & vC1  =  *tj.OppositeVertex();
     2517                                        const Vertex & vC2 = *tadjj.OppositeVertex();
     2518
     2519#ifdef TRACETRIANGLE
     2520                                        trace = trace || k == TRACETRIANGLE;
     2521                                        if(trace) {
     2522                                                cout << "Test Arete " << i << " AB = " << A << B
     2523                                                  << "i "  <<Number(vA)<< "j" <<Number(vB);
     2524                                                cout << " link" <<(int)t->link << " ta=" << Number( ta)
     2525                                                  << " det " <<ta->det ;
     2526                                                cout << " hA = " <<vA.m.h << " hB = " <<vB.m.h ;
     2527                                                cout << " loc " << ta->Locked(j) << endl;
     2528                                        }
     2529#endif
     2530
     2531                                        if(first_np_or_next_t[k]>0) { // this edge is done before
     2532                                                // find the color of the edge and begin , end of newpoint
     2533                                                register int kk = t->NuEdgeTriangleAdj(j);
     2534                                                assert ((*t)(VerticesOfTriangularEdge[j][0]) == (*ta)(VerticesOfTriangularEdge[kk][1]));
     2535                                                assert ((*t)(VerticesOfTriangularEdge[j][1]) == (*ta)(VerticesOfTriangularEdge[kk][0]));
     2536                                                register Int4 kolor =3*k + kk;
     2537                                                ColorEdge[j]=kolor;
     2538                                                register Int4 kkk= 1;
     2539                                                step[j]=-1;// other sens
     2540                                                BeginNewPoint[j]=0;
     2541                                                EndNewPoint[j]=-1; // empty list         
     2542                                                for (Int4 iv=first_np_or_next_t[k];iv<nbv;iv++)
     2543                                                 if (vertices[iv].color > kolor)
     2544                                                  break; // the color is passed           
     2545                                                 else if (vertices[iv].color == kolor) {
     2546                                                         EndNewPoint[j]=iv;
     2547                                                         if (kkk) // one time test
     2548                                                          kkk=0,BeginNewPoint[j]=iv;}
     2549                                                         continue; // next edge of the triangle
     2550                                        } // end  if( k < i)
     2551
     2552
     2553                                        const Int4 NbvOld = nbv;
     2554                                        lIntTria.SplitEdge(Bh,A,B);
     2555                                        // Int4 NbvNp =
     2556                                        lIntTria.NewPoints(vertices,nbv,nbvx);
     2557                                        Int4 nbvNew=nbv;
     2558                                        nbv = NbvOld;
     2559                                        for (Int4 iv=NbvOld;iv<nbvNew;iv++) {
     2560                                                vertices[nbv].color = color;
     2561                                                vertices[nbv].ReferenceNumber=nbv;// circular link
     2562                                                R2 C =  vertices[iv].r;
     2563                                                vertices[nbv].r =  C;
     2564                                                vertices[nbv].m =  vertices[iv].m ;
     2565                                                // test if the new point is not to close to the 2 opposite vertex
     2566                                                R2 CC1 = C-vC1 , CC2 = C-vC2;
     2567                                                if (   (  (vC1.m(CC1) + vertices[nbv].m(CC1)) >  seuil)
     2568                                                                        && (  (vC2.m(CC2) + vertices[nbv].m(CC2)) >  seuil) )
     2569                                                 nbv++;
     2570                                        }
     2571
     2572                                        EndNewPoint[j] = nbv-1;
     2573                                  } // end loop for each edge
     2574
     2575#ifdef TRACETRIANGLE
     2576                                if(trace) {
     2577                                        // verification des point cree
     2578                                        cout << "\n ------------ " << t->link << " " << t->det
     2579                                          << " b " << BeginNewPoint[0] << " " << BeginNewPoint[1]
     2580                                          << " " << BeginNewPoint[2] << " "
     2581                                          << " e " << EndNewPoint[0] << " " << EndNewPoint[1]
     2582                                          << " " << EndNewPoint[2] << " "
     2583                                          << " s " << step[0] << " " << step[1] << " " << step[2] << " "
     2584                                          <<  endl;
     2585                                }
     2586#endif
     2587
     2588                                if (!t->link) continue;// boundary
     2589                                if (t->det<=0) continue;// outside
     2590                                //      continue;
     2591                                for(int j0=0;j0<3;j0++)
     2592                                 for (Int4 i0= BeginNewPoint[j0]; i0 <= EndNewPoint[j0];i0++)
     2593                                        {
     2594                                         // find the neart  point one the opposite edge
     2595                                         // to compute i1
     2596                                         Vertex & vi0 = vertices[i0];
     2597                                         int kstack = 0;
     2598                                         Int4 stack[10];
     2599                                         //   Int4 savRef[10];
     2600                                         int j1 = j0;
     2601                                         while (j0 != (j1 = NextEdge[j1])) {//loop on the 2 other edge
     2602                                                 // computation of the intersection of edge j1 and DOrto
     2603                                                 // take the good sens
     2604
     2605                                                 if (BeginNewPoint[j1]> EndNewPoint[j1])
     2606                                                  continue; //
     2607                                                 else if (EndNewPoint[j1] - BeginNewPoint[j1] <1) {
     2608                                                         for (Int4 ii1= BeginNewPoint[j1];ii1<=EndNewPoint[j1];ii1++)
     2609                                                          stack[kstack++] = ii1;
     2610                                                         continue;}
     2611
     2612
     2613                                                         int k0,k1;
     2614                                                         if (step[j1]<0) k0=1,k1=0; // reverse
     2615                                                         else k0=0,k1=1;
     2616                                                         R2 V10 = (R2)(*t)[VerticesOfTriangularEdge[j1][k0]];
     2617                                                         R2 V11 = (R2)(*t)[VerticesOfTriangularEdge[j1][k1]];
     2618                                                         R2 D = V11-V10;
     2619                                                         Real8 c0 =  vi0.m(D,(R2) vi0);
     2620
     2621                                                         Real8 c10 =  vi0.m(D,V10);
     2622                                                         Real8 c11 =  vi0.m(D,V11);
     2623
     2624                                                         Real8 s;
     2625                                                         //cout << " --i0 = " << i0  << D  << V10 << V11 << endl ;
     2626                                                         //cout << "   c10 " <<  c10 << " c0 " << c0 << " c11 " << c11 << endl;
     2627                                                         if (( c10 < c0 ) && (c0 < c11))
     2628                                                          s = (c11-c0)/(c11-c10);
     2629                                                         else if  (( c11 < c0 ) && (c0 < c10))
     2630                                                          s = (c11-c0) /(c11-c10);
     2631                                                         else break;
     2632                                                         R2 VP = V10*s + V11*(1-s);
     2633                                                         int sss = (c11-c10) >0 ? 1 : -1;
     2634                                                         // find the 2 point by dichotomie
     2635                                                         //cout << "   t =" << Number(t) << " c0 " << c0  ;
     2636                                                         Int4 ii0 =  BeginNewPoint[j1];
     2637                                                         Int4 ii1 =  EndNewPoint[j1];       
     2638                                                         Real8 ciii=-1,cii0=-1,cii1=-1  ;
     2639                                                         if ( sss * ((cii0=vi0.m(D,(R2) vertices[ii0]))- c0) >0 ) 
     2640                                                          stack[kstack++] = ii0;//cout << " add+0 " << ii0;
     2641                                                         else if ( sss * ((cii1=  vi0.m(D ,(R2) vertices[ii1]))- c0) < 0 ) 
     2642                                                          stack[kstack++] = ii1;//cout << " add+1 " << ii1;
     2643                                                         else {
     2644                                                                 while ((ii1-ii0)> 1) {
     2645                                                                         Int4 iii = (ii0+ii1)/2;
     2646                                                                         ciii = vi0.m( D ,(R2) vertices[iii]);
     2647                                                                         //cout << " (iii = " << iii << " " <<  ciii << ") ";
     2648                                                                         if ( sss * (ciii - c0) <0 )  ii0 = iii;
     2649                                                                         else ii1 = iii;}                             
     2650                                                                         stack[kstack++] = ii0;// cout << " add0 " << ii0;
     2651                                                                         if (ii1 != ii0)  stack[kstack++] = ii1;//cout << " add1 " << ii1;
     2652                                                         }
     2653                                                         if (kstack >5) // bug ?
     2654                                                          cout << "NewPoints: bug????? " << kstack << " stack  " << stack[kstack]<< endl;
     2655                                         }
     2656
     2657                                         stack[kstack++] = -1; // to stop
     2658                                         Int4 i1;
     2659                                         kstack =0;
     2660                                         while( (i1=stack[kstack++]) >= 0)
     2661                                                { // the two parameter is i0 and i1
     2662                                                 assert(i1 < nbv && i1 >= 0);
     2663                                                 assert(i0 < nbv && i0 >= 0);
     2664                                                 assert(i1 != i0);
     2665                                                 R2 v01 = (R2) vertices[i1]- (R2) vertices[i0];
     2666                                                 Real8 d01 = (vertices[i0].m(v01) + vertices[i1].m(v01));
     2667
     2668
     2669#ifdef TRACETRIANGLE
     2670                                                 if(trace) {
     2671                                                         cout << "\n test j" << j <<" "  << i0
     2672                                                                << " " << i1 << " d01=" << d01 <<endl;}
     2673#endif
     2674                                                 assert (i0 >= nbvold);
     2675                                                 assert (i1 >= nbvold);
     2676                                                 assert(i0 != i1);
     2677                                                 if (d01 == 0)
     2678                                                  break;
     2679                                                 if ( d01 < seuil)
     2680                                                  if (i1<nbvold) {
     2681                                                          // remove all the points i0;
     2682                                                          register Int4 ip,ipp;
     2683                                                          for  (ip=i0;i0 != (ipp = vertices[ip].ReferenceNumber);ip=ipp)
     2684                                                                vertices[ip].ReferenceNumber = -1;// mark remove
     2685                                                          vertices[ip].ReferenceNumber = -1;// mark remove
     2686                                                  }
     2687                                                  else {
     2688                                                          // remove on of two points
     2689                                                          register Int4 ip0, ip1, ipp0,ipp1;
     2690                                                          register int kk0=1,kk1=1;
     2691                                                          // count the number of common points to compute weight w0,w1
     2692                                                          for  (ip0=i0;i0 != (ipp0 = vertices[ip0].ReferenceNumber);ip0=ipp0) kk0++;
     2693                                                          for  (ip1=i1;i1 != (ipp1 = vertices[ip1].ReferenceNumber);ip1=ipp1) kk1++;
     2694
     2695                                                          register Real8 w0 = ((Real8) kk0)/(kk0+kk1);
     2696                                                          register Real8 w1 = ((Real8) kk1)/(kk0+kk1);
     2697
     2698                                                          // make a circular link
     2699                                                          Exchange(vertices[i0].ReferenceNumber,vertices[i1].ReferenceNumber);
     2700                                                          // the new coordinate
     2701                                                          R2 C //= vertices[i0] ;
     2702                                                          =  vertices[i0].r *w0 + vertices[i1].r* w1;
     2703
     2704#ifdef TRACETRIANGLE
     2705                                                          if(trace) {
     2706                                                                  cout << "\n ref = "<< vertices[i0].ref << " " <<vertices[i1].ref <<endl;
     2707                                                          }
     2708#endif   
     2709                                                          // update the new point points of the list
     2710                                                          for  (ip0=i0;i0 != (ipp0 = vertices[ip0].ReferenceNumber);ip0=ipp0)
     2711                                                                vertices[ip0].r = C;         
     2712                                                          vertices[ip0].r = C;
     2713                                                  }
     2714                                                }
     2715                                        } // for (i0= ....
     2716                          }// for triangle   
     2717
     2718                        // remove of all the double points
     2719
     2720                        Int4 ip,ipp,kkk=nbvold;
     2721                        for (i=nbvold;i<nbv;i++)
     2722                         if (vertices[i].ReferenceNumber>=0) {// good points
     2723                                 //  cout <<" i = " << i ;
     2724                                 for  (ip=i;i != (ipp = vertices[ip].ReferenceNumber);ip=ipp)
     2725                                  vertices[ip].ReferenceNumber = -1;// mark remove
     2726                                 vertices[ip].ReferenceNumber = -1;// mark remove
     2727                                 // cout << i << " ---> " << kkk << endl;       
     2728                                 vertices[kkk] = vertices[i];
     2729                                 vertices[kkk].i = toI2(vertices[kkk].r);
     2730                                 vertices[kkk++].ReferenceNumber = 0;
     2731
     2732                         }
     2733
     2734                        // insertion part ---
     2735
     2736                        const Int4 nbvnew = kkk-nbvold;
     2737
     2738                        cout << "    Remove " << nbv - kkk  << " to close  vertex " ;
     2739                        cout << " and   Insert the " <<nbvnew<< " new points " << endl; 
     2740                        nbv = kkk;
     2741                        Int4 NbSwap=0;
     2742                        Icoor2 dete[3];
     2743
     2744                        // construction d'un ordre aleatoire
     2745                        if (! nbvnew)
     2746                         break;
     2747                        if (nbvnew) {
     2748                                const Int4 PrimeNumber= AGoodNumberPrimeWith(nbv)  ;
     2749                                Int4 k3 = rand()%nbvnew ;
     2750                                for (Int4 is3=0; is3<nbvnew; is3++)
     2751                                 ordre[nbvold+is3]= &vertices[nbvold +(k3 = (k3 + PrimeNumber)% nbvnew)];
     2752
     2753                                for (i=nbvold;i<nbv;i++)
     2754                                  { Vertex * vi = ordre[i];
     2755                                        Triangle *tcvi = FindTriangleContening(vi->i,dete);
     2756                                        //     Vertex * nv =  quadtree->NearestVertex(vi->i.x,vi->i.y);
     2757                                        //      cout << " Neart Vertex of "  << Number(vi)<< vi->i << " is "
     2758                                        //   << Number(nv) << nv->i  << endl;
     2759                                        // Int4  kt = Number(tcvi);
     2760                                        //
     2761
     2762                                        quadtree->Add(*vi); //
     2763                                        assert (tcvi->det >= 0) ;// internal
     2764                                        Add(*vi,tcvi,dete),NbSwap += vi->Optim(1);         
     2765                                  } 
     2766                        }
     2767                        cout << " Nb swap = " << NbSwap << " after " ;
     2768
     2769                        for (i=nbvold;i<nbv;i++)
     2770                         NbSwap += vertices[i].Optim(1); 
     2771                        cout << NbSwap << endl;
     2772
     2773                        for (i=nbtold;i<nbt;i++)
     2774                         first_np_or_next_t[i]=1;
     2775
     2776                        Headt = nbt; // empty list
     2777                        for (i=nbvold;i<nbv;i++)
     2778                          { // for all the triangle contening the vertex i
     2779                                Vertex * s  = vertices + i;
     2780                                TriangleAdjacent ta(s->t, EdgesVertexTriangle[s->vint][1]);
     2781                                Triangle * tbegin= (Triangle*) ta;
     2782                                Int4 kt;
     2783                                do {
     2784                                        kt = Number((Triangle*) ta);
     2785                                        if (first_np_or_next_t[kt]>0)
     2786                                         first_np_or_next_t[kt]=-Headt,Headt=kt;
     2787                                        assert( ta.EdgeVertex(0) == s);
     2788                                        ta = Next(Adj(ta));
     2789                                } while ( (tbegin != (Triangle*) ta));
     2790                          }
     2791
     2792
     2793                } while (nbv!=nbvold);
     2794                delete []  first_np_or_next_t;
     2795                cout << " end :  Triangles::NewPoints old  nbv=" << nbv << endl;
     2796
     2797        }
     2798        /*}}}1*/
     2799        /*FUNCTION Triangles::Insert{{{1*/
     2800        void Triangles::Insert() {
     2801                long int verbosity=2;
     2802                if (verbosity>2) cout << "  -- Insert initial " << nbv << " vertices " << endl ;
     2803                Triangles * OldCurrentTh =CurrentTh;
     2804
     2805                CurrentTh=this;
     2806                double time0=CPUtime(),time1,time2,time3;
     2807                SetIntCoor();
     2808                Int4 i;
     2809                for (i=0;i<nbv;i++)
     2810                 ordre[i]= &vertices[i] ;
     2811
     2812                // construction d'un ordre aleatoire
     2813                const Int4 PrimeNumber= AGoodNumberPrimeWith(nbv) ;
     2814                Int4 k3 = rand()%nbv ;
     2815                for (int is3=0; is3<nbv; is3++)
     2816                 ordre[is3]= &vertices[k3 = (k3 + PrimeNumber)% nbv];
     2817
     2818
     2819
     2820
     2821                for (i=2 ; det( ordre[0]->i, ordre[1]->i, ordre[i]->i ) == 0;)
     2822                 if  ( ++i >= nbv) {
     2823                         cerr << " All the vertices are aline " << endl;
     2824                         MeshError(998,this); }
     2825
     2826                         // echange i et 2 dans ordre afin
     2827                         // que les 3 premiers ne soit pas aligne
     2828                         Exchange( ordre[2], ordre[i]);
     2829
     2830                         // on ajoute un point a l'infini pour construire le maillage
     2831                         // afin d'avoir une definition simple des aretes frontieres
     2832                         nbt = 2;
     2833
     2834
     2835                         // on construit un maillage trivale forme
     2836                         // d'une arete et de 2 triangles
     2837                         // construit avec le 2 aretes orientes et
     2838                         Vertex *  v0=ordre[0], *v1=ordre[1];
     2839
     2840                         triangles[0](0) = 0; // sommet pour infini
     2841                         triangles[0](1) = v0;
     2842                         triangles[0](2) = v1;
     2843
     2844                         triangles[1](0) = 0;// sommet pour infini
     2845                         triangles[1](2) = v0;
     2846                         triangles[1](1) = v1;
     2847                         const int e0 = OppositeEdge[0];
     2848                         const int e1 = NextEdge[e0];
     2849                         const int e2 = PreviousEdge[e0];
     2850                         triangles[0].SetAdj2(e0, &triangles[1] ,e0);
     2851                         triangles[0].SetAdj2(e1, &triangles[1] ,e2);
     2852                         triangles[0].SetAdj2(e2, &triangles[1] ,e1);
     2853
     2854                         triangles[0].det = -1;  // faux triangles
     2855                         triangles[1].det = -1;  // faux triangles
     2856
     2857                         triangles[0].SetTriangleContainingTheVertex();
     2858                         triangles[1].SetTriangleContainingTheVertex();
     2859
     2860                         triangles[0].link=&triangles[1];
     2861                         triangles[1].link=&triangles[0];
     2862
     2863                         //  nbtf = 2;
     2864                         if (  !quadtree )  quadtree = new QuadTree(this,0);
     2865                         quadtree->Add(*v0);
     2866                         quadtree->Add(*v1);
     2867
     2868                         // on ajoute les sommets un Ò un
     2869                         Int4 NbSwap=0;
     2870
     2871                         time1=CPUtime();
     2872
     2873                         if (verbosity>3) cout << "  -- Begin of insertion process " << endl;
     2874
     2875                         for (Int4 icount=2; icount<nbv; icount++) {
     2876                                 Vertex *vi  = ordre[icount];
     2877                                 //    cout << " Insert " << Number(vi) << endl;
     2878                                 Icoor2 dete[3];
     2879                                 Triangle *tcvi = FindTriangleContening(vi->i,dete);
     2880                                 quadtree->Add(*vi);
     2881                                 Add(*vi,tcvi,dete);
     2882                                 NbSwap += vi->Optim(1,0);
     2883
     2884                         }// fin de boucle en icount
     2885                         time2=CPUtime();
     2886                         if (verbosity>3)
     2887                          cout << "    NbSwap of insertion " <<    NbSwap
     2888                                 << " NbSwap/Nbv " <<  (float) NbSwap / (float) nbv
     2889                                 << " NbUnSwap " << NbUnSwap << " Nb UnSwap/Nbv "
     2890                                 << (float)NbUnSwap /(float) nbv
     2891                                 <<endl;
     2892                         NbUnSwap = 0;
     2893                         // construction d'un ordre aleatoire
     2894                         //  const int PrimeNumber= (nbv % 999983) ? 1000003: 999983 ;
     2895#ifdef NBLOOPOPTIM
     2896
     2897                         k3 = rand()%nbv ;
     2898                         for (int is4=0; is4<nbv; is4++)
     2899                          ordre[is4]= &vertices[k3 = (k3 + PrimeNumber)% nbv];
     2900
     2901                         double timeloop = time2 ;
     2902                         for(int Nbloop=0;Nbloop<NBLOOPOPTIM;Nbloop++)
     2903                                {
     2904                                 double time000 = timeloop;
     2905                                 Int4  NbSwap = 0;
     2906                                 for (int is1=0; is1<nbv; is1++)
     2907                                  NbSwap += ordre[is1]->Optim(0,0);
     2908                                 timeloop = CPUtime();
     2909                                 if (verbosity>3)
     2910                                  cout << "    Optim Loop "<<Nbloop<<" NbSwap: " <<  NbSwap
     2911                                         << " NbSwap/Nbv "         <<  (float) NbSwap / (float) nbv
     2912                                         << " CPU=" << timeloop - time000 << "  s, "
     2913                                         << " NbUnSwap/Nbv " << (float)NbUnSwap /(float) nbv 
     2914                                         <<  endl;
     2915                                 NbUnSwap = 0;
     2916                                 if(!NbSwap) break;
     2917                                }
     2918                         ReMakeTriangleContainingTheVertex();
     2919                         // because we break the TriangleContainingTheVertex
     2920#endif
     2921                         time3=CPUtime();
     2922                         if (verbosity>4)
     2923                          cout << "    init " << time1 - time0 << " initialisation,  "
     2924                                 << time2 - time1 << "s, insert point  "
     2925                                 << time3 -time2 << "s, optim " << endl
     2926                                 << "     Init Total Cpu Time = " << time3 - time0 << "s " << endl;
     2927
     2928                         CurrentTh=OldCurrentTh;
     2929        }
     2930        /*}}}1*/
     2931        /*FUNCTION Triangles::ForceBoundary{{{1*/
     2932        void Triangles::ForceBoundary() {
     2933                long int verbosity=2;
     2934                if (verbosity > 2)
     2935                 cout << "  -- ForceBoundary  nb of edge " << nbe << endl;
     2936                int k=0;
     2937                Int4  nbfe=0,nbswp=0,Nbswap=0;
     2938                for (Int4 t = 0; t < nbt; t++) 
     2939                 if (!triangles[t].det)
     2940                  k++,cerr << " det T" << t << " = " << 0 << endl;
     2941                if (k!=0) {
     2942                        cerr << " ther is  " << k << "  triangles of mes = 0 " << endl;
     2943                        MeshError(11,this);}
     2944
     2945                        TriangleAdjacent ta(0,0);
     2946                        for (Int4 i = 0; i < nbe; i++)
     2947                          {
     2948                                nbswp =  ForceEdge(edges[i][0],edges[i][1],ta);
     2949
     2950                                if ( nbswp < 0)         k++;
     2951                                else Nbswap += nbswp;
     2952                                if (nbswp) nbfe++;
     2953                                if ( nbswp < 0 && k < 5)
     2954                                  {
     2955                                        cerr << " Missing  Edge " << i << " v0 =  " << Number(edges[i][0]) << edges[i][0].r
     2956                                          <<" v1= " << Number(edges[i][1]) << edges[i][1].r << " " << edges[i].on->Cracked() << "  " << (Triangle *) ta ;
     2957                                        if(ta.t)
     2958                                          {
     2959                                                Vertex *aa = ta.EdgeVertex(0), *bb = ta.EdgeVertex(1); 
     2960                                                cerr << " crossing with  [" << Number(aa) << ", " << Number(bb) << "]\n";
     2961                                          }
     2962                                        else cerr << endl;
     2963
     2964                                  }
     2965                                if ( nbswp >=0 && edges[i].on->Cracked())
     2966                                 ta.SetCracked();
     2967                          }
     2968
     2969
     2970                        if (k!=0) {
     2971                                cerr << " they is " << k << " lost edges " << endl;
     2972                                cerr << " The boundary is crossing may be!" << endl;
     2973                                MeshError(10,this);
     2974                        }
     2975                        for (Int4 j=0;j<nbv;j++)
     2976                         Nbswap +=  vertices[j].Optim(1,0);
     2977                        if (verbosity > 3)
     2978                         cout << "     Nb of inforced edge = " << nbfe << " Nb of Swap " << Nbswap << endl;
     2979
     2980        }
     2981        /*}}}1*/
     2982        /*FUNCTION Triangles::FindSubDomain{{{1*/
     2983        void Triangles::FindSubDomain(int OutSide=0) {
     2984                long int verbosity=0;
     2985
     2986                if (verbosity >2)
     2987                  {
     2988                        if (OutSide)
     2989                         cout << "  -- Find all external sub-domain "; 
     2990                        else
     2991                         cout << "  -- Find all internal sub-domain ";
     2992                        if(verbosity>99)
     2993                          {
     2994
     2995                                for(int i=0;i<nbt;++i)
     2996                                 cout << i<< " " << triangles[i] << endl;
     2997                          }
     2998
     2999                  }
     3000                // if (verbosity > 4) cout << " OutSide=" << OutSide << endl;
     3001                short * HeapArete = new short[nbt];
     3002                Triangle  **  HeapTriangle = new Triangle*  [nbt];
     3003                Triangle *t,*t1;
     3004                Int4 k,it;
     3005
     3006                for (Int4 itt=0;itt<nbt;itt++)
     3007                 triangles[itt].link=0; // par defaut pas de couleur
     3008
     3009                Int4  NbSubDomTot =0;
     3010                for ( it=0;it<nbt;it++)  {
     3011                        if ( ! triangles[it].link  ) {
     3012                                t = triangles + it;
     3013                                NbSubDomTot++;; // new composante connexe
     3014                                Int4 i = 0; // niveau de la pile
     3015                                t->link = t ; // sd forme d'un triangle cicular link
     3016
     3017                                HeapTriangle[i] =t ;
     3018                                HeapArete[i] = 3;
     3019
     3020                                while (i >= 0) // boucle sur la pile
     3021                                  { while ( HeapArete[i]--) // boucle sur les 3 aretes
     3022                                          {
     3023                                                int na =  HeapArete[i];
     3024                                                Triangle * tc =  HeapTriangle[i]; // triangle courant
     3025                                                if( ! tc->Locked(na)) // arete non frontiere
     3026                                                  {
     3027                                                        Triangle * ta = tc->TriangleAdj(na) ; // næ triangle adjacent
     3028                                                        if (ta->link == 0 ) // non deja chainer => on enpile
     3029                                                          {
     3030                                                                i++;
     3031                                                                ta->link = t->link ;  // on chaine les triangles
     3032                                                                t->link = ta ;  // d'un meme sous domaine         
     3033                                                                HeapArete[i] = 3; // pour les 3 triangles adjacents
     3034                                                                HeapTriangle[i] = ta;
     3035                                                          }}
     3036                                          } // deplie fin de boucle sur les 3 adjacences
     3037                                        i--;
     3038                                  }         
     3039                        }     
     3040                }
     3041
     3042                // supression de tous les sous domaine infini <=>  contient le sommet NULL
     3043                it =0;
     3044                NbOutT = 0;
     3045                while (it<nbt) {
     3046                        if (triangles[it].link)
     3047                          {
     3048                                if (!( triangles[it](0) &&  triangles[it](1) &&  triangles[it](2) ))
     3049                                  {
     3050                                        // infini triangle
     3051                                        NbSubDomTot --;
     3052                                        //  cout << " triangle infini " << it << triangles[it] << endl;
     3053                                        t=&triangles[it];
     3054                                        NbOutT--;  // on fait un coup de trop.
     3055                                        while  (t){ // cout << Number(t) << " " << endl;
     3056                                                NbOutT++;
     3057                                                t1=t;
     3058                                                t=t->link;
     3059                                                t1->link=0;}//while (t)
     3060                                  }
     3061                          }   
     3062                        it++;} // end while (it<nbt)
     3063                        if (nbt == NbOutT ||  !NbSubDomTot)
     3064                          {
     3065                                cout << "\n error : " <<  NbOutT << " " << NbSubDomTot <<" " << nbt << endl;
     3066                                cerr << "Error: The boundary is not close => All triangles are outside " << endl;
     3067                                MeshError(888,this);
     3068                          }
     3069
     3070                        delete [] HeapArete;
     3071                        delete [] HeapTriangle;
     3072
     3073
     3074                        if (OutSide|| !Gh.subdomains || !Gh.NbSubDomains )
     3075                          { // No geom sub domain
     3076                                Int4 i;
     3077                                if (subdomains) delete [] subdomains;
     3078                                subdomains = new SubDomain[ NbSubDomTot];
     3079                                NbSubDomains=  NbSubDomTot;
     3080                                for ( i=0;i<NbSubDomains;i++) {
     3081                                        subdomains[i].head=NULL;
     3082                                        subdomains[i].ref=i+1;
     3083                                }
     3084                                Int4 * mark = new Int4[nbt];
     3085                                for (it=0;it<nbt;it++)
     3086                                 mark[it]=triangles[it].link ? -1 : -2;
     3087
     3088                                it =0;
     3089                                k = 0;
     3090                                while (it<nbt) {
     3091                                        if (mark[it] == -1) {
     3092                                                t1 = & triangles[it];
     3093                                                t = t1->link;
     3094                                                mark[it]=k;
     3095                                                subdomains[k].head = t1;
     3096                                                // cout << " New -- " << Number(t1) << " " << it << endl;
     3097                                                do {// cout << " k " << k << " " << Number(t) << endl;
     3098                                                        mark[Number(t)]=k;
     3099                                                        t=t->link;
     3100                                                } while (t!=t1);
     3101                                                mark[it]=k++;}
     3102                                                //    else if(mark[it] == -2 ) triangles[it].Draw(999);
     3103                                                it++;} // end white (it<nbt)
     3104                                                assert(k== NbSubDomains);
     3105                                                if(OutSide)
     3106                                                  {
     3107                                                        //  to remove all the sub domain by parity adjacents
     3108                                                        //  because in this case we have only the true boundary edge
     3109                                                        // so teh boundary is manifold
     3110                                                        Int4 nbk = NbSubDomains;
     3111                                                        while (nbk)
     3112                                                         for (it=0;it<nbt && nbk ;it++)
     3113                                                          for (int na=0;na<3 && nbk ;na++)
     3114                                                                 {
     3115                                                                  Triangle *ta = triangles[it].TriangleAdj(na);
     3116                                                                  Int4 kl = ta ? mark[Number(ta)] : -2;
     3117                                                                  Int4 kr = mark[it];
     3118                                                                  if(kr !=kl) {
     3119                                                                          //cout << kl << " " << kr << " rl "  << subdomains[kl].ref
     3120                                                                          // << " rr " << subdomains[kr].ref ;
     3121                                                                          if (kl >=0 && subdomains[kl].ref <0 && kr >=0 && subdomains[kr].ref>=0)
     3122                                                                                nbk--,subdomains[kr].ref=subdomains[kl].ref-1;
     3123                                                                          if (kr >=0 && subdomains[kr].ref <0 && kl >=0 && subdomains[kl].ref>=0)
     3124                                                                                nbk--,subdomains[kl].ref=subdomains[kr].ref-1;
     3125                                                                          if(kr<0 && kl >=0 && subdomains[kl].ref>=0)
     3126                                                                                nbk--,subdomains[kl].ref=-1;
     3127                                                                          if(kl<0 && kr >=0 && subdomains[kr].ref>=0)
     3128                                                                                nbk--,subdomains[kr].ref=-1;
     3129                                                                          //   cout << " after \t "   
     3130                                                                          //     << kl << subdomains[kl].ref << " rr " << kr
     3131                                                                          // << subdomains[kr].ref << endl;
     3132                                                                  }
     3133                                                                 }
     3134                                                        //  cout << subdomains[0].ref << subdomains[1].ref << endl;
     3135                                                        Int4  j=0;
     3136                                                        for ( i=0;i<NbSubDomains;i++)
     3137                                                         if((-subdomains[i].ref) %2) { // good
     3138                                                                 //cout << " sudom ok  = " << i << " " << subdomains[i].ref
     3139                                                                 // << " " << (-subdomains[i].ref) %2 << endl;
     3140                                                                 if(i != j)
     3141                                                                  Exchange(subdomains[i],subdomains[j]);
     3142                                                                 j++;}
     3143                                                         else
     3144                                                                { //cout << " remove sub domain " << i << endl;
     3145                                                                 t= subdomains[i].head;
     3146                                                                 while  (t){// cout << Number(t) << " " << endl;
     3147                                                                         NbOutT++;
     3148                                                                         t1=t;
     3149                                                                         t=t->link;
     3150                                                                         t1->link=0;}//while (t)
     3151                                                                }
     3152
     3153                                                        if(verbosity>4)
     3154                                                         cout << " Number of remove sub domain (OutSideMesh) =" << NbSubDomains-j << endl;
     3155                                                        NbSubDomains=j;
     3156                                                  }
     3157
     3158                                                delete []  mark;
     3159
     3160                          }
     3161                        else
     3162                          { // find the head for all sub domaine
     3163                                if (Gh.NbSubDomains != NbSubDomains && subdomains)
     3164                                 delete [] subdomains, subdomains=0;
     3165                                if (! subdomains  )
     3166                                 subdomains = new SubDomain[ Gh.NbSubDomains];
     3167                                NbSubDomains =Gh.NbSubDomains;
     3168                                if(verbosity>4)
     3169                                 cout << "     find the " << NbSubDomains << " sub domain " << endl;
     3170                                Int4 err=0;
     3171                                ReMakeTriangleContainingTheVertex();
     3172                                Int4 * mark = new Int4[nbt];
     3173                                Edge **GeometricalEdgetoEdge = MakeGeometricalEdgeToEdge();
     3174
     3175                                for (it=0;it<nbt;it++)
     3176                                 mark[it]=triangles[it].link ? -1 : -2;
     3177                                Int4 inew =0;
     3178                                for (Int4 i=0;i<NbSubDomains;i++)
     3179                                  {
     3180                                        GeometricalEdge &eg = *Gh.subdomains[i].edge;
     3181                                        subdomains[i].ref = Gh.subdomains[i].ref;
     3182                                        int ssdlab = subdomains[i].ref;
     3183                                        // by carefull is not easy to find a edge create from a GeometricalEdge
     3184                                        // see routine MakeGeometricalEdgeToEdge
     3185                                        Edge &e = *GeometricalEdgetoEdge[Gh.Number(eg)];
     3186                                        assert(&e);
     3187                                        Vertex * v0 =  e(0),*v1 = e(1);
     3188                                        Triangle *t  = v0->t;
     3189                                        int sens = Gh.subdomains[i].sens;
     3190                                        // test if ge and e is in the same sens
     3191                                        //      cout << " geom edge = " <<  Gh.Number(eg) <<" @" << &eg << " ref = " << subdomains[i].ref
     3192                                        //     << " ref edge =" << eg.ref << " sens " << sens ;
     3193                                        if (((eg[0].r-eg[1].r),(e[0].r-e[1].r))<0)
     3194                                         sens = -sens ;
     3195                                        subdomains[i].sens = sens;
     3196                                        subdomains[i].edge = &e;
     3197                                        //      cout << " sens " << sens << " in geom " << eg[0].r << eg[1].r << " in mesh  " << e[0].r << e[1].r << endl;
     3198                                        //      cout << "  v0 , v1 = " << Number(v0) << " "  << Number(v1) << endl;
     3199                                        assert(t && sens);
     3200
     3201                                        TriangleAdjacent  ta(t,EdgesVertexTriangle[v0->vint][0]);// previous edges
     3202
     3203                                        while (1)
     3204                                          {
     3205                                                assert( v0 == ta.EdgeVertex(1) );
     3206                                                //       cout << " recherche " << Number( ta.EdgeVertex(0)) << endl;
     3207                                                if (ta.EdgeVertex(0) == v1) { // ok we find the edge
     3208                                                        if (sens>0) 
     3209                                                         subdomains[i].head=t=Adj(ta);
     3210                                                        else
     3211                                                         subdomains[i].head=t=ta;
     3212                                                        //cout << "      triangle  =" << Number(t) << " = " << (*t)[0].r <<  (*t)[1].r <<  (*t)[2].r << endl;
     3213                                                        if(t<triangles || t >= triangles+nbt || t->det < 0
     3214                                                                                || t->link == 0) // Ajoute aout 200
     3215                                                          {
     3216                                                                cerr << " Error in the def of sub domain "<<i
     3217                                                                  << " form border " << NbSubDomains - i  << "/" << NbSubDomains
     3218                                                                  << ": Bad sens  " << Gh.Number(eg) <<" "<< sens <<  endl; 
     3219                                                                err++;
     3220                                                                break;}
     3221                                                                Int4 it = Number(t);
     3222                                                                if (mark[it] >=0) {
     3223                                                                        if(verbosity>10)
     3224                                                                         cerr << "     Warning: the sub domain " << i << " ref = " << subdomains[i].ref
     3225                                                                                << " is previouly defined with "  <<mark[it] << " ref = " << subdomains[mark[it]].ref
     3226                                                                                << " skip this def " << endl;
     3227                                                                        break;}
     3228                                                                        if(i != inew)
     3229                                                                         Exchange(subdomains[i],subdomains[inew]);
     3230                                                                        inew++;
     3231                                                                        Triangle *tt=t;
     3232                                                                        Int4 kkk=0;
     3233                                                                        do
     3234                                                                          {
     3235                                                                                kkk++;
     3236                                                                                assert(mark[Number(tt)]<0);
     3237                                                                                mark[Number(tt)]=i;
     3238                                                                                tt=tt->link;
     3239                                                                          } while (tt!=t);
     3240                                                                        if(verbosity>7)
     3241                                                                         cout << "     Nb de triangles dans le sous domaine " << i << " de ref " << subdomains[i].ref << " = " << kkk << endl;
     3242                                                                        break;}
     3243                                                                        ta = Previous(Adj(ta));         
     3244                                                                        if(t == (Triangle *) ta) {
     3245                                                                                err++;
     3246                                                                                cerr << " Error in the def of sub domain " << i
     3247                                                                                  << " edge=" << Gh.Number(eg) << " " << sens << endl;
     3248                                                                                break;}
     3249                                                                                //         cout << " NB of remove subdomain " << NbSubDomTot-NbSubDomains<< endl;
     3250
     3251                                          }
     3252
     3253                                  }
     3254                                if (err) MeshError(777,this);
     3255
     3256                                if (inew < NbSubDomains) {
     3257                                        if (verbosity>5)
     3258                                         cout << "     Warning: We remove " << NbSubDomains-inew << " SubDomains " << endl;
     3259                                        NbSubDomains=inew;}
     3260
     3261
     3262                                        for (it=0;it<nbt;it++)
     3263                                         if ( mark[it] ==-1 )
     3264                                          NbOutT++,triangles[it].link =0;
     3265                                        delete [] GeometricalEdgetoEdge;
     3266                                        delete [] mark;
     3267
     3268                          }
     3269                        NbOutT=0;
     3270                        for (it=0;it<nbt;it++)
     3271                         if(!triangles[it].link)  NbOutT++;
     3272                        if (verbosity> 4)
     3273                         cout << "    " ;
     3274                        if (verbosity> 2)
     3275                         cout << " Nb of Sub borned Domain  = " <<  NbSubDomTot << " NbOutTriangles = " << NbOutT <<endl;
     3276
     3277
     3278        }
     3279        /*}}}1*/
     3280        /*FUNCTION Triangles::ReNumberingVertex{{{1*/
     3281        void Triangles::ReNumberingVertex(Int4 * renu) {
     3282                // warning be carfull because pointeur
     3283                // from on mesh to over mesh
     3284                //  --  so do ReNumbering a the beginning
     3285                Vertex * ve = vertices+nbv;
     3286                Int4 it,ie,i;
     3287
     3288                for ( it=0;it<nbt;it++)
     3289                 triangles[it].ReNumbering(vertices,ve,renu);
     3290
     3291                for ( ie=0;ie<nbe;ie++)
     3292                 edges[ie].ReNumbering(vertices,ve,renu);
     3293
     3294                for (i=0;i< NbVerticesOnGeomVertex;i++)
     3295                  {
     3296                        Vertex *v = VerticesOnGeomVertex[i].mv;
     3297                        if (v>=vertices && v < ve)
     3298                         VerticesOnGeomVertex[i].mv=vertices+renu[Number(v)];
     3299                  }
     3300
     3301                for (i=0;i< NbVerticesOnGeomEdge;i++)
     3302                  {
     3303                        Vertex *v =VerticesOnGeomEdge[i].mv;
     3304                        if (v>=vertices && v < ve)
     3305                         VerticesOnGeomEdge[i].mv=vertices+renu[Number(v)];
     3306                  }
     3307
     3308                for (i=0;i< NbVertexOnBThVertex;i++)
     3309                  {
     3310                        Vertex *v=VertexOnBThVertex[i].v;
     3311                        if (v>=vertices && v < ve)
     3312                         VertexOnBThVertex[i].v=vertices+renu[Number(v)];
     3313                  }
     3314
     3315                for (i=0;i< NbVertexOnBThEdge;i++)
     3316                  {
     3317                        Vertex *v=VertexOnBThEdge[i].v;
     3318                        if (v>=vertices && v < ve)
     3319                         VertexOnBThEdge[i].v=vertices+renu[Number(v)];
     3320                  }
     3321
     3322                // move the Vertices without a copy of the array
     3323                // be carefull not trivial code
     3324                Int4 j;
     3325                for ( it=0;it<nbv;it++) // for all sub cycles of the permutation renu
     3326                 if (renu[it] >= 0) // a new sub cycle
     3327                        {
     3328                         i=it;
     3329                         Vertex ti=vertices[i],tj;
     3330                         while ( (j=renu[i]) >= 0)
     3331                                { // i is old, and j is new
     3332                                 renu[i] = -1-renu[i]; // mark
     3333                                 tj = vertices[j]; // save new
     3334                                 vertices[j]= ti; // new <- old
     3335                                 i=j;     // next
     3336                                 ti = tj;
     3337                                } 
     3338                        }
     3339                if (quadtree)
     3340                  {  delete quadtree;
     3341                        quadtree = new QuadTree(this);
     3342                  }
     3343                for ( it=0;it<nbv;it++)
     3344                 renu[i]= -renu[i]-1;
     3345
     3346        }
     3347        /*}}}1*/
     3348        /*FUNCTION Triangles::ReNumberingTheTriangleBySubDomain{{{1*/
     3349        void Triangles::ReNumberingTheTriangleBySubDomain(bool justcompress) {
     3350                long int verbosity=0;
     3351                Int4 *renu= new Int4[nbt];
     3352                register Triangle *t0,*t,*te=triangles+nbt;
     3353                register Int4 k=0,it,i,j;
     3354
     3355                for ( it=0;it<nbt;it++)
     3356                 renu[it]=-1; // outside triangle
     3357                for ( i=0;i<NbSubDomains;i++)
     3358                  {
     3359                        t=t0=subdomains[i].head;
     3360                        assert(t0); // no empty sub domain
     3361                        do {
     3362                                Int4 kt = Number(t);
     3363                                assert(kt>=0 && kt < nbt );
     3364                                assert(renu[kt]==-1);
     3365                                renu[kt]=k++;
     3366                        }
     3367                        while (t0 != (t=t->link));
     3368                  }
     3369                if (verbosity>9)
     3370                 cout << " number of inside triangles " << k << " nbt = " << nbt << endl;
     3371                // take is same numbering if possible   
     3372                if(justcompress)
     3373                 for ( k=0,it=0;it<nbt;it++)
     3374                  if(renu[it] >=0 )
     3375                        renu[it]=k++;
     3376
     3377                // put the outside triangles at the end
     3378                for ( it=0;it<nbt;it++)
     3379                 if (renu[it]==-1)
     3380                  renu[it]=k++;
     3381
     3382                assert(k == nbt);
     3383                // do the change on all the pointeur
     3384                for ( it=0;it<nbt;it++)
     3385                 triangles[it].ReNumbering(triangles,te,renu);
     3386
     3387                for ( i=0;i<NbSubDomains;i++)
     3388                 subdomains[i].head=triangles+renu[Number(subdomains[i].head)];
     3389
     3390                // move the Triangles  without a copy of the array
     3391                // be carefull not trivial code
     3392                for ( it=0;it<nbt;it++) // for all sub cycles of the permutation renu
     3393                 if (renu[it] >= 0) // a new sub cycle
     3394                        {
     3395                         i=it;
     3396                         Triangle ti=triangles[i],tj;
     3397                         while ( (j=renu[i]) >= 0)
     3398                                { // i is old, and j is new
     3399                                 renu[i] = -1; // mark
     3400                                 tj = triangles[j]; // save new
     3401                                 triangles[j]= ti; // new <- old
     3402                                 i=j;     // next
     3403                                 ti = tj;
     3404                                } 
     3405                        }
     3406                delete [] renu;
     3407                nt = nbt - NbOutT;
     3408
     3409        }
     3410        /*}}}1*/
     3411        /*FUNCTION Triangles::ConsRefTriangle{{{1*/
     3412        Int4  Triangles::ConsRefTriangle(Int4 *reft) const {
     3413                long int verbosity=0;
     3414                assert(reft);
     3415                register Triangle *t0,*t;
     3416                register Int4 k=0, num;   
     3417                for (Int4 it=0;it<nbt;it++)
     3418                 reft[it]=-1; // outside triangle
     3419                for (Int4 i=0;i<NbSubDomains;i++)
     3420                  {
     3421                        t=t0=subdomains[i].head;
     3422                        assert(t0); // no empty sub domain
     3423                        // register Int4 color=i+1;// because the color 0 is outside triangle
     3424                        do { k++;
     3425                                num = Number(t);
     3426                                assert(num>=0 &&num < nbt);
     3427                                reft[num]=i;
     3428                                //  cout << Number(t0) << " " <<Number(t)<< " "  << i << endl;
     3429                        }
     3430                        while (t0 != (t=t->link));
     3431                  }
     3432                //  NbOutT = nbt - k;
     3433                if (verbosity>5)
     3434                 cout << " Nb of Sub Domain =" << NbSubDomains  << " Nb of In Triangles " << k
     3435                        << " Nbt = " << nbt << " Out Triangles = " << nbt - k <<  endl;
     3436
     3437                return k;   
     3438
     3439        }
     3440        /*}}}1*/
     3441        /*FUNCTION Triangles::GeomToTriangles1{{{1*/
     3442        void Triangles::GeomToTriangles1(Int4 inbvx,int KeepBackVertices) {
     3443                Gh.NbRef++;// add a ref to Gh
     3444
     3445
     3446                /*************************************************************************
     3447                // methode in 2 step
     3448                // 1 - compute the number of new edge to allocate
     3449                // 2 - construct the edge
     3450remark:
     3451in this part we suppose to have a background mesh with the same
     3452geometry
     3453
     3454To construct the discretisation of the new mesh we have to
     3455rediscretize the boundary of background Mesh
     3456because we have only the pointeur from the background mesh to the geometry.
     3457We need the abcisse of the background mesh vertices on geometry
     3458so a vertex is
     34590 on GeometricalVertex ;
     34601 on GeometricalEdge + abcisse
     34612 internal
     3462
     3463                 *************************************************************************/
     3464                assert(&BTh.Gh == &Gh);
     3465
     3466                long int verbosity=0;
     3467                BTh.NbRef++; // add a ref to BackGround Mesh
     3468                PreInit(inbvx);
     3469                BTh.SetVertexFieldOn();
     3470                int * bcurve = new int[Gh.NbOfCurves]; //
     3471
     3472                // we have 2 ways to make the loop
     3473                // 1) on the geometry
     3474                // 2) on the background mesh
     3475                //  if you do the loop on geometry, we don't have the pointeur on background,
     3476                //  and if you do the loop in background we have the pointeur on geometry
     3477                // so do the walk on  background
     3478                //  Int4 NbVerticesOnGeomVertex;
     3479                //  VertexOnGeom * VerticesOnGeomVertex; 
     3480                //  Int4 NbVerticesOnGeomEdge;
     3481                //  VertexOnGeom * VerticesOnGeomEdge;
     3482
     3483
     3484                NbVerticesOnGeomVertex=0;
     3485                NbVerticesOnGeomEdge=0;
     3486                //1 copy of the  Required vertex
     3487                int i;
     3488                for ( i=0;i<Gh.nbv;i++)
     3489                 if (Gh[i].Required()) NbVerticesOnGeomVertex++;
     3490
     3491                VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];
     3492                VertexOnBThVertex = new VertexOnVertex[NbVerticesOnGeomVertex];
     3493                //
     3494                if( NbVerticesOnGeomVertex >= nbvx)
     3495                  {
     3496                        cerr << " Too much vertices on geometry " << NbVerticesOnGeomVertex << " >= " << nbvx << endl;
     3497                        MeshError(1,this);
     3498                  }
     3499                assert(vertices);
     3500                for (i=0;i<Gh.nbv;i++)
     3501                 if (Gh[i].Required()) {//Gh  vertices Required
     3502                         vertices[nbv] =  Gh[i];
     3503                         vertices[nbv].i = I2(0,0);
     3504                         Gh[i].to = vertices + nbv;// save Geom -> Th
     3505                         VerticesOnGeomVertex[nbv]= VertexOnGeom(vertices[nbv],Gh[i]);
     3506                         // cout << "--------- "  <<Number(Gh[i].to) << " " << Gh[i].to << " " << i << endl;
     3507                         nbv++;}
     3508                 else Gh[i].to=0;
     3509                //
     3510                for (i=0;i<BTh.NbVerticesOnGeomVertex;i++)
     3511                  {
     3512                        VertexOnGeom & vog = BTh.VerticesOnGeomVertex[i];
     3513                        if (vog.IsRequiredVertex()) {
     3514                                GeometricalVertex * gv = vog;
     3515                                Vertex *bv = vog;
     3516                                assert(gv->to);// use of Geom -> Th
     3517                                VertexOnBThVertex[NbVertexOnBThVertex++] = VertexOnVertex(gv->to,bv);
     3518                                gv->to->m = bv->m; // for taking the metrix of the background mesh
     3519                                ;}
     3520                  }
     3521                assert(NbVertexOnBThVertex == NbVerticesOnGeomVertex);
     3522                // new stuff FH with curve
     3523                //  find the begin of the curve in BTh
     3524                  {
     3525                        Gh.UnMarkEdges();       
     3526                        int bfind=0;
     3527                        /*
     3528                                cout << " nb curves = " << Gh.NbOfCurves << endl;
     3529                                for(int i=0;i<Gh.NbOfCurves ;i++)
     3530                                {
     3531                                cout << " Curve " << i << " begin e=" << Gh.Number(Gh.curves[i].be) << " k=" << Gh.curves[i].kb
     3532                                << "  end e= " << Gh.Number(Gh.curves[i].ee) << " k=" << Gh.curves[i].ke << endl;
     3533                                }*/
     3534                        for (int i=0;i<Gh.NbOfCurves;i++)
     3535                          {
     3536                                bcurve[i]=-1;
     3537                          }
     3538
     3539                        for (int iedge=0;iedge<BTh.nbe;iedge++)
     3540                          {     
     3541                                Edge & ei = BTh.edges[iedge];
     3542                                for(int je=0;je<2;je++) // for the 2 extremites
     3543                                 if (!ei.on->Mark() && ei[je].on->IsRequiredVertex() )
     3544                                        {
     3545                                         // a begin of curve
     3546                                         int nc = ei.on->CurveNumber;
     3547
     3548                                         //cout << "curve " <<  nc << " v " << Gh.Number((GeometricalVertex *) *ei[je].on) << " "
     3549                                         //     << " e "  << " " << Gh.Number(ei.on) << " vc " << Gh.Number((*Gh.curves[nc].be)[Gh.curves[nc].kb]) << endl;
     3550                                         if(
     3551                                                                 ei.on==Gh.curves[nc].be    &&
     3552                                                                 (GeometricalVertex *) *ei[je].on == &(*Gh.curves[nc].be)[Gh.curves[nc].kb] //  same extremity
     3553                                                )     
     3554                                                {
     3555                                                 // cout << " find " << endl;
     3556                                                 bcurve[nc]=iedge*2+je;
     3557                                                 bfind++;       
     3558                                                }     
     3559                                        }
     3560                          }
     3561                        assert( bfind==Gh.NbOfCurves);
     3562                  }         
     3563                // method in 2 + 1 step
     3564                //  0.0) compute the length and the number of vertex to do allocation
     3565                //  1.0)  recompute the length
     3566                //  1.1)   compute the  vertex
     3567                Int4 nbex=0,NbVerticesOnGeomEdgex=0;
     3568                for (int step=0; step <2;step++)
     3569                  {
     3570                        Int4 NbOfNewPoints=0;
     3571                        Int4 NbOfNewEdge=0;
     3572                        Int4 iedge;
     3573                        Gh.UnMarkEdges();       
     3574                        /*   add Curve loop  FH   
     3575                        // find a starting back groud edges to walk
     3576                        for (iedge=0;iedge<BTh.nbe;iedge++) {     
     3577                        Edge & ei = BTh.edges[iedge];
     3578                        for(int jedge=0;jedge<2;jedge++) // for the 2 extremites
     3579                        if (!ei.on->Mark() && ei[jedge].on->IsRequiredVertex() )
     3580                        {
     3581                        */ 
     3582                        // new code FH 2004
     3583                        Real8 L=0;
     3584                        for (int icurve=0;icurve<Gh.NbOfCurves;icurve++)
     3585                          {
     3586                                iedge=bcurve[icurve]/2;
     3587                                int jedge=bcurve[icurve]%2;
     3588                                if( ! Gh.curves[icurve].master) continue; // we skip all equi curve
     3589                                Edge & ei = BTh.edges[iedge];
     3590                                // warning: ei.on->Mark() can be change in
     3591                                // loop for(jedge=0;jedge<2;jedge++)
     3592                                // new curve 
     3593                                // good the find a starting edge
     3594                                Real8 Lstep=0,Lcurve=0;// step between two points   (phase==1)
     3595                                Int4 NbCreatePointOnCurve=0;// Nb of new points on curve     (phase==1)
     3596
     3597
     3598                                //    cout.precision(16);
     3599                                for(int phase=0;phase<=step;phase++)
     3600                                  {
     3601
     3602                                        for(Curve * curve= Gh.curves+icurve;curve;curve= curve->next)
     3603                                          {
     3604
     3605                                                int icurveequi= Gh.Number(curve);
     3606
     3607                                                if( phase == 0 &&  icurveequi != icurve)  continue;
     3608
     3609                                                int k0=jedge,k1;
     3610                                                Edge * pe=  BTh.edges+iedge;
     3611                                                //GeometricalEdge *ong = ei.on;
     3612                                                int iedgeequi=bcurve[icurveequi]/2;
     3613                                                int jedgeequi=bcurve[icurveequi]%2;
     3614
     3615                                                int k0equi=jedgeequi,k1equi;             
     3616                                                Edge * peequi= BTh.edges+iedgeequi;
     3617                                                GeometricalEdge *ongequi = peequi->on;
     3618
     3619                                                Real8 sNew=Lstep;// abcisse of the new points (phase==1)
     3620                                                L=0;// length of the curve
     3621                                                Int4 i=0;// index of new points on the curve
     3622                                                register GeometricalVertex * GA0 = *(*peequi)[k0equi].on;
     3623                                                Vertex *A0;
     3624                                                A0 = GA0->to;  // the vertex in new mesh
     3625                                                Vertex *A1;
     3626                                                VertexOnGeom *GA1;
     3627                                                Edge * PreviousNewEdge = 0;
     3628                                                //  cout << "  --------------New Curve phase " << phase
     3629                                                //       << "---------- A0=" << *A0 << ei[k0]  <<endl;
     3630                                                assert (A0-vertices>=0 && A0-vertices <nbv);
     3631                                                if(ongequi->Required() )
     3632                                                  {
     3633                                                        GeometricalVertex *GA1 = *(*peequi)[1-k0equi].on;
     3634                                                        A1 = GA1->to;  //
     3635                                                  }       
     3636                                                else
     3637                                                 for(;;)
     3638                                                        {
     3639                                                         //   assert(pe && BTh.Number(pe)>=0 && BTh.Number(pe)<=BTh.nbe);
     3640                                                         Edge &ee=*pe;
     3641                                                         Edge &eeequi=*peequi;
     3642                                                         k1 = 1-k0; // next vertex of the edge
     3643                                                         k1equi= 1 - k0equi;
     3644
     3645                                                         assert(pe  && ee.on);
     3646                                                         ee.on->SetMark();
     3647                                                         Vertex & v0=ee[0], & v1=ee[1];
     3648                                                         R2 AB= (R2) v1 - (R2) v0;
     3649                                                         Real8 L0=L,LAB;
     3650                                                         LAB =  LengthInterpole(v0.m,v1.m,AB);
     3651                                                         L+= LAB;   
     3652                                                         if (phase) {// computation of the new points
     3653                                                                 while ((i!=NbCreatePointOnCurve) && sNew <= L) {
     3654                                                                         //    cout  << " L0= " << L0 << " L " << L << " sN="
     3655                                                                         //         << sNew << " LAB=" << LAB << " NBPC =" <<NbCreatePointOnCurve<< " i " << i  << endl;
     3656                                                                         assert (sNew >= L0);
     3657                                                                         assert(LAB);
     3658
     3659
     3660                                                                         assert(vertices && nbv<nbvx);
     3661                                                                         assert(edges && nbe < nbex);
     3662                                                                         assert(VerticesOnGeomEdge && NbVerticesOnGeomEdge < NbVerticesOnGeomEdgex);
     3663                                                                         // new vertex on edge
     3664                                                                         A1=vertices+nbv++;
     3665                                                                         GA1=VerticesOnGeomEdge+NbVerticesOnGeomEdge;
     3666                                                                         Edge *e = edges + nbe++;
     3667                                                                         Real8 se= (sNew-L0)/LAB;
     3668                                                                         assert(se>=0 && se < 1.000000001);
     3669                                                                         se =  abscisseInterpole(v0.m,v1.m,AB,se,1);
     3670                                                                         assert(se>=0 && se <= 1);
     3671                                                                         //((k1==1) != (k1==k1equi))
     3672                                                                         se = k1 ? se : 1. - se;
     3673                                                                         se = k1==k1equi ? se : 1. - se;
     3674                                                                         VertexOnBThEdge[NbVerticesOnGeomEdge++] = VertexOnEdge(A1,&eeequi,se); // save
     3675                                                                         ongequi = Gh.ProjectOnCurve(eeequi,se,*A1,*GA1);
     3676                                                                         A1->ReferenceNumber = eeequi.ref;
     3677                                                                         A1->DirOfSearch =NoDirOfSearch;
     3678                                                                         //cout << icurveequi << " " << i << " " <<  *A1 << endl;
     3679                                                                         e->on = ongequi;
     3680                                                                         e->v[0]=  A0;
     3681                                                                         e->v[1]=  A1;
     3682                                                                         if(verbosity>99)
     3683                                                                          cout << i << "+ New P "<< nbv-1 << " "  <<sNew<< " L0=" << L0
     3684                                                                                 << " AB=" << LAB << " s=" << (sNew-L0)/LAB << " se= " 
     3685                                                                                 << se <<" B edge " << BTh.Number(ee) << " signe = " << k1 <<" " << A1->r <<endl;
     3686
     3687                                                                         e->ref = eeequi.ref;
     3688                                                                         e->adj[0]=PreviousNewEdge;
     3689
     3690                                                                         if (PreviousNewEdge)
     3691                                                                          PreviousNewEdge->adj[1] =  e;
     3692                                                                         PreviousNewEdge = e;
     3693                                                                         A0=A1;
     3694                                                                         sNew += Lstep;
     3695                                                                         //   cout << " sNew = " << sNew << " L = " << L
     3696                                                                         //        << "  ------" <<NbCreatePointOnCurve << " " << i <<  endl;
     3697                                                                         if (++i== NbCreatePointOnCurve) break;
     3698                                                                 }
     3699
     3700                                                         }               
     3701                                                         assert(ee.on->CurveNumber==ei.on->CurveNumber);
     3702                                                         if(verbosity>98) cout <<  BTh.Number(ee) << " " << " on=" << *ee[k1].on << " "<< ee[k1].on->IsRequiredVertex() <<  endl;
     3703                                                         if ( ee[k1].on->IsRequiredVertex()) {
     3704                                                                 assert(eeequi[k1equi].on->IsRequiredVertex());
     3705                                                                 register GeometricalVertex * GA1 = *eeequi[k1equi].on;
     3706                                                                 A1=GA1->to;// the vertex in new mesh
     3707                                                                 assert (A1-vertices>=0 && A1-vertices <nbv);
     3708                                                                 break;}
     3709                                                                 if (!ee.adj[k1])
     3710                                                                        {cerr << "Error adj edge " << BTh.Number(ee) << ", nbe = "  << nbe
     3711                                                                         << " Gh.vertices " << Gh.vertices
     3712                                                                                << " k1 = " << k1 << " on=" << *ee[k1].on << endl;
     3713                                                                         cerr << ee[k1].on->gv-Gh.vertices << endl;
     3714                                                                        }
     3715                                                                 pe = ee.adj[k1]; // next edge
     3716                                                                 k0 = pe->Intersection(ee);
     3717                                                                 peequi= eeequi.adj[k1equi];  // next edge
     3718                                                                 k0equi=peequi->Intersection(eeequi);           
     3719                                                        }// for(;;) end of the curve
     3720
     3721
     3722                                                if (phase) // construction of the last edge
     3723                                                  {
     3724                                                        Edge *e = edges + nbe++;
     3725                                                        if (verbosity>10)
     3726                                                         cout << " Fin curve A1" << *A1 << " " << icurve << " <=> " << icurveequi <<"-----" <<
     3727                                                                NbCreatePointOnCurve << " == " <<i<<endl;
     3728                                                        e->on  = ongequi;
     3729                                                        e->v[0]=  A0;
     3730                                                        e->v[1]=        A1;
     3731                                                        e->ref = peequi->ref;
     3732                                                        e->adj[0]=PreviousNewEdge;
     3733                                                        e->adj[1]=0;
     3734                                                        if (PreviousNewEdge)
     3735                                                         PreviousNewEdge->adj[1] =  e;
     3736                                                        PreviousNewEdge = e;
     3737
     3738                                                        assert(i==NbCreatePointOnCurve);
     3739
     3740                                                  }
     3741                                          } //  end loop on equi curve
     3742
     3743                                        if (!phase)  { //
     3744                                                Int4 NbSegOnCurve = Max((Int4)(L+0.5),(Int4) 1);// nb of seg
     3745                                                Lstep = L/NbSegOnCurve;
     3746                                                Lcurve = L;
     3747                                                NbCreatePointOnCurve = NbSegOnCurve-1;
     3748
     3749                                                for(Curve * curve= Gh.curves+icurve;curve;curve= curve->next)
     3750                                                  {
     3751                                                        NbOfNewEdge += NbSegOnCurve;
     3752                                                        NbOfNewPoints += NbCreatePointOnCurve;
     3753                                                  }
     3754                                                if(verbosity>5)
     3755                                                 cout << icurve << " NbSegOnCurve = " <<  NbSegOnCurve << " Lstep="
     3756                                                        << Lstep <<" " << NbOfNewPoints<< " NBPC= " << NbCreatePointOnCurve <<endl;
     3757                                                // do'nt
     3758                                                //  if(NbCreatePointOnCurve<1) break;
     3759                                        }
     3760                                  }//for(phase;;)
     3761                                /*  modif FH add Curve class             
     3762                                         }}//for (iedge=0;iedge<BTh.nbe;iedge++)
     3763                                         */
     3764                                // new code Curve class         
     3765                  } //  end of curve loop
     3766                // end new code     
     3767                // do the allocation
     3768                if(step==0)
     3769                  {
     3770                        //if(!NbOfNewPoints) break;// nothing ????? bug
     3771                        if(nbv+NbOfNewPoints > nbvx)
     3772                          {
     3773                                cerr << " Too much vertices on geometry " << nbv+NbOfNewPoints  << " >= " << nbvx << endl;
     3774                                MeshError(3,this);
     3775                          }
     3776                        //cout << " NbOfNewEdge" << NbOfNewEdge << " NbOfNewPoints " << NbOfNewPoints << endl;
     3777                        edges = new Edge[NbOfNewEdge];
     3778                        nbex = NbOfNewEdge;
     3779                        if(NbOfNewPoints) { //
     3780                                VerticesOnGeomEdge = new VertexOnGeom[NbOfNewPoints];
     3781                                NbVertexOnBThEdge =NbOfNewPoints;
     3782                                VertexOnBThEdge = new  VertexOnEdge[NbOfNewPoints];
     3783                                NbVerticesOnGeomEdgex = NbOfNewPoints; }
     3784                                NbOfNewPoints =0;
     3785                                NbOfNewEdge = 0;
     3786                  }
     3787                  } // for(step;;)
     3788                assert(nbe);
     3789
     3790                delete [] bcurve;
     3791
     3792
     3793                Insert();
     3794                ForceBoundary();
     3795                FindSubDomain();
     3796
     3797                NewPoints(BTh,KeepBackVertices) ;
     3798                CurrentTh = 0;
     3799        }
     3800        /*}}}1*/
     3801        /*FUNCTION Triangles::GeomToTriangles0{{{1*/
     3802        void Triangles::GeomToTriangles0(Int4 inbvx) {
     3803                Gh.NbRef++;// add a ref to GH
     3804
     3805
     3806                Int4 i,NbOfCurves=0,NbNewPoints,NbEdgeCurve;
     3807                Real8 lcurve, lstep,s;
     3808
     3809                R2 AB;
     3810                GeometricalVertex *a,*b;
     3811                Vertex *va,*vb;
     3812                GeometricalEdge * e;
     3813                PreInit(inbvx);
     3814                int  background = &BTh != this;
     3815                //  int  SameGeom = background && (&BTh.Gh == &Gh);
     3816                nbv = 0;
     3817                NbVerticesOnGeomVertex=0;
     3818                NbVerticesOnGeomEdge=0;
     3819                for (i=0;i<Gh.nbv;i++)
     3820                 if (Gh[i].Required() && Gh[i].IsThe() ) NbVerticesOnGeomVertex++;
     3821                VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex]; 
     3822                //
     3823                if( NbVerticesOnGeomVertex >= nbvx)
     3824                  {
     3825                        cerr << " Too much vertices on geometry " << NbVerticesOnGeomVertex << " >= " << nbvx << endl;
     3826                        MeshError(1,this);
     3827                  }
     3828                for (i=0;i<Gh.nbv;i++)
     3829                 if (Gh[i].Required()&& Gh[i].IsThe()  ) {//Gh  vertices Required
     3830                         if (nbv < nbvx)
     3831                          vertices[nbv] = Gh[i];
     3832                         Gh[i].to = vertices + nbv;// save Geom -> Th
     3833                         VerticesOnGeomVertex[nbv]= VertexOnGeom(*Gh[i].to,Gh[i]);
     3834                         //  cout << "--------- "  <<Number(Gh[i].to) << " " << Gh[i].to << " " << i << endl;
     3835                         nbv++;
     3836                 }
     3837                //  assert( Gh.nbv < nbvx);
     3838
     3839                // Method in 2 step:  0 and 1
     3840                // 1) compute de nb of edge
     3841                // 2) construct the edge   
     3842                // generation of the curves
     3843                assert(! edges);
     3844                // 2 step
     3845                // --step=0 to compute the number of edges + alloc at end
     3846                // --step=1 to construct the edges
     3847                for (int step=0;step<2;step++)
     3848                  {//  for (int step=0;step<2;step++)
     3849                        Int4 nbex = 0;
     3850                        nbe = 0;
     3851                        Int4 NbVerticesOnGeomEdge0=NbVerticesOnGeomEdge;
     3852                        //  cout <<  "  -------------- step =" << step << endl;
     3853                        Gh.UnMarkEdges();       
     3854                        NbOfCurves = 0;
     3855                        for (i=0;i<Gh.nbe;i++) {
     3856                                GeometricalEdge & ei = Gh.edges[i];   
     3857                                if (!ei.Dup()) // a good curve (not dup )
     3858                                 for(int j=0;j<2;j++)
     3859                                  if (!ei.Mark() && ei[j].Required()) {
     3860                                          // warning ei.Mark() can be change in loop for(j=0;j<2;j++)
     3861                                          //  cout << " New curve = " << NbOfCurves << endl;
     3862                                          Int4 nbvend  =0;
     3863
     3864                                          Edge * PreviousNewEdge=0;
     3865
     3866                                          lstep = -1;//to do not create points
     3867                                          if(ei.Required())
     3868                                                 {
     3869                                                  if (j==0)
     3870                                                        if(step==0)
     3871                                                         nbe++;
     3872                                                        else
     3873                                                          {
     3874                                                                e = & ei;
     3875                                                                a=ei(0)->The();
     3876                                                                b=ei(1)->The();
     3877                                                                assert(edges);
     3878                                                                edges[nbe].v[0]=a->to;
     3879                                                                edges[nbe].v[1]=b->to;;
     3880                                                                edges[nbe].ref = e->ref;
     3881                                                                edges[nbe].on = e;
     3882                                                                edges[nbe].adj[0] = 0;
     3883                                                                edges[nbe].adj[1] = 0;
     3884                                                                nbe++;}
     3885                                                 }
     3886                                          else
     3887                                                 { // on curve ------
     3888                                                  for ( int kstep=0;kstep<= step;kstep++)
     3889                                                         { // begin  for ( int kstep=0;kstep<= step;kstep++)
     3890                                                          // if 2nd step where 2 step
     3891                                                          // -- 1 compute le length of the curve
     3892                                                          // -- create the points and edge
     3893                                                          PreviousNewEdge=0;
     3894                                                          NbNewPoints=0;
     3895                                                          NbEdgeCurve=0;
     3896                                                          assert(nbvend < nbvx);
     3897                                                          lcurve =0;
     3898                                                          s = lstep;
     3899                                                          int k=j;
     3900                                                          e = & ei;
     3901                                                          a=ei(k)->The();
     3902                                                          va = a->to;
     3903                                                          e->SetMark();
     3904                                                          //  cout << " New curve " ;
     3905
     3906                                                          // if SameGeo  We have go in the background geometry
     3907                                                          // to find the discretisation of the curve
     3908
     3909                                                          for(;;)
     3910                                                                 {
     3911                                                                  k = 1-k;
     3912                                                                  b= (*e)(k)->The();
     3913                                                                  AB = b->r - a->r;
     3914                                                                  Metric MA = background ? BTh.MetricAt(a->r) :a->m ;
     3915                                                                  Metric MB =  background ? BTh.MetricAt(b->r) :b->m ;
     3916                                                                  Real8 ledge = (MA(AB) + MB(AB))/2;
     3917                                                                  //
     3918                                                                  const int MaxSubEdge = 10;
     3919                                                                  int NbSubEdge = 1;
     3920                                                                  Real8 lSubEdge[MaxSubEdge];
     3921                                                                  R2 A,B;
     3922                                                                  if (ledge < 1.5)
     3923                                                                        lSubEdge[0] = ledge;
     3924                                                                  else {
     3925                                                                          NbSubEdge = Min( MaxSubEdge, (int) (ledge +0.5));
     3926                                                                          A= a->r;
     3927                                                                          Metric MAs =MA,MBs;
     3928                                                                          // cout << " lSubEdge old=" << ledge
     3929                                                                          //      << " new " << A << MA << endl;
     3930                                                                          ledge = 0;
     3931                                                                          Real8 x =0, xstep= 1. /  NbSubEdge;
     3932                                                                          for (int kk=0; kk < NbSubEdge; kk++,A=B,MAs=MBs ) {
     3933                                                                                  x += xstep;
     3934                                                                                  B =  e->F(k ? x : 1-x);
     3935                                                                                  MBs= background ? BTh.MetricAt(B) :Metric(1-x, MA, x ,MB);
     3936                                                                                  AB = A-B;
     3937                                                                                  lSubEdge[kk]= (ledge += (MAs(AB)+MBs(AB))/2);
     3938                                                                                  // cout << "     " << lSubEdge[kk] << " x " << x 
     3939                                                                                  //      << " " << A << B << MA << MB<< endl ;
     3940                                                                          }
     3941                                                                          //  cout << endl;
     3942                                                                  }
     3943
     3944                                                                  Real8 lcurveb = lcurve+ ledge ;
     3945                                                                  while (lcurve<=s && s <= lcurveb && nbv < nbvend)
     3946                                                                         {
     3947                                                                          // New points
     3948
     3949                                                                          // Real8 aa=(lcurveb-s)/ledge;
     3950                                                                          // Real8 bb=(s-lcurve)/ledge;
     3951
     3952                                                                          Real8 ss = s-lcurve;
     3953                                                                          // 1) find the SubEdge containing ss by dichotomie
     3954                                                                          int kk0=-1,kk1=NbSubEdge-1,kkk;
     3955                                                                          Real8 ll0=0,ll1=ledge,llk;
     3956                                                                          while (kk1-kk0>1)
     3957                                                                                 {
     3958                                                                                  if (ss < (llk=lSubEdge[kkk=(kk0+kk1)/2]))
     3959                                                                                        kk1=kkk,ll1=llk;
     3960                                                                                  else
     3961                                                                                        kk0=kkk,ll0=llk;}
     3962                                                                                  assert(kk1 != kk0);
     3963
     3964                                                                                  Real8 sbb = (ss-ll0  )/(ll1-ll0);
     3965                                                                                  Real8 bb = (kk1+sbb)/NbSubEdge, aa=1-bb;
     3966
     3967                                                                                  // new vertex on edge
     3968                                                                                  vb = &vertices[nbv++];
     3969                                                                                  vb->m = Metric(aa,a->m,bb,b->m);
     3970                                                                                  vb->ReferenceNumber = e->ref;
     3971                                                                                  vb->DirOfSearch =NoDirOfSearch;
     3972                                                                                  Real8 abcisse = k ? bb : aa;
     3973                                                                                  vb->r =  e->F( abcisse );
     3974                                                                                  VerticesOnGeomEdge[NbVerticesOnGeomEdge++]= VertexOnGeom(*vb,*e,abcisse);       
     3975
     3976                                                                                  // to take in account the sens of the edge
     3977
     3978                                                                                  s += lstep;
     3979                                                                                  edges[nbe].v[0]=va;
     3980                                                                                  edges[nbe].v[1]=vb;
     3981                                                                                  edges[nbe].ref = e->ref;
     3982                                                                                  edges[nbe].on = e;
     3983                                                                                  edges[nbe].adj[0] = PreviousNewEdge;
     3984                                                                                  if(PreviousNewEdge)
     3985                                                                                        PreviousNewEdge->adj[1] = &edges[nbe];
     3986                                                                                  PreviousNewEdge = edges + nbe;
     3987                                                                                  nbe++;
     3988                                                                                  va = vb;
     3989                                                                         }
     3990                                                                  lcurve = lcurveb;
     3991                                                                  e->SetMark();
     3992                                                                  // cout << e-Gh.edges << ", " << k << " "
     3993                                                                  //      <<(*e)[k].r <<" " <<(*e)[1-k].r <<" "
     3994                                                                  //      << lcurve<< ";; " ;                         
     3995                                                                  a=b;
     3996                                                                  if (b->Required() ) break;
     3997                                                                  int kprev=k;
     3998                                                                  k = e->SensAdj[kprev];// next vertices
     3999                                                                  e = e->Adj[kprev];
     4000                                                                  assert(e);
     4001                                                                 }// for(;;)
     4002                                                          vb = b->to;
     4003                                                          //            cout << endl;
     4004                                                          NbEdgeCurve = Max((Int4) (lcurve +0.5), (Int4) 1);
     4005                                                          NbNewPoints = NbEdgeCurve-1;
     4006                                                          if(!kstep)
     4007                                                                 { NbVerticesOnGeomEdge0 += NbNewPoints;
     4008                                                                  NbOfCurves++;}
     4009
     4010                                                                  nbvend=nbv+NbNewPoints;
     4011
     4012                                                                  lstep = lcurve / NbEdgeCurve;
     4013                                                                  //   cout <<"lstep " << lstep << " lcurve "
     4014                                                                  //    << lcurve << " NbEdgeCurve " << NbEdgeCurve << " " <<NbVerticesOnGeomEdge0<<" " <<NbVerticesOnGeomEdge<<" step =" <<step<<  endl;
     4015                                                         }
     4016                                                  // end of curve --
     4017                                                  if (edges) { // last edges of the curves
     4018                                                          edges[nbe].v[0]=va;
     4019                                                          edges[nbe].v[1]=vb;
     4020                                                          edges[nbe].ref = e->ref;
     4021                                                          edges[nbe].on = e;
     4022                                                          edges[nbe].adj[0] = PreviousNewEdge;
     4023                                                          edges[nbe].adj[1] = 0;
     4024                                                          if(PreviousNewEdge)
     4025                                                                PreviousNewEdge->adj[1] = & edges[nbe];
     4026
     4027                                                          nbe++;}
     4028                                                  else
     4029                                                        nbe += NbEdgeCurve;
     4030                                                 } // end on  curve ---
     4031                                  } // if (edges[i][j].Corner()) 
     4032                        } // for (i=0;i<nbe;i++)
     4033                        if(!step) {
     4034                                // cout << "edges " << edges << " VerticesOnGeomEdge " <<VerticesOnGeomEdge << endl;
     4035                                assert(!edges);
     4036                                assert(!VerticesOnGeomEdge);
     4037                                edges = new Edge[nbex=nbe];
     4038                                if(NbVerticesOnGeomEdge0)
     4039                                 VerticesOnGeomEdge = new VertexOnGeom[NbVerticesOnGeomEdge0];
     4040                                assert(edges);
     4041                                assert(VerticesOnGeomEdge || NbVerticesOnGeomEdge0 ==0);
     4042                                // do the vertex on a geometrical vertex
     4043                                NbVerticesOnGeomEdge0 = NbVerticesOnGeomEdge;       
     4044                        }
     4045                        else
     4046                         assert(NbVerticesOnGeomEdge == NbVerticesOnGeomEdge0);
     4047                        //     cout << " Nb of Curves = " << NbOfCurves << "nbe = " << nbe
     4048                        //        << "== " << nbex << "  nbv = " << nbv <<  endl;
     4049                        assert(nbex=nbe);
     4050                  } // for (step=0;step<2;step++)
     4051
     4052                Insert();
     4053                ForceBoundary();
     4054                FindSubDomain();
     4055
     4056                // NewPointsOld(*this) ;
     4057                NewPoints(*this,0) ;
     4058                CurrentTh = 0;
     4059        }
     4060        /*}}}1*/
     4061        /*FUNCTION Triangles::MakeGeometricalEdgeToEdge{{{1*/
     4062        Edge** Triangles::MakeGeometricalEdgeToEdge() {
     4063                assert(Gh.nbe);
     4064                Edge **e= new (Edge* [Gh.nbe]);
     4065
     4066                Int4 i;
     4067                for ( i=0;i<Gh.nbe ; i++)
     4068                 e[i]=NULL;
     4069                for ( i=0;i<nbe ; i++)
     4070                  {
     4071                        Edge * ei = edges+i;
     4072                        GeometricalEdge *on = ei->on;
     4073                        e[Gh.Number(on)] = ei;   
     4074                  }
     4075                for ( i=0;i<nbe ; i++)
     4076                 for (int ii=0;ii<2;ii++) {
     4077                         Edge * ei = edges+i;
     4078                         GeometricalEdge *on = ei->on;
     4079                         int j= ii;
     4080                         while (!(*on)[j].Required()) {
     4081                                 //     cout << i << " " << ii << " j= " << j << " curve = "
     4082                                 //           <<  on->CurveNumber << "  " << Gh.Number(on) << " on " << j
     4083                                 //   << " s0 " << Gh.Number( (*on)[0]) << " s1  " << Gh.Number( (*on)[1])
     4084                                 //   << " ->  " ;
     4085                                 Adj(on,j); // next geom edge
     4086                                 j=1-j;
     4087                                 //       cout << Gh.Number(on) << "  " << j  << " e[ON] =  " <<  e[Gh.Number(on)]
     4088                                 //    << " s0 " << Gh.Number( (*on)[0]) << " s1  " << Gh.Number( (*on)[1]) << endl;
     4089                                 if (e[Gh.Number(on)])  break; // optimisation     
     4090                                 e[Gh.Number(on)] = ei;
     4091                         }
     4092                 }
     4093
     4094                int kk=0;
     4095                for ( i=0;i<Gh.nbe ; i++)
     4096                 if (!e[i])
     4097                  if(kk++<10) {
     4098                          cerr << " Bug -- the geometrical edge " << i << " is on no edge curve = " << Gh.edges[i].CurveNumber
     4099                                 << " s0 " << Gh.Number( Gh.edges[i][0]) << " s1  " << Gh.Number( Gh.edges[i][1]) << endl;
     4100                          //     assert( e[i]);
     4101                  }
     4102                if(kk) MeshError(997,this);
     4103
     4104                return e;
     4105        }
     4106        /*}}}1*/
     4107        /*FUNCTION Triangles::SetIntCoor{{{1*/
     4108        void Triangles::SetIntCoor(const char * strfrom) {
     4109                pmin =  vertices[0].r;
     4110                pmax =  vertices[0].r;
     4111
     4112                // recherche des extrema des vertices pmin,pmax
     4113                Int4 i;
     4114                for (i=0;i<nbv;i++) {
     4115                        pmin.x = Min(pmin.x,vertices[i].r.x);
     4116                        pmin.y = Min(pmin.y,vertices[i].r.y);
     4117                        pmax.x = Max(pmax.x,vertices[i].r.x);
     4118                        pmax.y = Max(pmax.y,vertices[i].r.y);
     4119                }
     4120                R2 DD = (pmax-pmin)*0.05;
     4121                pmin = pmin-DD;
     4122                pmax = pmax+DD;
     4123                coefIcoor= (MaxICoor)/(Max(pmax.x-pmin.x,pmax.y-pmin.y));
     4124                assert(coefIcoor >0);
     4125
     4126                // generation of integer coord 
     4127                for (i=0;i<nbv;i++) {
     4128                        vertices[i].i = toI2(vertices[i].r);   
     4129                }
     4130
     4131                // computation of the det
     4132                int Nberr=0;
     4133                for (i=0;i<nbt;i++)
     4134                  {
     4135                        Vertex & v0 = triangles[i][0];
     4136                        Vertex & v1 = triangles[i][1];
     4137                        Vertex & v2 = triangles[i][2];
     4138                        if ( &v0 && &v1 &&  &v2 ) // a good triangles;
     4139                          {
     4140                                triangles[i].det= det(v0,v1,v2);
     4141                                if (triangles[i].det <=0 && Nberr++ <10)
     4142                                  {
     4143                                        if(Nberr==1)
     4144                                         if (strfrom)
     4145                                          cerr << "+++ Fatal Error " << strfrom << "(SetInCoor)  Error :  area of Triangle < 0 " << endl;
     4146                                         else
     4147                                          cerr << "+++  Fatal Error Triangle (in SetInCoor) area of Triangle < 0" << endl;
     4148                                        cerr << " Triangle " << i << "  det  (I2) = " << triangles[i].det ;
     4149                                        cerr << " (R2) " << Det(v1.r-v0.r,v2.r-v0.r);
     4150                                        cerr << "; The 3  vertices " << endl;
     4151                                        cerr << Number(v0) << " "  << Number(v1) << " "
     4152                                          << Number(v2) << " : " ;
     4153                                        cerr << v0.r << v1.r << v2.r << " ; ";
     4154                                        cerr << v0.i << v1.i << v2.i << endl;
     4155                                  }
     4156                          }
     4157                        else
     4158                         triangles[i].det= -1; // Null triangle;
     4159                  }
     4160                if (Nberr) MeshError(899,this);
     4161
     4162        }
     4163        /*}}}1*/
     4164        /*FUNCTION Triangles::FillHoleInMesh{{{1*/
     4165        void Triangles::FillHoleInMesh() {
     4166
     4167                Triangles* OldCurrentTh =CurrentTh;
     4168                CurrentTh=this;
     4169
     4170                int verbosity=0;
     4171
     4172                // generation of the integer coordinate
     4173                  {
     4174
     4175                        // find extrema coordinates of vertices pmin,pmax
     4176                        Int4 i;
     4177                        if(verbosity>2) printf("      Filling holes in mesh of %i vertices\n",nbv);
     4178
     4179                        //initialize ordre
     4180                        assert(ordre);
     4181                        for (i=0;i<nbv;i++) ordre[i]=0;
     4182
     4183                        NbSubDomains =0;
     4184
     4185                        /* generation of the adjacence of the triangles*/
     4186
     4187                        SetOfEdges4* edge4= new SetOfEdges4(nbt*3,nbv);
     4188
     4189                        //initialize st
     4190                        Int4* st = new Int4[nbt*3];
     4191                        for (i=0;i<nbt*3;i++) st[i]=-1;
     4192
     4193                        //check number of edges
     4194                        Int4 kk =0;
     4195                        for (i=0;i<nbe;i++){
     4196                                kk=kk+(i == edge4->addtrie(Number(edges[i][0]),Number(edges[i][1])));
     4197                        }
     4198                        if (kk != nbe) {
     4199                                throw ErrorException(__FUNCT__,exprintf("Some Double edge in the mesh, the number is %i",kk-nbe));
     4200                        }
     4201
     4202                        //
     4203                        for (i=0;i<nbt;i++){
     4204                                for (int j=0;j<3;j++) {
     4205                                        Int4 k =edge4->addtrie(Number(triangles[i][VerticesOfTriangularEdge[j][0]]),
     4206                                                                Number(triangles[i][VerticesOfTriangularEdge[j][1]]));
     4207                                        Int4 invisible = triangles[i].Hidden(j);
     4208                                        if(st[k]==-1){
     4209                                                st[k]=3*i+j;
     4210                                        }
     4211                                        else if(st[k]>=0) {
     4212                                                assert( ! triangles[i].TriangleAdj(j) && !triangles[st[k] / 3].TriangleAdj((int) (st[k]%3)));
     4213
     4214                                                triangles[i].SetAdj2(j,triangles + st[k] / 3,(int) (st[k]%3));
     4215                                                if (invisible)  triangles[i].SetHidden(j);
     4216                                                if (k<nbe) {
     4217                                                        triangles[i].SetLocked(j);
     4218                                                }
     4219                                                st[k]=-2-st[k];
     4220                                        }
     4221                                        else {
     4222                                                throw ErrorException(__FUNCT__,exprintf("The edge (%i , %i) belongs to more than 2 triangles",
     4223                                                                                Number(triangles[i][VerticesOfTriangularEdge[j][0]]),Number(triangles[i][VerticesOfTriangularEdge[j][1]])));
     4224                                        }
     4225                                }
     4226                        }
     4227                        if(verbosity>5) {
     4228                                printf("         info on Mesh %s:\n",name);
     4229                                printf("            - number of vertices    = %i \n",nbv);
     4230                                printf("            - number of triangles   = %i \n",nbt);
     4231                                printf("            - number of given edges = %i \n",nbe);
     4232                                printf("            - number of all edges   = %i \n"  ,edge4->nb());
     4233                                printf("            - Euler number 1 - nb of holes = %i \n"  ,nbt-edge4->nb()+nbv);
     4234                        }
     4235
     4236                        // check the consistant of edge[].adj and the geometrical required  vertex
     4237                        Int4 k=0;
     4238                        for (i=0;i<edge4->nb();i++){
     4239                                if (st[i] >=0){ // edge alone
     4240                                        if (i < nbe) {
     4241                                                Int4 i0=edge4->i(i);
     4242                                                ordre[i0] = vertices+i0;
     4243                                                Int4 i1=edge4->j(i);
     4244                                                ordre[i1] = vertices+i1;
     4245                                        }
     4246                                        else {
     4247                                                k=k+1;
     4248                                                if (k <20) {
     4249                                                        throw ErrorException(__FUNCT__,exprintf("Lost boundary edges %i : %i %i",i,edge4->i(i),edge4->j(i)));
     4250                                                }
     4251                                        }
     4252                                }
     4253                        }
     4254                        if(k != 0) {
     4255                                throw ErrorException(__FUNCT__,exprintf("%i boundary edges  are not defined as edges",k));
     4256                        }
     4257
     4258                        /* mesh generation with boundary points*/
     4259                        Int4 nbvb = 0;
     4260                        for (i=0;i<nbv;i++){
     4261                                vertices[i].t=0;
     4262                                vertices[i].vint=0;
     4263                                if (ordre[i]){
     4264                                        ordre[nbvb++] = ordre[i];
     4265                                }
     4266                        }
     4267
     4268                        Triangle* savetriangles= triangles;
     4269                        Int4 savenbt=nbt;
     4270                        Int4 savenbtx=nbtx;
     4271                        SubDomain * savesubdomains = subdomains;
     4272                        subdomains = 0;
     4273
     4274                        Int4  Nbtriafillhole = 2*nbvb;
     4275                        Triangle* triafillhole =new Triangle[Nbtriafillhole];
     4276                        triangles =  triafillhole;
     4277
     4278                        nbt=2;
     4279                        nbtx= Nbtriafillhole;
     4280
     4281                        for (i=2 ; det( ordre[0]->i, ordre[1]->i, ordre[i]->i ) == 0;)
     4282                         if  ( ++i >= nbvb) {
     4283                                 cerr << "FillHoleInMesh: All the vertices are aline " << nbvb << endl;
     4284                                 MeshError(998,this); }
     4285                                 Exchange( ordre[2], ordre[i]);
     4286
     4287                                 Vertex *  v0=ordre[0], *v1=ordre[1];
     4288
     4289
     4290                                 triangles[0](0) = 0; // sommet pour infini
     4291                                 triangles[0](1) = v0;
     4292                                 triangles[0](2) = v1;
     4293
     4294                                 triangles[1](0) = 0;// sommet pour infini
     4295                                 triangles[1](2) = v0;
     4296                                 triangles[1](1) = v1;
     4297                                 const int e0 = OppositeEdge[0];
     4298                                 const int e1 = NextEdge[e0];
     4299                                 const int e2 = PreviousEdge[e0];
     4300                                 triangles[0].SetAdj2(e0, &triangles[1] ,e0);
     4301                                 triangles[0].SetAdj2(e1, &triangles[1] ,e2);
     4302                                 triangles[0].SetAdj2(e2, &triangles[1] ,e1);
     4303
     4304                                 triangles[0].det = -1;  // faux triangles
     4305                                 triangles[1].det = -1;  // faux triangles
     4306
     4307                                 triangles[0].SetTriangleContainingTheVertex();
     4308                                 triangles[1].SetTriangleContainingTheVertex();
     4309
     4310                                 triangles[0].link=&triangles[1];
     4311                                 triangles[1].link=&triangles[0];
     4312
     4313                                 if (!quadtree )
     4314                                  delete  quadtree; // ->ReInitialise();
     4315
     4316                                 quadtree = new QuadTree(this,0);
     4317                                 quadtree->Add(*v0);
     4318                                 quadtree->Add(*v1);
     4319
     4320                                 // We add the vertices one by one
     4321                                 Int4 NbSwap=0;
     4322                                 for (Int4 icount=2; icount<nbvb; icount++) {
     4323                                         Vertex *vi  = ordre[icount];
     4324                                         //       cout << " Add vertex " <<  Number(vi) << endl;
     4325                                         Icoor2 dete[3];
     4326                                         Triangle *tcvi = FindTriangleContening(vi->i,dete);
     4327                                         quadtree->Add(*vi);
     4328                                         Add(*vi,tcvi,dete);
     4329                                         NbSwap += vi->Optim(1,1);
     4330                                 }
     4331
     4332                                 // inforce the boundary
     4333                                 TriangleAdjacent ta(0,0);
     4334                                 Int4 nbloss = 0,knbe=0;
     4335                                 for ( i = 0; i < nbe; i++){
     4336                                         if (st[i] >=0){  // edge alone => on border ...  FH oct 2009
     4337                                                 Vertex & a=edges[i][0], & b =    edges[i][1];
     4338                                                 if (a.t && b.t) // le bug est la si maillage avec des bod non raffine 1.
     4339                                                        {
     4340                                                         knbe++;
     4341                                                         if (ForceEdge(a,b,ta)<0)
     4342                                                          nbloss++;
     4343                                                        }
     4344                                         }
     4345                                 }
     4346                                 if(nbloss) {
     4347                                         cerr << " we loss some  " << nbloss << " "  << " edges other " << knbe << endl;
     4348                                         MeshError(1100,this);
     4349                                 }
     4350
     4351                                 FindSubDomain(1);
     4352                                 // remove all the hole
     4353                                 // remove all the good sub domain
     4354                                 Int4 krm =0;
     4355                                 for (i=0;i<nbt;i++){
     4356                                         if (triangles[i].link){ // remove triangles
     4357                                                 krm++;
     4358                                                 for (int j=0;j<3;j++)
     4359                                                        {
     4360                                                         TriangleAdjacent ta =  triangles[i].Adj(j);
     4361                                                         Triangle & tta = * (Triangle *) ta;
     4362                                                         if(! tta.link) // edge between remove and not remove
     4363                                                                { // change the link of ta;
     4364                                                                 int ja = ta;
     4365                                                                 Vertex *v0= ta.EdgeVertex(0);
     4366                                                                 Vertex *v1= ta.EdgeVertex(1);
     4367                                                                 Int4 k =edge4->addtrie(v0?Number(v0):nbv,v1? Number(v1):nbv);
     4368                                                                 assert(st[k] >=0);
     4369                                                                 tta.SetAdj2(ja,savetriangles + st[k] / 3,(int) (st[k]%3));
     4370                                                                 ta.SetLock();
     4371                                                                 st[k]=-2-st[k];
     4372                                                                }
     4373                                                        }
     4374                                         }
     4375                                 }
     4376                                 Int4 NbTfillHoll =0;
     4377                                 for (i=0;i<nbt;i++){
     4378                                         if (triangles[i].link) {
     4379                                                 triangles[i]=Triangle((Vertex *) NULL,(Vertex *) NULL,(Vertex *) NULL);
     4380                                                 triangles[i].color=-1;
     4381                                         }
     4382                                         else
     4383                                                {
     4384                                                 triangles[i].color= savenbt+ NbTfillHoll++;
     4385                                                }
     4386                                 }
     4387                                 // cout <<      savenbt+NbTfillHoll << " " <<  savenbtx  << endl;
     4388                                 assert(savenbt+NbTfillHoll <= savenbtx );
     4389                                 // copy of the outside triangles in saveTriangles
     4390                                 for (i=0;i<nbt;i++){
     4391                                         if(triangles[i].color>=0) {
     4392                                                 savetriangles[savenbt]=triangles[i];
     4393                                                 savetriangles[savenbt].link=0;
     4394                                                 savenbt++;
     4395                                         }
     4396                                 }
     4397                                 // gestion of the adj
     4398                                 k =0;
     4399                                 Triangle * tmax = triangles + nbt;
     4400                                 for (i=0;i<savenbt;i++) 
     4401                                        {
     4402                                         Triangle & ti = savetriangles[i];
     4403                                         for (int j=0;j<3;j++)
     4404                                                {
     4405                                                 Triangle * ta = ti.TriangleAdj(j);
     4406                                                 int aa = ti.NuEdgeTriangleAdj(j);
     4407                                                 int lck = ti.Locked(j);
     4408                                                 if (!ta) k++; // bug
     4409                                                 else if ( ta >= triangles && ta < tmax)
     4410                                                        {
     4411                                                         ta= savetriangles + ta->color;
     4412                                                         ti.SetAdj2(j,ta,aa);
     4413                                                         if(lck) ti.SetLocked(j);
     4414                                                        }
     4415                                                }
     4416                                        }
     4417                                 //      OutSidesTriangles = triangles;
     4418                                 //     Int4 NbOutSidesTriangles = nbt;
     4419
     4420                                 // restore triangles;
     4421                                 nbt=savenbt;
     4422                                 nbtx=savenbtx;
     4423                                 delete [] triangles;
     4424                                 delete [] subdomains;
     4425                                 triangles = savetriangles;
     4426                                 subdomains = savesubdomains;
     4427                                 //      cout <<  triangles << " <> " << OutSidesTriangles << endl;
     4428                                 /*      k=0;
     4429                                                 for (i=0;i<nbt;i++)
     4430                                                 for (int j=0;j<3;j++)
     4431                                                 if (!triangles[i].TriangleAdj(j))
     4432                                                 k++;
     4433                                                 */
     4434                                 if (k) {
     4435                                         cerr << "Error Nb of triangles edge alone = " << k << endl;
     4436                                         MeshError(9997,this);
     4437                                 }
     4438                                 FindSubDomain();
     4439                                 // cout << " NbTOld = " << NbTold << " ==  " << nbt - NbOutT << " " << nbt << endl;
     4440
     4441                                 delete edge4;
     4442                                 delete [] st;
     4443                                 for (i=0;i<nbv;i++)
     4444                                  quadtree->Add(vertices[i]);
     4445
     4446                                 SetVertexFieldOn();
     4447
     4448                                 for (i=0;i<nbe;i++)
     4449                                  if(edges[i].on)
     4450                                        for(int j=0;j<2;j++)
     4451                                         if (!edges[i].adj[j])
     4452                                          if(!edges[i][j].on->IsRequiredVertex()) {
     4453                                                  cerr << " Erreur adj et sommet requis edges [" << i <<  "][ " << j << "]= "
     4454                                                         <<  Number(edges[i][j]) << " : "  << " on = " << Gh.Number(edges[i].on) ;
     4455                                                  if (edges[i][j].on->OnGeomVertex())
     4456                                                        cerr << " vertex " << Gh.Number(edges[i][j].on->gv);
     4457                                                  else if (edges[i][j].on->OnGeomEdge())
     4458                                                        cerr << "Edges " << Gh.Number(edges[i][j].on->ge);
     4459                                                  else
     4460                                                        cerr << " = " << edges[i][j].on ;
     4461                                                  cerr << endl;
     4462                                          }
     4463                  }
     4464                CurrentTh=OldCurrentTh;
     4465        }
     4466        /*}}}1*/
     4467        /*FUNCTION Triangles::Optim{{{1*/
     4468        Int4  Triangle::Optim(Int2 i,int koption) {
     4469                // turne around in positif sens
     4470                Int4 NbSwap =0;
     4471                Triangle  *t = this;
     4472                int k=0,j =OppositeEdge[i];
     4473                int jp = PreviousEdge[j];
     4474                // initialise   tp, jp the previous triangle & edge
     4475                Triangle *tp= at[jp];
     4476                jp = aa[jp]&3;
     4477                do {
     4478                        //    cout << *t << " " <<  j  << "\n\t try swap " ;
     4479                        while (t->swap(j,koption))
     4480                          {
     4481                                NbSwap++;
     4482                                assert(k++<20000);
     4483                                t=  tp->at[jp];      // set unchange t qnd j for previous triangles
     4484                                j=  NextEdge[tp->aa[jp]&3];
     4485                                //   cout << "\n\t s  " <<  *t << " " << j << endl;
     4486                          }
     4487                        // end on this  Triangle
     4488                        tp = t;
     4489                        jp = NextEdge[j];
     4490
     4491                        t=  tp->at[jp];      // set unchange t qnd j for previous triangles
     4492                        j=  NextEdge[tp->aa[jp]&3];
     4493
     4494                } while( t != this);
     4495                return NbSwap;
     4496        }
     4497        /*}}}1*/
     4498        /*FUNCTION Triangles::SmoothingVertex{{{1*/
     4499        void Triangles::SmoothingVertex(int nbiter,Real8 omega ) {
     4500                long int verbosity=0;
     4501                //  if quatree exist remove it end reconstruct
     4502                if (quadtree) delete quadtree;
     4503                quadtree=0;
     4504                ReMakeTriangleContainingTheVertex();
     4505                Triangle vide; // a triangle to mark the boundary vertex
     4506                Triangle   ** tstart= new Triangle* [nbv];
     4507                Int4 i,j,k;
     4508                //   attention si Background == Triangle alors on ne peut pas utiliser la rechech rapide
     4509                if ( this == & BTh)
     4510                 for ( i=0;i<nbv;i++)
     4511                  tstart[i]=vertices[i].t;     
     4512                else
     4513                 for ( i=0;i<nbv;i++)
     4514                  tstart[i]=0;
     4515                for ( j=0;j<NbVerticesOnGeomVertex;j++ )
     4516                 tstart[ Number(VerticesOnGeomVertex[j].mv)]=&vide;
     4517                for ( k=0;k<NbVerticesOnGeomEdge;k++ )
     4518                 tstart[ Number(VerticesOnGeomEdge[k].mv)]=&vide;
     4519                if(verbosity>2)
     4520                 cout << "  -- SmoothingVertex: nb Iteration = " << nbiter << " Omega = " << omega << endl;
     4521                for (k=0;k<nbiter;k++)
     4522                  {
     4523                        Int4 i,NbSwap =0;
     4524                        Real8 delta =0;
     4525                        for ( i=0;i<nbv;i++)
     4526                         if (tstart[i] != &vide) // not a boundary vertex
     4527                          delta=Max(delta,vertices[i].Smoothing(*this,BTh,tstart[i],omega));
     4528                        if (!NbOfQuad)
     4529                         for ( i=0;i<nbv;i++)
     4530                          if (tstart[i] != &vide) // not a boundary vertex
     4531                                NbSwap += vertices[i].Optim(1);
     4532                        if (verbosity>3)
     4533                         cout << "    Move max = " <<  sqrt(delta) << " iteration = "
     4534                                << k << " Nb of Swap = " << NbSwap << endl;
     4535                  }
     4536
     4537                delete [] tstart;
     4538                if (quadtree) quadtree= new QuadTree(this);
     4539        }
     4540        /*}}}1*/
     4541        /*FUNCTION Triangles::MakeQuadTree{{{1*/
     4542        void Triangles::MakeQuadTree() { 
     4543                long int verbosity=0;
     4544                if(verbosity>8)
     4545                 cout << "      MakeQuadTree" << endl;
     4546                if (  !quadtree )  quadtree = new QuadTree(this);
     4547
     4548        }
     4549        /*}}}1*/
     4550        /*FUNCTION Triangles::ShowRegulaty{{{1*/
     4551        void  Triangles::ShowRegulaty() const {
     4552                const  Real8  sqrt32=sqrt(3.)*0.5;
     4553                const Real8  aireKh=sqrt32*0.5;
     4554                D2  Beq(1,0),Heq(0.5,sqrt32);
     4555                D2xD2 Br(D2xD2(Beq,Heq).t());
     4556                D2xD2 B1r(Br.inv());
     4557                /*   D2xD2 BB = Br.t()*Br;
     4558                          cout << " BB = " << BB << " " << Br*B1r <<  endl;
     4559                          MetricAnIso MMM(BB.x.x,BB.x.y,BB.y.y);
     4560                          MatVVP2x2 VMM(MMM);
     4561                          cout << " " << VMM.lambda1 << " " << VMM.lambda2 <<  endl;
     4562                          */
     4563                double gammamn=1e100,hmin=1e100;
     4564                double gammamx=0,hmax=0;
     4565                double beta=1e100;
     4566                double beta0=0;
     4567                double  alpha2=0;
     4568                double area=0,Marea=0;
     4569                // Real8 cf= Real8(coefIcoor);
     4570                // Real8 cf2= 6.*cf*cf;
     4571                int nt=0;
     4572                for (int it=0;it<nbt;it++)
     4573                 if ( triangles[it].link)
     4574                        {
     4575                         nt++;
     4576                         Triangle &K=triangles[it];
     4577                         Real8  area3= Area2((R2) K[0],(R2) K[1],(R2) K[2])/6.;
     4578                         area+= area3;
     4579                         D2xD2 B_Kt(K[0],K[1],K[2]);
     4580                         D2xD2 B_K(B_Kt.t());
     4581                         D2xD2 B1K = Br*B_K.inv();
     4582                         D2xD2 BK =  B_K*B1r;
     4583                         D2xD2 B1B1 = B1K.t()*B1K;
     4584                         MetricAnIso MK(B1B1.x.x,B1B1.x.y,B1B1.y.y);
     4585                         MatVVP2x2 VMK(MK);
     4586                         alpha2 = Max(alpha2,Max(VMK.lambda1/VMK.lambda2,VMK.lambda2/VMK.lambda1));
     4587                         // cout << B_K << " * " << B1r << " == " << BK << " " << B_K*B_K.inv() << endl;
     4588                         Real8 betaK=0;
     4589
     4590                         for (int j=0;j<3;j++)
     4591                                {
     4592                                 Real8 he= Norme2(R2(K[j],K[(j+1)%3]));
     4593                                 hmin=Min(hmin,he);
     4594                                 hmax=Max(hmax,he);
     4595                                 Vertex & v=K[j];
     4596                                 D2xD2 M((MetricAnIso)v);
     4597                                 betaK += sqrt(M.det());
     4598
     4599                                 D2xD2 BMB = BK.t()*M*BK;
     4600                                 MetricAnIso M1(BMB.x.x,BMB.x.y,BMB.y.y);
     4601                                 MatVVP2x2 VM1(M1);
     4602                                 //cout << B_K <<" " <<  M << " " <<  he << " " << BMB << " " << VM1.lambda1 << " " << VM1.lambda2<<   endl;
     4603                                 gammamn=Min3(gammamn,VM1.lambda1,VM1.lambda2);
     4604                                 gammamx=Max3(gammamx,VM1.lambda1,VM1.lambda2);         
     4605                                }
     4606                         betaK *= area3;//  1/2 (somme sqrt(det))* area(K)
     4607                         Marea+= betaK;
     4608                         // cout << betaK << " " << area3 << " " << beta << " " << beta0 << " " << area3*3*3*3 <<endl;
     4609                         beta=min(beta,betaK);
     4610                         beta0=max(beta0,betaK);
     4611                        }   
     4612                area*=3;
     4613                gammamn=sqrt(gammamn);
     4614                gammamx=sqrt(gammamx);   
     4615                cout << "  -- adaptmesh Regulary:  Nb triangles " << nt <<  " , h  min " << hmin  << " , h max " << hmax << endl; 
     4616                cout << "     area =  " << area << " , M area = " << Marea << " , M area/( |Khat| nt) " << Marea/(aireKh*nt) << endl;
     4617                cout << "     infiny-regulaty:  min " << gammamn << "  max " << gammamx << endl; 
     4618                cout << "     anisomax  "<< sqrt(alpha2) << ", beta max = " << 1./sqrt(beta/aireKh)
     4619                  << " min  "<<  1./sqrt(beta0/aireKh)  << endl;
     4620        }
     4621        /*}}}1*/
     4622        /*FUNCTION Triangles::ShowHistogram{{{1*/
     4623        void  Triangles::ShowHistogram() const {
     4624
     4625                const Int4 kmax=10;
     4626                const Real8 llmin = 0.5,llmax=2;
     4627                const Real8 lmin=log(llmin),lmax=log(llmax),delta= kmax/(lmax-lmin);
     4628                Int4 histo[kmax+1];
     4629                Int4 i,it,k, nbedges =0;
     4630                for (i=0;i<=kmax;i++) histo[i]=0;
     4631                for (it=0;it<nbt;it++)
     4632                 if ( triangles[it].link)
     4633                        {
     4634
     4635                         for (int j=0;j<3;j++)
     4636                                {
     4637                                 Triangle *ta = triangles[it].TriangleAdj(j);
     4638                                 if ( !ta || !ta->link || Number(ta) >= it)
     4639                                        {
     4640                                         Vertex & vP = triangles[it][VerticesOfTriangularEdge[j][0]];
     4641                                         Vertex & vQ = triangles[it][VerticesOfTriangularEdge[j][1]];
     4642                                         if ( !& vP || !&vQ) continue;
     4643                                         R2 PQ = vQ.r - vP.r;
     4644                                         Real8 l = log(LengthInterpole(vP,vQ,PQ));
     4645                                         nbedges++;
     4646                                         k = (int) ((l - lmin)*delta);
     4647                                         k = Min(Max(k,0L),kmax);
     4648                                         histo[k]++;
     4649                                        }
     4650                                }
     4651                        } 
     4652                cout << "  -- Histogram of the unit mesh,  nb of edges" << nbedges << endl <<endl;
     4653
     4654                cout << "        length of edge in   | % of edge  | Nb of edges " << endl;
     4655                cout << "        ------------------- | ---------- | ----------- " << endl;
     4656                for   (i=0;i<=kmax;i++)
     4657                  {
     4658                        cout << "    " ;
     4659                        cout.width(10);
     4660                        if (i==0) cout  << " 0 " ;
     4661                        else cout  << exp(lmin+i/delta) ;
     4662                        cout.width(); cout << "," ;
     4663                        cout.width(10);
     4664                        if (i==kmax) cout << " +infty " ;
     4665                        else cout  << exp(lmin+(i+1)/delta) ;
     4666                        cout.width();cout << "   |   " ;
     4667
     4668                        cout.precision(4);
     4669                        cout.width(6);
     4670                        cout <<  ((long)  ((10000.0 * histo[i])/ nbedges))/100.0 ;
     4671                        cout.width();
     4672                        cout.precision();
     4673                        cout <<  "   |   " << histo[i] <<endl;
     4674                  }
     4675                cout << "        ------------------- | ---------- | ----------- " << endl <<endl;
     4676
     4677        }
     4678        /*}}}1*/
     4679        /*FUNCTION Triangles::Crack{{{1*/
     4680        int  Triangles::Crack() {
     4681                assert(NbCrackedEdges ==0 || NbCrackedVertices >0);
     4682                for (int i=0;i<NbCrackedEdges;i++)
     4683                 CrackedEdges[i].Crack();
     4684                return NbCrackedEdges;
     4685        }
     4686        /*}}}1*/
     4687        /*FUNCTION Triangles::UnCrack{{{1*/
     4688        int Triangles::UnCrack() {
     4689                assert(NbCrackedEdges ==0 || NbCrackedVertices >0);
     4690                for (int i=0;i<NbCrackedEdges;i++)
     4691                 CrackedEdges[i].UnCrack();
     4692                return NbCrackedEdges;
     4693        }
     4694        /*}}}1*/
     4695        /*FUNCTION Triangles::CrackMesh{{{1*/
     4696        int Triangles::CrackMesh() {
     4697                long int verbosity=0;
     4698                Triangles *CurrentThOld = CurrentTh;
     4699                //  computed the number of cracked edge
     4700                int i,k;
     4701                for (k=i=0;i<nbe;i++)
     4702                 if(edges[i].on->Cracked()) k++;
     4703                if( k==0) return 0;
     4704                CurrentTh = this;
     4705                cout << " Nb of Cracked Edges = " << k << endl;
     4706                NbCrackedEdges =k;
     4707                CrackedEdges = new  CrackedEdge[k];
     4708                //  new edge
     4709                Edge * e = new Edge[ nbe + k];
     4710
     4711                // copy
     4712                for (i=0;i<nbe;i++)
     4713                 e[i] = edges[i];
     4714                delete edges;
     4715                edges = e;
     4716
     4717                const int  nbe0  = nbe;
     4718                for (k=i=0;i<nbe0;i++) // on double les arete cracked
     4719                 if(edges[i].on->Cracked())
     4720                        {
     4721                         e[nbe] = e[i];
     4722                         //  return the edge
     4723                         e[nbe].v[0] =  e[i].v[1];
     4724                         e[nbe].v[1] =  e[i].v[0];
     4725                         e[nbe].on = e[i].on->link ; // fqux
     4726                         CrackedEdges[k++]=CrackedEdge(edges,i,nbe);
     4727                         nbe++;
     4728                        }
     4729                ReMakeTriangleContainingTheVertex() ;
     4730                // 
     4731                int nbcrakev  =0;
     4732                Vertex *vlast = vertices + nbv;
     4733                Vertex *vend = vertices + nbvx; // end of array
     4734                for (int iv=0;iv<nbv;iv++) // vertex
     4735                  {
     4736                        Vertex & v= vertices[iv];
     4737                        Vertex * vv = & v; 
     4738                        int kk=0; // nb cracked
     4739                        int kc=0;
     4740                        int kkk =0; // nb triangle  with same number
     4741                        Triangle * tbegin = v.t;
     4742                        int i  = v.vint;       
     4743                        assert(tbegin && (i >= 0 ) && (i <3));
     4744                        // turn around the vertex v
     4745                        TriangleAdjacent ta(tbegin,EdgesVertexTriangle[i][0]);// previous edge
     4746                        int k=0;
     4747                        do {
     4748                                int kv = VerticesOfTriangularEdge[ta][1];
     4749                                k++;
     4750                                Triangle * tt (ta);
     4751                                if ( ta.Cracked() )
     4752                                  {   
     4753                                        TriangleAdjacent tta=(ta.Adj());
     4754                                        assert(tta.Cracked());
     4755                                        if ( kk == 0) tbegin=ta,kkk=0;  //  begin by a cracked edge  => restart               
     4756                                        if (  kkk ) { kc =1;vv = vlast++;  kkk = 0; } // new vertex if use
     4757                                        kk++;// number of cracked edge view                 
     4758                                  }
     4759                                if ( tt->link ) { // if good triangles store the value
     4760                                        int it = Number(tt);
     4761                                        assert(it < nt);
     4762                                        (*tt)(kv)= vv; //   Change the vertex of triangle
     4763                                        if(vv<vend) {*vv= v;vv->ReferenceNumber=iv;} // copy the vertex value + store the old vertex number in ref
     4764                                        //        tt->SetTriangleContainingTheVertex();
     4765                                        kkk++;
     4766                                } else if (kk) { // crack + boundary
     4767                                        if (  kkk ) { kc =1;vv = vlast++;  kkk = 0; } // new vertex if use
     4768                                }
     4769
     4770                                ta = Next(ta).Adj();
     4771                        } while ( (tbegin != ta));
     4772                        assert(k);
     4773                        if (kc)  nbcrakev++;
     4774                  }
     4775
     4776                if ( nbcrakev )
     4777                 for (int iec =0;iec < NbCrackedEdges; iec ++)
     4778                  CrackedEdges[iec].Set();
     4779
     4780                //  set the ref
     4781                cout << " set the ref " <<  endl ;
     4782                NbCrackedVertices =   nbcrakev;
     4783                // int nbvo = nbv;
     4784                nbv = vlast - vertices;
     4785                int nbnewv =  nbv - nbv; // nb of new vrtices
     4786                if (nbcrakev && verbosity > 1 )
     4787                 cout << " Nb of craked vertices = " << nbcrakev << " Nb of created vertices " <<   nbnewv<< endl;
     4788                // all the new vertices are on geometry
     4789                //  BOFBO--  A VOIR
     4790                if (nbnewv)
     4791                  { //
     4792                        Int4 n = nbnewv+NbVerticesOnGeomVertex;
     4793                        Int4 i,j,k;
     4794                        VertexOnGeom * vog = new VertexOnGeom[n];
     4795                        for ( i =0; i<NbVerticesOnGeomVertex;i++)
     4796                         vog[i]=VerticesOnGeomVertex[i];
     4797                        delete [] VerticesOnGeomVertex;
     4798                        VerticesOnGeomVertex = vog;
     4799                        // loop on cracked edge
     4800                        Vertex * LastOld = vertices + nbv - nbnewv;
     4801                        for (int iec =0;iec < NbCrackedEdges; iec ++)
     4802                         for (k=0;k<2;k++)
     4803                                {
     4804                                 Edge & e = *( k ? CrackedEdges[iec].a.edge : CrackedEdges[iec].b.edge);
     4805                                 for (j=0;j<2;j++)
     4806                                        {
     4807                                         Vertex * v = e(j);
     4808                                         if ( v >=  LastOld)
     4809                                                { // a new vertex
     4810                                                 Int4 old = v->ReferenceNumber ; // the old same vertex
     4811                                                 Int4 i  = ( v - LastOld);
     4812                                                 //  if the old is on vertex => warning
     4813                                                 // else the old is on edge => ok
     4814                                                 vog[i] = vog[old];
     4815                                                 //                 vog[i].mv = v;
     4816                                                 //g[i].ge = ;
     4817                                                 //og[i].abcisse = ;
     4818                                                }
     4819
     4820                                        }
     4821                                }
     4822
     4823                        NbVerticesOnGeomVertex = n;
     4824                  }
     4825                SetVertexFieldOn();
     4826
     4827
     4828                if (vlast >= vend)
     4829                  { 
     4830                        cerr << " Not enougth vertices to crack the mesh we need " << nbv << " vertices " << endl;
     4831                        MeshError(555,this);
     4832                  }
     4833                cout << "  NbCrackedVertices " <<  NbCrackedVertices << endl;
     4834                CurrentTh = CurrentThOld;
     4835                return  NbCrackedVertices;
     4836        }
     4837        /*}}}1*/
     4838        /*FUNCTION Triangles::FindTriangleContening{{{1*/
     4839        Triangle * Triangles::FindTriangleContening(const I2 & B,Icoor2 dete[3], Triangle *tstart) const {
     4840                Triangle * t=0;
     4841                int j,jp,jn,jj;
     4842                if (tstart)
     4843                 t=tstart;
     4844                else
     4845                  {
     4846                        assert(quadtree);
     4847                        Vertex *a = quadtree->NearestVertex(B.x,B.y) ;
     4848
     4849                        if (! a || !a->t ) {
     4850                                if (a)
     4851                                  {cerr << " Attention PB TriangleConteningTheVertex  vertex number=" << Number(a) << endl;
     4852                                        cerr  << "We forget a call to ReMakeTriangleContainingTheVertex" << endl;}
     4853                                        cerr << " Pb with " << B << toR2(B) << endl;
     4854                                        MeshError(7777);
     4855                        }
     4856                        assert(a>= vertices && a < vertices+nbv);
     4857                        //  int k=0;
     4858                        t = a->t;
     4859                        assert(t>= triangles && t < triangles+nbt);
     4860
     4861                  }
     4862                Icoor2  detop ;
     4863                int kkkk =0; // number of test triangle
     4864
     4865                while ( t->det < 0)
     4866                  { // the initial triangles is outside 
     4867                        int k0=(*t)(0) ?  ((  (*t)(1) ? ( (*t)(2) ? -1 : 2) : 1  )) : 0;
     4868                        assert(k0>=0); // k0 the NULL  vertex
     4869                        int k1=NextVertex[k0],k2=PreviousVertex[k0];
     4870                        dete[k0]=det(B,(*t)[k1],(*t)[k2]);
     4871                        dete[k1]=dete[k2]=-1;     
     4872                        if (dete[k0] > 0) // outside B
     4873                         return t;
     4874                        t = t->TriangleAdj(OppositeEdge[k0]);
     4875                        assert(kkkk++ < 2);
     4876                  }
     4877
     4878                jj=0;
     4879                detop = det(*(*t)(VerticesOfTriangularEdge[jj][0]),*(*t)(VerticesOfTriangularEdge[jj][1]),B);
     4880
     4881                while(t->det  > 0 )
     4882                  {
     4883                        assert( kkkk++ < 2000 );
     4884                        j= OppositeVertex[jj];
     4885                        dete[j] = detop;  //det(*b,*s1,*s2);
     4886                        jn = NextVertex[j];
     4887                        jp = PreviousVertex[j];
     4888                        dete[jp]= det(*(*t)(j),*(*t)(jn),B);
     4889                        dete[jn] = t->det-dete[j] -dete[jp];
     4890
     4891                        // count the number k of  dete <0
     4892                        int k=0,ii[3];
     4893                        if (dete[0] < 0 ) ii[k++]=0;
     4894                        if (dete[1] < 0 ) ii[k++]=1;
     4895                        if (dete[2] < 0 ) ii[k++]=2;
     4896                        // 0 => ok
     4897                        // 1 => go in way 1
     4898                        // 2 => two way go in way 1 or 2 randomly
     4899
     4900                        if (k==0)
     4901                         break;
     4902                        if (k == 2 && BinaryRand())
     4903                         Exchange(ii[0],ii[1]);
     4904                        assert ( k  < 3);
     4905                        TriangleAdjacent t1 = t->Adj(jj=ii[0]);
     4906                        if ((t1.det() < 0 ) && (k == 2))
     4907                         t1 = t->Adj(jj=ii[1]);
     4908                        t=t1;
     4909                        j=t1;// for optimisation we now the -det[OppositeVertex[j]];
     4910                        detop = -dete[OppositeVertex[jj]];
     4911                        jj = j;
     4912                  }
     4913
     4914                if (t->det<0) // outside triangle
     4915                 dete[0]=dete[1]=dete[2]=-1,dete[OppositeVertex[jj]]=detop;
     4916                //  NbOfTriangleSearchFind += kkkk; 
     4917                return t;
     4918        }
     4919        /*}}}1*/
    16504920
    16514921} // end of namespace bamg
Note: See TracChangeset for help on using the changeset viewer.