Index: sm/trunk/src/c/Bamgx/GeometricalEdge.cpp
===================================================================
--- /issm/trunk/src/c/Bamgx/GeometricalEdge.cpp	(revision 2819)
+++ 	(revision )
@@ -1,123 +1,0 @@
-#include <cstdio>
-#include <string.h>
-#include <cmath>
-#include <time.h>
-#include <iostream>
-
-#include "Mesh2.h"
-#include "QuadTree.h"
-#include "SetOfE4.h"
-using namespace std;
-
-namespace bamg {
-
-	/*Constructor/Destructor*/
-
-	/*Others*/
-	/*FUNCTION GeometricalEdge::R1tg{{{1*/
-	Real8 GeometricalEdge::R1tg(Real8 theta,R2 & t) const // 1/R of radius of cuvature
-	  { R2 A=v[0]->r,B=v[1]->r;
-		Real8 dca,dcb,dcta,dctb;
-		Real8 ddca,ddcb,ddcta,ddctb;
-		// Real8 t1 = 1 -theta;
-		// Real8 t1t1 = t1*t1;
-		Real8 tt = theta*theta;
-		assert( theta >=0);
-		assert( theta <=1);
-		if (TgA()) 
-		 if (TgB()) // interpolation d'hermite
-			{ //cb =  theta*theta*(3-2*theta);
-			 dcb = 6*theta*(1-theta);
-			 ddcb = 6*(1-2*theta);
-			 //ca =  1-cb;     
-			 dca = -dcb;
-			 ddca = -ddcb;
-
-			 // cta = (1-theta)*(1-theta)*theta;
-			 dcta =  (3*theta - 4)*theta + 1;
-			 ddcta=6*theta-4;
-
-			 //ctb = (theta-1)*theta*theta ;
-			 dctb = 3*tt - 2*theta;
-			 ddctb = 6*theta-2;
-			}
-		 else { // 1-t*t, t-t*t, t*t
-			 Real8 t = theta;
-			 // cb = t*t;
-			 dcb = 2*t;
-			 ddcb = 2;
-			 //ca = 1-cb;
-			 dca = -dcb;
-			 ddca = -2;
-			 // cta= t-cb;
-			 dcta = 1-dcb;
-			 ddcta = -ddcb;
-			 // ctb =0;
-			 dctb=0;    
-			 ddctb=0;    
-		 }    
-		else
-		 if (TgB()){
-			 Real8 t = 1-theta;
-			 //ca = t*t;
-			 dca = -2*t;
-			 ddca = 2;
-			 //cb = 1-ca;
-			 dcb = -dca;
-			 ddcb = -2;
-			 //ctb= -t+ca;
-			 dctb = 1+dca;
-			 ddctb= ddca;
-			 //cta=0;    
-			 dcta =0;
-			 ddcta =0;
-		 }
-		 else {t=B-A;return 0;} // lagrange P1
-		R2 d =  A*dca + B*dcb + tg[0]* dcta + tg[1] * dctb;
-
-		R2 dd =  A*ddca + B*ddcb + tg[0]* ddcta + tg[1] * ddctb;
-		Real8 d2=(d,d);
-		Real8 sd2 = sqrt(d2);
-		t=d;
-		if(d2>1.0e-20) {t/=sd2;return Abs(Det(d,dd))/(d2*sd2);}
-		else return 0;
-	  }
-	/*}}}1*/
-	/*FUNCTION GeometricalEdge::F{{{1*/
-	R2 GeometricalEdge::F(Real8 theta) const // parametrization of the curve edge
-	  { R2 A=v[0]->r,B=v[1]->r;
-		Real8 ca,cb,cta,ctb;
-		assert( theta >=-1e-12);
-		assert( theta <=1+1e-12);
-		if (TgA()) 
-		 if (TgB()) // interpolation d'hermite
-			{ cb =  theta*theta*(3-2*theta);
-			 ca =  1-cb;     
-			 cta = (1-theta)*(1-theta)*theta;
-			 ctb = (theta-1)*theta*theta ;
-			 //  if(ref==4 || ref==5)
-			 //  cout << " FFF " << tg[0] << tg[1] << A << B << " => " << A*ca + B*cb + tg[0]* cta + tg[1] * ctb << endl;
-			}
-		 else { // 1-t*t, t-t*t, t*t
-			 Real8 t = theta;
-			 cb = t*t;
-			 ca = 1-cb;
-			 cta= t-cb;
-			 ctb=0;    
-		 }    
-		else
-		 if (TgB()){
-			 Real8 t = 1-theta;
-			 ca = t*t;
-			 cb = 1-ca;
-			 ctb= -t+ca;
-			 cta=0;    
-		 }
-		 else {
-			 ca =(1-theta),cb = theta,cta=ctb=0; // lagrange P1
-		 }
-		return A*ca + B*cb + tg[0]* cta + tg[1] * ctb;
-	  }
-	/*}}}1*/
-
-}
Index: sm/trunk/src/c/Bamgx/Geometry.cpp
===================================================================
--- /issm/trunk/src/c/Bamgx/Geometry.cpp	(revision 2819)
+++ 	(revision )
@@ -1,1031 +1,0 @@
-#include "../shared/shared.h"
-#include "../include/macros.h"
-#include "../toolkits/toolkits.h"
-
-#include <cstdio>
-#include <cstring>
-#include <cmath>
-#include <ctime>
-#include "Mesh2.h"
-#include "QuadTree.h"
-#include "SetOfE4.h"
-
-
-namespace bamg {
-
-	static const  Direction NoDirOfSearch=Direction();
-
-	/*Constructors/Destructors*/
-
-	/*IO*/
-	/*FUNCTION Geometry::WriteGeometry{{{1*/
-	void Geometry::WriteGeometry(BamgGeom* bamggeom, BamgOpts* bamgopts){
-
-		int verbose;
-		int nbreq=0;
-		int nbreqv=0;
-		int nbtan=0;
-		int nbcracked=0;
-		int i,count;
-
-		verbose=bamgopts->verbose;
-
-		//Vertices
-		if(verbose>3) printf("      writing Vertices\n");
-		bamggeom->NumVertices=nbv;
-		xfree((void**)&bamggeom->Vertices);
-		if (nbv){
-			bamggeom->Vertices=(double*)xmalloc(3*nbv*sizeof(double));
-			for (i=0;i<nbv;i++){
-				bamggeom->Vertices[i*3+0]=vertices[i].r.x;
-				bamggeom->Vertices[i*3+1]=vertices[i].r.y;
-				bamggeom->Vertices[i*3+2]=vertices[i].ref();
-
-				//update counters
-				if (vertices[i].Required()) nbreqv++;
-			}
-		}
-		else{
-			bamggeom->Vertices=NULL;
-		}
-
-		//Edges
-		if(verbose>3) printf("      writing Edges\n");
-		bamggeom->NumEdges=nbe;
-		xfree((void**)&bamggeom->Edges);
-		if (nbe){
-			bamggeom->Edges=(double*)xmalloc(3*nbe*sizeof(double));
-			for (i=0;i<nbe;i++){
-				bamggeom->Edges[i*3+0]=Number(edges[i][0])+1; //back to Matlab indexing
-				bamggeom->Edges[i*3+1]=Number(edges[i][1])+1; //back to Matlab indexing
-				//bamggeom->Edges[i*3+2]=(double)edges[i].ref(); //TEST does not compile???
-				bamggeom->Edges[i*3+2]=1; //TEST for now
-
-				//update counters
-				if (edges[i].Required()) nbreq++;
-				if (edges[i].Cracked()){
-					if (i<=Number(edges[i].link)) nbcracked++;
-				}
-				if (edges[i].TgA() && edges[i][0].Corner()) nbtan++;
-				if (edges[i].TgB() && edges[i][1].Corner()) nbtan++;
-			}
-		}
-		else{
-			bamggeom->Edges=NULL;
-		}
-
-		//CrackedEdges
-		if(verbose>3) printf("      writing CrackedEdges\n");
-		bamggeom->NumCrackedEdges=nbcracked;
-		xfree((void**)&bamggeom->CrackedEdges);
-		if (nbcracked){
-			bamggeom->CrackedEdges=(double*)xmalloc(2*nbcracked*sizeof(double));
-			count=0;
-			for (i=0;i<nbe;i++){
-				if (edges[i].Cracked()){
-					if (i<=Number(edges[i].link)){
-						bamggeom->CrackedEdges[count*2+0]=i+1;                     //back to Matlab indexing
-						bamggeom->CrackedEdges[count*2+1]=Number(edges[i].link)+1; //back to Matlab indexing
-						count=count+1;
-					}
-				}
-			}
-		}
-		else{
-			bamggeom->CrackedEdges=NULL;
-		}
-
-		//RequiredEdges
-		if(verbose>3) printf("      writing RequiredEdges\n");
-		bamggeom->NumRequiredEdges=nbreq;
-		xfree((void**)&bamggeom->RequiredEdges);
-		if (nbreq){
-			bamggeom->RequiredEdges=(double*)xmalloc(1*nbreq*sizeof(double));
-			count=0;
-			for (i=0;i<nbe;i++){
-				if (edges[i].Required()){
-					bamggeom->RequiredEdges[count]=i+1; //back to Matlab indexing
-					count=count+1;
-				}
-			}
-		}
-		else{
-			bamggeom->RequiredEdges=NULL;
-		}
-
-		//No corners
-
-		//RequiredVertices
-		if(verbose>3) printf("      writing RequiredVertices\n");
-		bamggeom->NumRequiredVertices=nbreqv;
-		xfree((void**)&bamggeom->RequiredVertices);
-		if (nbreqv){
-			bamggeom->RequiredVertices=(double*)xmalloc(1*nbreqv*sizeof(double));
-			count=0;
-			for (i=0;i<nbe;i++){
-				if (vertices[i].Required()){
-					bamggeom->RequiredVertices[count]=i+1; //back to Matlab indexing
-					count=count+1;
-				}
-			}
-		}
-		else{
-			bamggeom->RequiredVertices=NULL;
-		}
-
-		//SubDomains
-		if(verbose>3) printf("      writing SubDomains\n");
-		bamggeom->NumSubDomains=NbSubDomains;
-		xfree((void**)&bamggeom->SubDomains);
-		if (NbSubDomains){
-			bamggeom->SubDomains=(double*)xmalloc(4*NbSubDomains*sizeof(double));
-			for (i=0;i<NbSubDomains;i++){
-				bamggeom->SubDomains[4*i+0]=2;
-				bamggeom->SubDomains[4*i+1]=Number(subdomains[i].edge)+1; //back to Matlab indexing
-				bamggeom->SubDomains[4*i+2]=subdomains[i].sens;
-				bamggeom->SubDomains[4*i+3]=subdomains[i].ref;
-			}
-		}
-		else{
-			bamggeom->SubDomains=NULL;
-		}
-
-		//TangentAtEdges
-		if(verbose>3) printf("      writing TangentAtEdges\n");
-		bamggeom->NumTangentAtEdges=nbtan;
-		xfree((void**)&bamggeom->TangentAtEdges);
-		if (nbtan){
-			bamggeom->TangentAtEdges=(double*)xmalloc(4*nbtan*sizeof(double));
-			count=0;
-			for (i=0;i<nbe;i++){
-				if (edges[i].TgA() && edges[i][0].Corner()){
-					bamggeom->TangentAtEdges[4*i+0]=i+1; //back to Matlab indexing
-					bamggeom->TangentAtEdges[4*i+1]=1;
-					bamggeom->TangentAtEdges[4*i+2]=edges[i].tg[0].x;
-					bamggeom->TangentAtEdges[4*i+3]=edges[i].tg[0].y;
-				}
-				if (edges[i].TgB() && edges[i][1].Corner()){
-					bamggeom->TangentAtEdges[4*i+0]=i+1; //back to Matlab indexing
-					bamggeom->TangentAtEdges[4*i+1]=2;
-					bamggeom->TangentAtEdges[4*i+2]=edges[i].tg[1].x;
-					bamggeom->TangentAtEdges[4*i+3]=edges[i].tg[2].y;
-				}
-				count=count+1;
-			}
-		}
-		else{
-			bamggeom->TangentAtEdges=NULL;
-		}
-	}
-	/*}}}1*/
-	/*FUNCTION Geometry::ReadGeometry{{{1*/
-	void Geometry::ReadGeometry(BamgGeom* bamggeom,BamgOpts* bamgopts){
-
-		int verbose;
-		nbiv=nbv=nbvx=0;
-		nbe=nbt=nbtx=0;
-		NbOfCurves=0;
-
-		Real8 Hmin = HUGE_VAL;// the infinie value 
-		Int4 hvertices=0;
-		int i,j,k,n;
-
-		//initialize some variables
-		int Version=1,dim=2;
-		nbv=bamggeom->NumVertices;
-		nbe=bamggeom->NumEdges;
-		nbvx = nbv;
-		nbiv = nbv;
-		verbose=bamgopts->verbose;
-
-		//some checks
-		if (bamggeom->NumVertices<=0 || bamggeom->Vertices==NULL){
-			throw ErrorException(__FUNCT__,exprintf("the domain provided does not contain any vertex"));
-		}
-		if (bamggeom->NumEdges<=0 || bamggeom->Edges==NULL){
-			throw ErrorException(__FUNCT__,exprintf("the domain provided does not contain any edge"));
-		}
-
-		//Vertices
-		if (bamggeom->Vertices){
-			if(verbose>3) printf("      processing Vertices\n");
-			vertices = new GeometricalVertex[nbvx];
-			for (i=0;i<nbv;i++) {
-				vertices[i].r.x=(double)bamggeom->Vertices[i*3+0];
-				vertices[i].r.y=(double)bamggeom->Vertices[i*3+1];
-				vertices[i].ReferenceNumber=(Int4)bamggeom->Vertices[i*3+2];
-				vertices[i].DirOfSearch=NoDirOfSearch;
-				vertices[i].color =0;
-				vertices[i].Set();
-			}
-			//find domain extrema for pmin,pmax
-			pmin =  vertices[0].r;
-			pmax =  vertices[0].r;
-			for (i=0;i<nbv;i++) {
-				pmin.x = Min(pmin.x,vertices[i].r.x);
-				pmin.y = Min(pmin.y,vertices[i].r.y);
-				pmax.x = Max(pmax.x,vertices[i].r.x);
-				pmax.y = Max(pmax.y,vertices[i].r.y);
-			}
-			R2 DD05 = (pmax-pmin)*0.05;
-			pmin -=  DD05;
-			pmax +=  DD05;
-			coefIcoor= (MaxICoor)/(Max(pmax.x-pmin.x,pmax.y-pmin.y));
-			if(coefIcoor <=0){
-				throw ErrorException(__FUNCT__,exprintf("coefIcoor should be positive"));
-			}
-		}
-		else{
-			throw ErrorException(__FUNCT__,exprintf("No Vertex provided"));
-		}
-
-		//Edges
-		if (bamggeom->Edges){
-			int i1,i2;
-			R2 zero2(0,0);
-			Real4 *len =0;
-
-			if(verbose>3) printf("      processing Edges\n");
-			edges = new GeometricalEdge[nbe];
-
-			if (!hvertices) {
-				len = new Real4[nbv];
-				for(i=0;i<nbv;i++)
-				 len[i]=0;
-			}
-
-			for (i=0;i<nbe;i++){
-				i1=(int)bamggeom->Edges[i*3+0]-1; //-1 for C indexing
-				i2=(int)bamggeom->Edges[i*3+1]-1; //-1 for C indexing
-				edges[i].ref=(Int4)bamggeom->Edges[i*3+2];
-				edges[i].v[0]=  vertices + i1;
-				edges[i].v[1]=  vertices + i2;
-				R2 x12 = vertices[i2].r-vertices[i1].r;
-				Real8 l12=sqrt((x12,x12));
-				edges[i].tg[0]=zero2;
-				edges[i].tg[1]=zero2;
-				edges[i].SensAdj[0] = edges[i].SensAdj[1] = -1;
-				edges[i].Adj[0] = edges[i].Adj[1] = 0;
-				edges[i].flag = 0;
-				if (!hvertices) {
-					vertices[i1].color++;
-					vertices[i2].color++;
-					len[i1] += l12;
-					len[i2] += l12;
-				}
-
-				Hmin = Min(Hmin,l12);
-			}
-
-			// definition  the default of the given mesh size 
-			if (!hvertices){
-				for (i=0;i<nbv;i++) 
-				 if (vertices[i].color > 0) 
-				  vertices[i].m=  Metric(len[i] /(Real4) vertices[i].color);
-				 else 
-				  vertices[i].m=  Metric(Hmin);
-				delete [] len;
-			}
-		}
-		else{
-			throw ErrorException(__FUNCT__,exprintf("No edges provided"));
-		}
-
-		//hVertices
-		if(bamggeom->hVertices){
-			if(verbose>3) printf("      processing hVertices\n");
-			for (i=0;i< nbv;i++){
-				vertices[i].m=Metric((Real4)bamggeom->hVertices[i]);
-			}
-		}
-		else{
-			if(verbose>3) printf("      no hVertices found\n");
-		}
-
-		//MetricVertices
-		if(bamggeom->MetricVertices){
-			if(verbose>3) printf("      processing MetricVertices\n");
-			hvertices=1;
-			for (i=0;i< nbv;i++) {
-				vertices[i].m = Metric((Real4)bamggeom->MetricVertices[i*3+0],(Real4)bamggeom->MetricVertices[i*3+1],(Real4)bamggeom->MetricVertices[i*3+2]);
-			}
-		}
-		else{
-			if(verbose>3) printf("      no MetricVertices found\n");
-		}
-
-		//h1h2VpVertices
-		if(bamggeom->h1h2VpVertices){
-			if(verbose>3) printf("      processing h1h2VpVertices\n");
-			Real4 h1,h2,v1,v2;
-			hvertices =1;
-			for (i=0;i< nbv;i++) {
-				h1=(Real4)bamggeom->MetricVertices[i*4+0];
-				h2=(Real4)bamggeom->MetricVertices[i*4+1];
-				v1=(Real4)bamggeom->MetricVertices[i*4+2];
-				v2=(Real4)bamggeom->MetricVertices[i*4+3];
-				vertices[i].m = Metric(MatVVP2x2(1/(h1*h1),1/(h2*h2),D2(v1,v2)));
-			}
-		}
-		else{
-			if(verbose>3) printf("      no h1h2VpVertices found\n");
-		}
-
-		//MaximalAngleOfCorner
-		if (bamgopts->MaximalAngleOfCorner){
-			if(verbose>3) printf("      processing MaximalAngleOfCorner\n");
-			MaximalAngleOfCorner=bamgopts->MaximalAngleOfCorner*Pi/180;
-		}
-		else{
-			if(verbose>3) printf("      no MaximalAngleOfCorner found\n");
-		}
-
-		//TangentAtEdges
-		if (bamggeom->TangentAtEdges){
-			if(verbose>3) printf("      processing TangentAtEdges");
-			int n,i,j,k;
-			R2 tg;
-
-			n=bamggeom->NumTangentAtEdges;
-			for (k=0;k<n;k++) {
-				i=(int)bamggeom->TangentAtEdges[k*4+0]-1; //for C indexing
-				j=(int)bamggeom->TangentAtEdges[k*4+1]-1; //for C indexing
-				tg.x=bamggeom->TangentAtEdges[k*4+2];
-				tg.y=bamggeom->TangentAtEdges[k*4+3];
-				if (j!=0 && j!=1){
-					throw ErrorException(__FUNCT__,exprintf("TangentAtEdges second index should be 1 or 2 only"));
-				}
-				edges[i].tg[j] = tg;
-			}
-		}
-		else{
-			if(verbose>3) printf("      no TangentAtEdges found\n");
-		}
-
-		//Corners
-		if(bamggeom->Corners){
-			if(verbose>3) printf("      processing Corners");
-			n=bamggeom->NumCorners;
-			for (i=0;i<n;i++) {     
-				j=(int)bamggeom->Corners[i]-1; //for C indexing
-				if (j>nbv-1 || j<0){
-					throw ErrorException(__FUNCT__,exprintf("Bad corner definition: should in [0 %i]",nbv));
-				}
-				vertices[j].SetCorner();
-				vertices[j].SetRequired();  }
-		}
-		else{
-			if(verbose>3) printf("      no Corners found\n");
-		}
-
-		//RequiredVertices
-		if(bamggeom->RequiredVertices){
-			if(verbose>3) printf("      processing RequiredVertices");
-			n=bamggeom->NumRequiredVertices;
-			for (i=0;i<n;i++) {     
-				j=(int)bamggeom->RequiredVertices[i]-1; //for C indexing
-				if (j>nbv-1 || j<0){
-					throw ErrorException(__FUNCT__,exprintf("Bad RequiredVerticess  definition: should in [0 %i]",nbv));
-				}
-				vertices[j].SetRequired();  }
-		}
-		else{
-			if(verbose>3) printf("      no RequiredVertices found\n");
-		}
-
-		//RequiredEdges
-		if(bamggeom->RequiredEdges){
-			if(verbose>3) printf("      processing RequiredEdges");
-			n=bamggeom->NumRequiredEdges;
-			for (i=0;i<n;i++) {     
-				j=(int)bamggeom->RequiredEdges[i]-1; //for C indexing
-				if (j>nbe-1 || j<0){
-					throw ErrorException(__FUNCT__,exprintf("Bad RequiredEdges definition: should in [0 %i]",nbv));
-				}
-				edges[j].SetRequired();  }
-		}
-		else{
-			if(verbose>3) printf("      no RequiredEdges found\n");
-		}
-
-		//SubDomain
-		if(bamggeom->SubDomains){
-			Int4 i0,i1,i2,i3;
-			if(verbose>3) printf("      processing SubDomains\n");
-			NbSubDomains=bamggeom->NumSubDomains;
-			subdomains = new GeometricalSubDomain[NbSubDomains];
-			for (i=0;i<NbSubDomains;i++) {
-				i0=(int)bamggeom->SubDomains[i*4+0];
-				i1=(int)bamggeom->SubDomains[i*4+1];
-				i2=(int)bamggeom->SubDomains[i*4+2];
-				i3=(int)bamggeom->SubDomains[i*4+3];
-				if (i0!=2) throw ErrorException(__FUNCT__,exprintf("Bad Subdomain definition: first number should be 2 (for Edges)"));
-				if (i1>nbe || i1<=0) throw ErrorException(__FUNCT__,exprintf("Bad Subdomain definition: second number should in [1 %i] (edge number)",nbe));
-				subdomains[i].edge=edges + (i1-1);
-				subdomains[i].sens = (int) i2;
-				subdomains[i].ref = i3;
-			}
-		}
-		else{
-			if(verbose>3) printf("      no SubDomains found\n");
-		}
-	}
-	/*}}}1*/
-
-	/*Other*/
-
-void Geometry::EmptyGeometry()  // empty geometry
-  {
-  OnDisk=0;
-  NbRef=0;
-  name =0;
-  quadtree=0;
-  curves=0;
- // edgescomponante=0;
-  triangles=0;
-  edges=0;
-  vertices=0;
-  NbSubDomains=0;
-  //  nbtf=0;
-//  BeginOfCurve=0;  
-  nbiv=nbv=nbvx=0;
-  nbe=nbt=nbtx=0;
-  NbOfCurves=0;
-//  BeginOfCurve=0;
-  subdomains=0;
-  MaximalAngleOfCorner = 10*Pi/180;
-  }
-
-
-
-Geometry::Geometry(const Geometry & Gh)
- { Int4 i;
-   *this = Gh;
-   NbRef =0;
-   quadtree=0;
-   name = new char[strlen(Gh.name)+4];
-   strcpy(name,"cp:");
-   strcat(name,Gh.name);
-   vertices = nbv ? new GeometricalVertex[nbv] : NULL;
-   triangles = nbt ? new  Triangle[nbt]:NULL;
-   edges = nbe ? new GeometricalEdge[nbe]:NULL;
-   curves= NbOfCurves ? new Curve[NbOfCurves]:NULL;
-   subdomains = NbSubDomains ? new GeometricalSubDomain[NbSubDomains]:NULL;
-   for (i=0;i<nbv;i++)
-     vertices[i].Set(Gh.vertices[i],Gh,*this);
-   for (i=0;i<nbe;i++)
-     edges[i].Set(Gh.edges[i],Gh,*this);
-   for (i=0;i<NbOfCurves;i++)
-     curves[i].Set(Gh.curves[i],Gh,*this);
-   for (i=0;i<NbSubDomains;i++)
-     subdomains[i].Set(Gh.subdomains[i],Gh,*this);
-     
-   //    for (i=0;i<nbt;i++)
-   //      triangles[i].Set(Gh.triangles[i],Gh,*this);
-   assert(!nbt);   
- }
-
-
-GeometricalEdge* Geometry::Contening(const R2 P,  GeometricalEdge * start) const
-{
-  GeometricalEdge* on =start,* pon=0;
-  // walk with the cos on geometry
-  //  cout << P ;
-  int k=0;
-   while(pon != on)
-     {  
-       pon = on;
-       assert(k++<100);
-       R2 A= (*on)[0];
-       R2 B= (*on)[1];
-       R2 AB = B-A;
-       R2 AP = P-A;
-       R2 BP = P-B;
-       //   cout << "::  " << on - edges << " "  <<  AB*AP  << " " <<  AB*BP << " " << A << B << endl;
-       if ( (AB,AP) < 0) 
-	 on = on->Adj[0];
-       else if ( (AB,BP)  > 0) 
-	 on = on->Adj[1];
-       else
-	 return on;
-     }
-   return on;
-}
-GeometricalEdge* Geometry::ProjectOnCurve(const Edge & e,Real8 s,Vertex &V,VertexOnGeom &GV ) const 
- {  
-    Real8 save_s=s;
-    int NbTry=0;
-retry:    
-    s=save_s;
-    GeometricalEdge * on = e.on;
-    assert(on);
-    assert( e[0].on &&  e[1].on);
-    const Vertex &v0=e[0],&v1=e[1];
-    V.m = Metric(1.0-s, v0,s, v1);
-#define MXE__LINE  __LINE__+1
-    const int mxe =100;
-    GeometricalEdge *ge[mxe+1];
-    int    sensge[mxe+1];
-    Real8  lge[mxe+1];
-    int bge=mxe/2,tge=bge;
-    ge[bge] = e.on;
-    sensge[bge]=1;
-
-    R2 V0 = v0,V1=v1,V01=V1-V0;
-    VertexOnGeom  vg0= *v0.on,  vg1=*v1.on;
-    if(NbTry) cout << "bug: s==== " << s << " e=" <<  V0 << " " << V1 << endl;
-
-    //    GeometricalEdge * eg0 = e.on,* eg1 = e.on, *eg=NULL;
-    GeometricalEdge * eg0=on, *eg1=on;
-    R2 Ag=(R2) (*on)[0],Bg=(R2)(*on)[1],AB=Bg-Ag; 
-    if(NbTry) cout <<" G edge= " << Ag << Bg << endl << " v edge" << V01 << " v geom " << AB  <<  (V01,AB) <<endl; 
-    int OppositeSens = (V01,AB) < 0;
-    int sens0=0,sens1=1;
-    if (OppositeSens)
-      s=1-s,Exchange(vg0,vg1),Exchange(V0,V1);
-    if(NbTry) cout << "bug: edge = " << v0.r << " -> " << v1.r << endl 
-		   << "sg 0 = " << vg0 
-		   << " on = " << Number(on) << ":" << Ag << Bg << "; " 
-		   <<  " sg 1= " << vg1 
-		   << "--------------------------------------------" << endl;
-    while (eg0 != (GeometricalEdge*) vg0  &&  (*eg0)(sens0) != (GeometricalVertex*) vg0)
-      { 
-      if (bge<=0) {
-	//          int kkk;
-          // if (NbTry) cout <<"Read (int) to Show Sioux window", cin >> kkk ;
-	       if(NbTry) 
-	          {
-		    cerr << " -- Fatal Error: on the class triangles before call Geometry::ProjectOnCurve" << endl; 
-		    cerr << "   The mesh of the  Geometry is to fine: ";
-		    cerr << "     1)  a mesh edge  contening more than "<< mxe/2 << " geometrical edges." << endl;
-		    cerr << "     2)  code bug : be sure that we call   Triangles::SetVertexFieldOn() before " << endl;
-		    cerr << "   To solve the problem do a coarsening of the geometrical mesh " << endl;
-		    cerr << " or change the constant value of mxe in " << __FILE__ << " line " << MXE__LINE << "( dangerous way )" << endl;	  
-		    MeshError(222);
-		  }
-	    NbTry++;
-	    goto retry;}
-        GeometricalEdge* tmpge = eg0;
-	 if(NbTry)
-		cout << "bug: --Edge @" <<  Number(tmpge)  << " = "<< Number(eg0) << ":" <<Number(eg0->Adj[0]) << "," <<  
-			 Number(eg0->Adj[1]) <<"," ;
-	ge[--bge] =eg0 = eg0->Adj[sens0];
-	assert(bge>=0 && bge <= mxe);
-	sens0 = 1-( sensge[bge] = tmpge->SensAdj[sens0]);
-	if(NbTry)
-		cout << "bug: Edge "  <<  Number(eg0) << " "<< 1-sens0 <<  " S "
-		     << Number((*eg0)[1-sens0]) <<":" << Number(eg0->Adj[0]) << "," 
-		     <<  Number(eg0->Adj[1]) <<"," << endl
-	 	     <<Number(eg0)<< (*eg0)[sens0].r << "v = " << Number((*eg1)(sens0)) << " e = " << eg0 <<  endl;
-     }
-      if(NbTry) cout << Number((GeometricalEdge*) vg1) << " " << Number((GeometricalVertex*) vg1) << endl;
-    while (eg1 != (GeometricalEdge*) vg1  &&  (*eg1)(sens1) != (GeometricalVertex*) vg1)
-      { 
-        if(tge>=mxe ) { 
-	  cerr << " --Fatal Error: on the class triangles before call Geometry::ProjectOnCurve" << endl; 
-	  NbTry++;
-	  if (NbTry<2) goto retry;
-	  cerr << "   The mesh of the  Geometry is to fine:" ;
-	  cerr << "     1)  a mesh edge  contening more than "<< mxe/2 << " geometrical edges." << endl;
-	  cerr << "     2)  code bug : be sure that we call   Triangles::SetVertexFieldOn() before " << endl;
-	  cerr << "   To solve the problem do a coarsening of the geometrical mesh " << endl;
-	  cerr << " or change the constant value of mxe in " << __FILE__ << " line " << MXE__LINE << "( dangerous way )" << endl;	
-	  MeshError(223);
-	}
-
-	GeometricalEdge* tmpge = eg1;
-	if(NbTry)
-		cout << "++Edge @" << tmpge << " = " <<  Number(eg1) <<"%" << Number(eg1->Adj[0]) << "," 
-		 <<  Number(eg1->Adj[1]) <<"," ;
-	ge[++tge] =eg1 = eg1->Adj[sens1];
-	sensge[tge]= sens1 = 1-tmpge->SensAdj[sens1];
-	assert(tge>=0 && tge <= mxe);
-         if(NbTry)
-		cout << "  Edge "  <<  Number(eg1) << " " << sens1 << " S "
-		     <<Number((*eg1)[sens1]) <<"%"<< Number(eg1->Adj[0]) << "," <<  Number(eg1->Adj[1]) <<"," 
-	             <<Number(eg1)<< (*eg1)[sens1].r << "v = " << Number((*eg1)(sens1)) << " e = " << Number(eg1) <<  endl;
-      }
-
-    	if(NbTry)    cout << endl;
-        
-
-    if ( (*eg0)(sens0) == (GeometricalVertex*) vg0 )
-      vg0 = VertexOnGeom( *(Vertex *) vg0,*eg0,sens0);
-    
-    if ( (*eg1)(sens1) == (GeometricalVertex*) vg1)
-       vg1 = VertexOnGeom( *(Vertex *) vg1,*eg1,sens1);
-
-    Real8 sg;
-    //   cout << "           " << Number(on) << " " <<  Number(eg0) << " " <<  Number(eg1) << " "  ; 
-    if (eg0 == eg1) { 
-       register Real8 s0= vg0,s1=vg1;
-       sg =  s0 * (1.0-s) +  s * s1;
-       //    cout <<"                s0=" << s0 << " s1=" << s1 
-       //             << " s = " << s << " sens= " << OppositeSens << "\t\t sg = " << sg << endl ;
-       on=eg0;}
-    else {
-       R2 AA=V0,BB;
-       Real8 s0,s1;
-       
-       //cout << endl << "s= " << s << Number(eg0) << " " << (Real8) vg0 << " " 
-       //	    << Number(eg1) << " " << (Real8) vg1 << V0 << V1 << "  Interpol = " 
-       // << V0*(1-s)+V1*s << ";;; " <<  endl;
-       int i=bge;
-       Real8 ll=0;
-       for(i=bge;i<tge;i++) 
-	 {
-	   assert( i>=0 && i <= mxe);
-	   BB =  (*ge[i])[sensge[i]];
-	   lge[i]=ll += Norme2(AA-BB);
-	   //   cout << " ll " << i << BB << ll << " " <<sensge[i] <<" on = " <<
-	   // Number(ge[i]) << " sens= " << sensge[i] ;
-	   AA=BB ;}
-       lge[tge]=ll+=Norme2(AA-V1); 
-       // cout << " ll " << tge << " " << ll <<  sensge[tge] 
-       //	     <<" on = " << Number(ge[tge]) <<  " sens= " << sensge[tge] << endl;
-    // search the geometrical edge
-      assert(s <= 1.0);
-      Real8 ls= s*ll;
-      on =0;
-      s0 = vg0;
-      s1= sensge[bge];
-      Real8 l0=0,l1;
-      i=bge;
-      while (  (l1=lge[i]) < ls ) {
-	assert(i >= 0 && i <= mxe);
-	i++,s0=1-(s1=sensge[i]),l0=l1;}
-      on=ge[i];
-      if (i==tge) 
-	s1=vg1;
-     
-      s=(ls-l0)/(l1-l0);
-      //  cout << "on =" << Number(on) << sens0 << sens1 <<  "s0  " << s0 << " s1 =" 
-      //	     << s1 << " l0 =" << l0 << " ls= " << ls << " l1= " << l1 << " s= " << s;
-       sg =  s0 * (1.0-s) +  s * s1;    
-       } 
-    assert(on);
-    // assert(sg && sg-1);
-    V.r= on->F(sg);
-    //  if (eg0 != eg1) 
-    //        cout << "----- sg = "<< sg << " Sens =" << OppositeSens << " Edge = " 
-    //     << Number(on) <<"  V=" << V << endl;
-    GV=VertexOnGeom(V,*on,sg);
-    return on;
- }
-
-void Geometry::AfterRead()
- {// -----------------
-	 long int verbosity=0;
-
-    if (verbosity>20)
-    cout << "Geometry::AfterRead()" <<  nbv << " " << nbe << endl;
-    Int4 i,k=0;        ;
-    int jj; // jj in [0,1]
-    Int4 * hv = new Int4 [ nbv];
-    Int4 * ev = new Int4 [ 2 * nbe ];
-    float  * eangle = new float[ nbe ];
-    {
-      double eps = 1e-20;
-      QuadTree quadtree; // to find same vertices
-      Vertex * v0 = vertices; 
-      GeometricalVertex  * v0g = (GeometricalVertex  *) (void *) v0;   
-      int k=0;
-      for (i=0;i<nbv;i++) 
-        vertices[i].link = vertices +i;
-      for (i=0;i<nbv;i++) 
-	     {
-	      vertices[i].i = toI2(vertices[i].r); // set integer coordinate
-	      Vertex *v= quadtree.NearestVertex(vertices[i].i.x,vertices[i].i.y); 
-	      if( v && Norme1(v->r - vertices[i]) < eps )
-	       { // link v & vertices[i] 
-	         // vieille ruse pour recuperer j 
-	         GeometricalVertex * vg = (GeometricalVertex  *) (void *) v;
-	         int j = vg-v0g;
-	         assert( v ==  & (Vertex &) vertices[j]);
-	         vertices[i].link = vertices + j;
-            k++;	      
-	       }
-	      else  quadtree.Add(vertices[i]); 
-	     }
-      if (k) {
-	cout << " Number of distinte vertices " << nbv - k << " Over " << nbv << endl;
-	//if (verbosity>10) 
-	{
-	  cout << " The duplicate vertex " << endl;
-	  for (i=0;i<nbv;i++)
-	    if (!vertices[i].IsThe())
-	      cout << " " << i << " and " << Number(vertices[i].The()) << endl;
-	  MeshError(102);
-	  //throw(ErrorExec("exit",1));    
-	}
-      }
-      
-      //  verification of cracked edge
-      int err =0;
-      for (i=0;i<nbe;i++)
-	if (edges[i].Cracked() )
-	  {
-	    //    verification of crack
-	    GeometricalEdge & e1=edges[i];
-	    GeometricalEdge & e2=*e1.link;
-            cerr << i << " " << e1[0].The() << " " << e2[0].The() << " " <<  e1[1].The() << " " << e2[1].The() << endl;
-	    if ( e1[0].The() == e2[0].The() && e1[1].The() == e2[1].The() )
-	      {
-	      }
-	    else 
-	      if ( e1[0].The() == e2[1].The() && e1[1].The() == e2[0].The() )
-		{
-		}
-	      else
-		{
-		  err++;
-		  cerr << " Cracked edges with no same vertex " << &e1-edges << " " << &e2 -edges << endl;
-		}
-	  }
-	else
-	  {
-	    //  if (!edges[i][0].IsThe()) err++;
-	    // if (!edges[i][1].IsThe()) err++;
-	  }
-      if (err)
-	{
-	  cerr << " Some vertex was not distint and not on cracked edge " << err<< endl;
-	  MeshError(222);
-	}
-    }
-    if(verbosity>7) 
-      for (i=0;i<nbv;i++)
-	if (vertices[i].Required())
-	  cout << "     The geo vertices  " << i << " is required" << endl;
-
-    for (i=0;i<nbv;i++) 
-      hv[i]=-1;// empty list
-
-    for (i=0;i<nbe;i++) 
-      {
-        R2 v10  =  edges[i].v[1]->r -  edges[i].v[0]->r;
-        Real8 lv10 = Norme2(v10);
-        if(lv10 == 0) {
-          cerr << "The length  of " <<i<< "th Egde is 0 " << endl ;
-          MeshError(1);}
-        eangle[i] = atan2(v10.y,v10.x)  ; // angle in [ -Pi,Pi ]
-	if(verbosity>9) 
-	  cout << "     angle edge " << i <<" " << eangle[i]*180/Pi<< v10<<endl;
-        for (jj=0;jj<2;jj++)
-          { // generation of list
-            Int4 v =  Number(edges[i].v[jj]);
-            ev[k] = hv[v];
-            hv[v] = k++;
-          }
-      }
-    // bulle sort on the angle of edge  
-    for (i=0;i<nbv;i++) {
-      int exch = 1,ord =0;      
-      while (exch) {
-        exch = 0;
-        Int4  *p =  hv + i, *po = p;
-	Int4 n = *p;
-        register float angleold = -1000 ; // angle = - infini 
-        ord = 0;
-        while (n >=0) 
-        {
-          ord++;
-          register Int4 i1= n /2;
-          register Int4  j1 = n % 2;
-          register Int4 *pn = ev + n;
-          float angle = j1 ? OppositeAngle(eangle[i1]):  eangle[i1];
-          n = *pn;
-          if (angleold > angle) // exch to have : po -> pn -> p 
-            exch=1,*pn = *po,*po=*p,*p=n,po = pn;
-          else //  to have : po -> p -> pn 
-            angleold =  angle, po = p,p  = pn;
-        }
-      } // end while (exch)
-      
-      if (ord >= 1 ) 
-	{ /*
-	  Int4 n = hv[i];
-	  while ( n >=0) 
-	    { Int4 i1 = n/2,j1 = n%2;
-	    //float a = 180*(j1 ? OppositeAngle(eangle[i1]): eangle[i1])/Pi;
-	    n = ev[n];
-	    }
-	  */
-	} 
-      if(ord == 2) { // angulare test to find a corner 
-        Int4 n1 = hv[i];
-        Int4 n2 = ev[n1];
-        Int4 i1 = n1 /2, i2 = n2/2; // edge number
-        Int4  j1 = n1 %2, j2 = n2%2; // vertex in the edge 
-        float angle1= j1 ? OppositeAngle(eangle[i1]) :  eangle[i1];
-        float angle2= !j2 ? OppositeAngle(eangle[i2]) :  eangle[i2];
-	float da12 = Abs(angle2-angle1);
-	if(verbosity>9)
-	  cout <<"     check angle " << i << " " << i1 << " " << i2  << " " << 180*(da12)/Pi 
-	       << " " << 180*MaximalAngleOfCorner/Pi << vertices[i] << endl;
-
-        if (( da12 >= MaximalAngleOfCorner ) 
-            && (da12 <= 2*Pi -MaximalAngleOfCorner)) {
-	  vertices[i].SetCorner() ; 
-	  if(verbosity>7)
-	    cout << "     The vertex " << i << " is a corner (angle) " 
-		 << 180*(da12)/ Pi<< " " << 180*MaximalAngleOfCorner/Pi << endl;}
-	// if the ref a changing then is     SetRequired();
-	
-	if (edges[i1].flag != edges[i2].flag || edges[i1].Required()) 
-	 {
-	  vertices[i].SetRequired();
-	  if(verbosity>7)
-	    cout << "     The vertex " << i << " is Required the flag change (crack or equi, or require)" << endl;}
-	  
-	if (edges[i1].ref != edges[i2].ref) {
-	  vertices[i].SetRequired();
-	  if(verbosity>7)
-	    cout << "     The vertex " << i << " is Required ref" << endl;}
-      } ;
-      
-      if(ord != 2) {
-        vertices[i].SetCorner();
-	if(verbosity>7)
-	  cout << "     the vertex " << i << " is a corner ordre = " << ord << endl;
-      }
-      // close the liste around the vertex 
-      { Int4 no=-1, ne = hv[i];
-        while ( ne >=0) 
-                 ne = ev[no=ne];        
-            if(no>=0) 
-              ev[no] = hv[i];
-          } // now the list around the vertex is circular
-      
-    } // end for (i=0;i<nbv;i++)
- 
-    k =0;
-    for (i=0;i<nbe;i++)
-      for (jj=0;jj<2;jj++){
-            Int4 n1 = ev[k++]; 
-            Int4 i1 = n1/2 ,j1=n1%2;
-            if( edges[i1].v[j1] != edges[i].v[jj]) 
-              { cerr << " Bug Adj edge " << i << " " << jj << 
-                  " et " << i1 << " " << j1 << " k=" << k;
-                cerr << Number(edges[i].v[jj]) <<" <> " 
-                     << Number(edges[i1].v[j1])  <<endl;
-                cerr << "edge " << Number(edges[i].v[0]) << " " 
-                     << Number(edges[i].v[1]) << endl; 
-            //    cerr << "in file " <<filename <<endl;
-                MeshError(1);
-              }
-            edges[i1].Adj[j1] = edges + i;
-            edges[i1].SensAdj[j1] = jj;
-	    if (verbosity>10)
-	      cout << " edges. Adj " << i1 << " " << j1 << " <--- " << i << " " << jj << endl;
-      }
-    
-    // generation of  all the tangente 
-    for (i=0;i<nbe;i++) {
-        R2 AB = edges[i].v[1]->r -edges[i].v[0]->r;        
-	Real8 lAB = Norme2(AB); // length of current edge AB
-        Real8 ltg2[2];
-        ltg2[0]=0;ltg2[1]=0;
-        for (jj=0;jj<2;jj++) {
-             R2 tg =  edges[i].tg[jj];
-             Real8 ltg = Norme2(tg); // length of tg
-             if(ltg == 0) {// no tg
-	       if( ! edges[i].v[jj]->Corner())   { // not a Corner       
-		 tg =  edges[i].v[1-jj]->r 
-		   - edges[i].Adj[jj]->v[1-edges[i].SensAdj[jj]]->r;
-		 ltg =  Norme2(tg);
-		 tg =  tg *(lAB/ltg),ltg=lAB;
-		/*
-		   if(edges[i].ref >=4) 
-		   cout << " tg " << tg.x << " "<< tg.y  << " " << edges[i].v[1-jj]->r << edges[i].Adj[jj]->v[1-edges[i].SensAdj[jj]]->r << " y-y = "
-		     << edges[i].v[1-jj]->r.y -edges[i].Adj[jj]->v[1-edges[i].SensAdj[jj]]->r.y <<  endl;
-		*/
-	       }
-	       
-	       //else ;// a Corner with no tangent => nothing to do    
-             } // a tg 
-             else 
-               tg = tg *(lAB/ltg),ltg=lAB;
-             ltg2[jj] = ltg;
-             if ( (tg,AB) < 0) 
-               tg = -tg;
-	    //if(edges[i].ref >=4) cout << " tg = " << tg << endl;
-             edges[i].tg[jj] = tg;
-	}     // for (jj=0;jj<2;jj++) 
-	
-	if (ltg2[0]!=0) edges[i].SetTgA();
-	if (ltg2[1]!=0) edges[i].SetTgB();
-    } // for (i=0;i<nbe;i++)
-
-    if(verbosity>7)
-      for (i=0;i<nbv;i++)
-	if (vertices[i].Required())
-	  cout << "     The  geo  vertices " << i << " is required " << endl;
-  
-   for (int step=0;step<2;step++)
-   {
-    for (i=0;i<nbe;i++) 
-      edges[i].SetUnMark();
-    
-    NbOfCurves = 0;
-    Int4  nbgem=0;
-    for (int level=0;level < 2 && nbgem != nbe;level++)
-      for (i=0;i<nbe;i++) {
-	GeometricalEdge & ei = edges[i];   
-	for(jj=0;jj<2;jj++) 
-	  if (!ei.Mark() && (level || ei[jj].Required())) { 
-	    // warning ei.Mark() can be change in loop for(jj=0;jj<2;jj++) 
-	    int k0=jj,k1;
-	    GeometricalEdge *e = & ei;
-	    GeometricalVertex *a=(*e)(k0); // begin 
-	    if(curves) {
-	      curves[NbOfCurves].be=e;
-	      curves[NbOfCurves].kb=k0;
-	    }
-	    int nee=0;
-	    for(;;) { 
-		nee++;
-	      k1 = 1-k0; // next vertex of the edge 
-	      e->SetMark();
-	      nbgem++;
-	      e->CurveNumber=NbOfCurves;
-	      if(curves) {
-	      curves[NbOfCurves].ee=e;
-	      curves[NbOfCurves].ke=k1;
-	      }
-	      
-	      GeometricalVertex *b=(*e)(k1);
-	      if (a == b ||  b->Required() ) break;
-	      k0 = e->SensAdj[k1];//  vertex in next edge
-	      e = e->Adj[k1]; // next edge
-	      
-	    }// for(;;)
-	      if(verbosity>10 && curves==0) cout << NbOfCurves <<" curve :  nb edges=  "<< nee<<  endl; 
-	    NbOfCurves++;
-	    if(level) {
-	      if(verbosity>4)
-		cout << "    Warning: Curve "<< NbOfCurves << " without required vertex " 
-		     << "so the vertex " << Number(a) << " become required " <<endl;
-	      a->SetRequired();
-	    }
-       
-	  }} 
-	  assert(nbgem && nbe);
-
-	  if(step==0) {
-	    curves = new Curve[NbOfCurves];
-	  }
-    	} 
-    for(int i=0;i<NbOfCurves ;i++)
-     {
-       GeometricalEdge * be=curves[i].be, *eqbe=be->link;
-       //GeometricalEdge * ee=curves[i].ee, *eqee=be->link;
-       curves[i].master=true;
-       if(be->Equi() || be->ReverseEqui() ) 
-        {
-          assert(eqbe);
-          int nc = eqbe->CurveNumber;
-          assert(i!=nc);
-          curves[i].next=curves[nc].next;
-          curves[i].master=false;
-          curves[nc].next=curves+i;
-          if(be->ReverseEqui())
-           curves[i].Reverse();           
-        }
-     }
-    	 
-    if(verbosity>3)
-      cout << "    End ReadGeometry: Number of curves in geometry is " << NbOfCurves <<endl; 
-    if(verbosity>4)
-    for(int i=0;i<NbOfCurves ;i++)
-     {
-        cout << " Curve " << i << " begin e=" << Number(curves[i].be) << " k=" << curves[i].kb 
-             << "  end e= " << Number(curves[i].ee) << " k=" << curves[i].ke << endl;
-     }
-    delete []ev;
-    delete []hv;
-    delete []eangle;
-    
-}
-Geometry::~Geometry() 
-{
-	long int verbosity=0;
-
-  assert(NbRef<=0);
-  if(verbosity>9)
-    cout << "DELETE      ~Geometry "<< this  << endl;
-  if(vertices)  delete [] vertices;vertices=0;
-  if(edges)     delete [] edges;edges=0;
- // if(edgescomponante) delete [] edgescomponante; edgescomponante=0;
-  if(triangles) delete [] triangles;triangles=0;
-  if(quadtree)  delete  quadtree;quadtree=0;
-  if(curves)  delete  []curves;curves=0;NbOfCurves=0;
-  if(name) delete [] name;name=0;
-  if(subdomains) delete [] subdomains;subdomains=0;
-//  if(ordre)     delete [] ordre;
-  EmptyGeometry();
-
-}
-
-
-} 
Index: sm/trunk/src/c/Bamgx/Triangle.cpp
===================================================================
--- /issm/trunk/src/c/Bamgx/Triangle.cpp	(revision 2819)
+++ 	(revision )
@@ -1,41 +1,0 @@
-#include "../shared/shared.h"
-#include "../include/macros.h"
-#include "../toolkits/toolkits.h"
-
-#include <cstdio>
-#include <cstring>
-#include <cmath>
-#include <ctime>
-#include "Mesh2.h"
-#include "QuadTree.h"
-#include "SetOfE4.h"
-
-namespace bamg {
-
-	/*Others*/
-	/*FUNCTION Triangle::FindBoundaryEdge{{{1*/
-	TriangleAdjacent Triangle::FindBoundaryEdge(int i) const
-	  {
-		// turn around  the vertex ns[i] also call  s
-		Triangle   *t = (Triangle *) this , *ttc;
-		int k=0,j = EdgesVertexTriangle[i][0],jc;
-		int exterieur  = !link  ;
-
-		do 
-		  {
-			int exterieurp = exterieur;
-			k++; 
-			ttc =  t->at[j];
-			exterieur = !ttc->link;
-			if (exterieur+exterieurp == 1) 
-			 return TriangleAdjacent(t,j);
-			jc = NextEdge[t->aa[j]&3];
-			t = ttc;
-			j = NextEdge[jc];
-			assert(k<2000);
-		  } while ( (this!= t)); 
-		return TriangleAdjacent(0,0);
-	  }
-	/*}}}1*/
-
-}
Index: sm/trunk/src/c/Bamgx/Triangles.cpp
===================================================================
--- /issm/trunk/src/c/Bamgx/Triangles.cpp	(revision 2819)
+++ 	(revision )
@@ -1,5763 +1,0 @@
-#include "../shared/shared.h"
-#include "../include/macros.h"
-#include "../toolkits/toolkits.h"
-
-#include <cstdio>
-#include <cstring>
-#include <cmath>
-#include <ctime>
-#include "Mesh2.h"
-#include "QuadTree.h"
-#include "SetOfE4.h"
-
-namespace bamg {
-
-	static const  Direction NoDirOfSearch=Direction();
-	long NbUnSwap =0;
-
-	/*Constructors/Destructors*/
-	/*FUNCTION Triangles::Triangles(BamgMesh* bamgmesh, BamgOpts* bamgopts){{{1*/
-	Triangles::Triangles(BamgMesh* bamgmesh, BamgOpts* bamgopts):Gh(*(new Geometry())),BTh(*this){ 
-
-		PreInit(0,"none");
-		OnDisk = 1;
-
-		ReadMesh(bamgmesh,bamgopts);
-		SetIntCoor();
-		FillHoleInMesh();
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::Triangles(const Triangles & Tho,const int *flag ,const int *bb){{{1*/
-	Triangles::Triangles(const Triangles & Tho,const int *flag ,const int *bb)
-	  : Gh(*(new Geometry())), BTh(*this) {
-
-		  char cname[] = "trunc";
-
-		  int i,k,itadj;
-		  int kt=0;
-		  int * kk    = new int [Tho.nbv];
-		  Int4 * reft = new Int4[Tho.nbt];
-		  Int4 nbInT =    Tho.ConsRefTriangle(reft);
-		  Int4 * refv = new Int4[Tho.nbv];
-
-		  for (i=0;i<Tho.nbv;i++)
-			kk[i]=-1;
-		  for (i=0;i<Tho.nbv;i++)
-			refv[i]=0;
-		  int nbNewBedge =0;
-		  //  int nbOldBedge =0;  
-		  for (i=0;i<Tho.nbt;i++)
-			if(  reft[i] >=0 && flag[i]) 
-			  {
-				const Triangle & t = Tho.triangles[i];
-				kt++;
-				kk[Tho.Number(t[0])]=1;
-				kk[Tho.Number(t[1])]=1;
-				kk[Tho.Number(t[2])]=1;
-				itadj=Tho.Number(t.TriangleAdj(0));
-				if (  reft[itadj] >=0 && !flag[itadj])
-				  { nbNewBedge++;
-					refv[Tho.Number(t[VerticesOfTriangularEdge[0][0]])]=bb[i];
-					refv[Tho.Number(t[VerticesOfTriangularEdge[0][1]])]=bb[i];
-				  }
-				itadj=Tho.Number(t.TriangleAdj(1));
-				if (  reft[itadj] >=0 && !flag[itadj])
-				  { nbNewBedge++;
-					refv[Tho.Number(t[VerticesOfTriangularEdge[1][0]])]=bb[i];
-					refv[Tho.Number(t[VerticesOfTriangularEdge[1][1]])]=bb[i];}
-					itadj=Tho.Number(t.TriangleAdj(2));
-					if (  reft[itadj] >=0 && !flag[itadj])
-					  { nbNewBedge++;
-						refv[Tho.Number(t[VerticesOfTriangularEdge[2][0]])]=bb[i];
-						refv[Tho.Number(t[VerticesOfTriangularEdge[2][1]])]=bb[i];}
-			  }
-		  k=0;
-		  for (i=0;i<Tho.nbv;i++)
-			if (kk[i]>=0) 
-			 kk[i]=k++;
-		  cout << " number of vertices " << k << " remove = " << Tho.nbv - k << endl;
-		  cout << " number of triangles " << kt << " remove = " << nbInT-kt << endl;
-		  cout << " number of New boundary edge " << nbNewBedge << endl;
-		  Int4 inbvx =k;
-		  PreInit(inbvx,cname);
-		  for (i=0;i<Tho.nbv;i++)
-			if (kk[i]>=0) 
-			  {
-				vertices[nbv] = Tho.vertices[i];
-				if (!vertices[nbv].ref())
-				 vertices[nbv].ReferenceNumber = refv[i];
-				nbv++;
-			  }
-		  assert(inbvx == nbv);
-		  for (i=0;i<Tho.nbt;i++)
-			if(  reft[i] >=0 && flag[i]) 
-			  {
-				const Triangle & t = Tho.triangles[i];
-				int i0 = Tho.Number(t[0]);
-				int i1 = Tho.Number(t[1]);
-				int i2 = Tho.Number(t[2]);
-				assert(i0>=0 && i1 >= 0 && i2  >= 0);
-				assert(i0<Tho.nbv && i1 <Tho.nbv && i2  <Tho.nbv);
-				// cout <<i<< " F" <<  flag[i] << " T " << nbt << "   = " <<  kk[i0] << " " << kk[i1] << " " << kk[i2] ;
-				// cout << " OT  " <<  i0 << " "  << i1 << " " << i2  << " " << reft[i] << endl;
-				triangles[nbt] = Triangle(this,kk[i0],kk[i1],kk[i2]);
-				triangles[nbt].color = Tho.subdomains[reft[i]].ref; 
-				nbt++;           
-			  }
-		  assert(kt==nbt);
-		  if (nbt ==0 && nbv ==0) {
-			  cout << "Error all triangles was remove " << endl;
-			  MeshError(999,this);
-		  }
-		  delete [] kk;
-		  delete [] reft;
-		  delete [] refv;
-		  double cutoffradian = 10.0/180.0*Pi;
-		  ConsGeometry(cutoffradian);
-		  Gh.AfterRead(); 
-		  SetIntCoor();
-		  FillHoleInMesh();
-
-		  assert(NbSubDomains);
-		  assert(subdomains[0].head && subdomains[0].head->link);
-
-	  }
-	/*}}}1*/
-	/*FUNCTION Triangles::~Triangles(){{{1*/
-	Triangles::~Triangles() {
-		long int verbosity=2;
-		//assert(NbRef<=0);
-		if (CurrentTh == this) CurrentTh=0;
-		//if(vertices)  delete [] vertices; //TEST  crash if not commented
-		if(edges)     delete [] edges;
-		if(triangles) delete [] triangles;
-		if(quadtree)  delete  quadtree;
-		//if(ordre)     delete [] ordre; //TEST  crash if not commented
-		if( subdomains) delete []  subdomains;
-		if (VerticesOnGeomEdge) delete [] VerticesOnGeomEdge;
-		if (VerticesOnGeomVertex) delete [] VerticesOnGeomVertex;
-		//if (name) delete [] name; //TEST crash if not commented
-		if (identity) delete [] identity;
-		if (VertexOnBThVertex) delete [] VertexOnBThVertex;
-		if (VertexOnBThEdge) delete [] VertexOnBThEdge;
-
-		if (&Gh) {
-			if (Gh.NbRef>0) Gh.NbRef--;
-			else if (Gh.NbRef==0) delete &Gh;
-		}
-		if (&BTh && (&BTh != this)) {
-			if (BTh.NbRef>0) BTh.NbRef--;
-			else if (BTh.NbRef==0) delete &BTh;
-		}
-		PreInit(0); // set all to zero 
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::Triangles(Triangles & Th,Geometry * pGh,Triangles * pBth,Int4 nbvxx) COPY{{{1*/
-	Triangles::Triangles(Triangles & Th,Geometry * pGh,Triangles * pBth,Int4 nbvxx)
-	  : Gh(*(pGh?pGh:&Th.Gh)), BTh(*(pBth?pBth:this)) {
-		  Gh.NbRef++;
-		  nbvxx = Max(nbvxx,Th.nbv); 
-		  Int4 i;
-		  // do all the allocation to be sure all the pointer existe
-
-		  char * cname = 0;
-		  if (Th.name) 
-			 {
-			  cname = new char[strlen(Th.name)+1];
-			  strcpy(cname,Th.name);
-			 }
-		  PreInit(nbvxx,cname);// to make the allocation 
-		  // copy of triangles
-		  nt=Th.nt;
-		  nbv = Th.nbv;
-		  nbt = Th.nbt;
-		  nbiv = Th.nbiv;
-		  nbe = Th.nbe;
-		  NbSubDomains = Th.NbSubDomains;
-		  NbOutT = Th.NbOutT;
-		  NbOfQuad =  Th.NbOfQuad ;
-		  NbOfSwapTriangle =0;
-		  NbVerticesOnGeomVertex = Th.NbVerticesOnGeomVertex;
-		  if(NbVerticesOnGeomVertex)
-			VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];
-		  NbVerticesOnGeomEdge = Th.NbVerticesOnGeomEdge;
-		  if (NbVerticesOnGeomEdge)
-			VerticesOnGeomEdge = new VertexOnGeom[NbVerticesOnGeomEdge] ;
-		  if (& BTh == & Th.BTh) // same back ground 
-			 {
-			  BTh.NbRef++;
-			  NbVertexOnBThVertex = Th.NbVertexOnBThVertex;
-			  if(NbVertexOnBThVertex)
-				VertexOnBThVertex = new VertexOnVertex[NbVertexOnBThVertex];
-			  NbVertexOnBThEdge = Th.NbVertexOnBThEdge;
-			  if(NbVertexOnBThEdge)
-				VertexOnBThEdge = new VertexOnEdge[NbVertexOnBThEdge];
-			 }
-		  else 
-			 { // no add on back ground mesh 
-			  BTh.NbRef++;
-			  NbVertexOnBThVertex=0;
-			  VertexOnBThVertex=0;
-			  NbVertexOnBThEdge=0;
-			  VertexOnBThEdge=0;
-			  //       assert (& BTh == this); // --- a voir 
-
-			 }
-
-
-		  if(nbe)
-			edges = new Edge[nbe];
-		  if(NbSubDomains)
-			subdomains = new SubDomain[NbSubDomains];
-		  pmin = Th.pmin;
-		  pmax = Th.pmax;
-		  coefIcoor = Th.coefIcoor;
-		  for(i=0;i<nbt;i++)
-			triangles[i].Set(Th.triangles[i],Th,*this);
-		  for(i=0;i<nbe;i++)
-			edges[i].Set(Th,i,*this);
-		  for(i=0;i<nbv;i++)
-			vertices[i].Set(Th.vertices[i],Th,*this);
-		  for(i=0;i<NbSubDomains;i++)  
-			subdomains[i].Set(Th,i,*this);
-		  for (i=0;i<NbVerticesOnGeomVertex;i++)
-			VerticesOnGeomVertex[i].Set(Th.VerticesOnGeomVertex[i],Th,*this);
-		  for (i=0;i<NbVerticesOnGeomEdge;i++)
-			VerticesOnGeomEdge[i].Set(Th.VerticesOnGeomEdge[i],Th,*this);
-		  quadtree=0;
-
-
-		  //  assert(!OutSidesTriangles);
-	  }
-	/*}}}1*/
-
-	/*IO*/
-	/*FUNCTION Triangles::ReadMesh{{{1*/
-	void Triangles::ReadMesh(BamgMesh* bamgmesh, BamgOpts* bamgopts){
-
-		int verbose;
-		Real8 Hmin = HUGE_VAL;// the infinie value 
-		Int4 i1,i2,i3,iref;
-		Int4 i,j;
-		Int4 hvertices =0;
-		Int4 ifgeom=0;
-		Metric M1(1);
-		int Version=1,dim=2;
-
-		verbose=bamgopts->verbose;
-
-		nbv=bamgmesh->NumVertices;
-		nbvx=nbv;
-		nbt=bamgmesh->NumTriangles;
-		nbiv=nbvx;
-
-		//Vertices
-		if(bamgmesh->Vertices){
-			if(verbose>3) printf("      processing Vertices\n");
-
-			vertices=(Vertex*)xmalloc(nbv*sizeof(Vertex));
-			ordre=(Vertex**)xmalloc(nbv*sizeof(Vertex*));
-
-			for (i=0;i<nbv;i++){
-				vertices[i].r.x=bamgmesh->Vertices[i*3+0];
-				vertices[i].r.y=bamgmesh->Vertices[i*3+1];
-				vertices[i].ReferenceNumber=1;
-				vertices[i].DirOfSearch =NoDirOfSearch;
-				vertices[i].m=M1;
-				vertices[i].color=(Int4)bamgmesh->Vertices[i*3+2];
-			}
-			nbtx=2*nbvx-2; // for filling The Holes and quadrilaterals 
-		}
-		else{
-			if(verbose>3) throw ErrorException(__FUNCT__,exprintf("no Vertices found in the initial mesh"));
-		}
-
-		//Triangles
-		if(bamgmesh->Triangles){
-			if(verbose>3) printf("      processing Triangles\n");
-			triangles =new Triangle[nbtx]; //we cannot allocate only nbt triangles since 
-			//other triangles will be added for each edge
-			for (i=0;i<nbt;i++){
-				Triangle & t = triangles[i];
-				i1=(Int4)bamgmesh->Triangles[i*4+0]-1; //for C indexing
-				i2=(Int4)bamgmesh->Triangles[i*4+1]-1; //for C indexing
-				i3=(Int4)bamgmesh->Triangles[i*4+2]-1; //for C indexing
-				t=Triangle(this,i1,i2,i3);
-				t.color=(Int4)bamgmesh->Triangles[i*4+3];
-			}
-		}
-		else{
-			if(verbose>3) throw ErrorException(__FUNCT__,exprintf("no Triangles found in the initial mesh"));
-		}
-
-		//Quadrilaterals
-		if(bamgmesh->Quadrilaterals){
-			if(verbose>3) printf("      processing Quadrilaterals\n");
-			Int4 i1,i2,i3,i4,iref;
-			triangles =new Triangle[nbt];
-			for (i=0;i<bamgmesh->NumQuadrilaterals;i++){
-				Triangle & t1 = triangles[2*i];
-				Triangle & t2 = triangles[2*i+1];
-				i1=(Int4)bamgmesh->Quadrilaterals[i*4+0]-1; //for C indexing
-				i2=(Int4)bamgmesh->Quadrilaterals[i*4+1]-1; //for C indexing
-				i3=(Int4)bamgmesh->Quadrilaterals[i*4+2]-1; //for C indexing
-				i4=(Int4)bamgmesh->Quadrilaterals[i*4+3]-1; //for C indexing
-				t1=Triangle(this,i1,i2,i3);
-				t2=Triangle(this,i3,i4,i1);
-				t1.color=1; //reference = 1 for all triangles since it has not been specified
-				t2.color=1; //reference = 1 for all triangles since it has not been specified
-				t1.SetHidden(OppositeEdge[1]); // two times  because the adj was not created 
-				t2.SetHidden(OppositeEdge[1]); 
-			}
-		}
-		else{
-			if(verbose>3) printf("      no Quadrilaterals found\n");
-		}
-
-		//hVertices
-		if(bamgmesh->hVertices){
-			if(verbose>3) printf("      processing hVertices\n");
-			hvertices=1;
-			for (i=0;i< nbv;i++){
-				vertices[i].m=Metric((Real4)bamgmesh->hVertices[i]);
-			}
-		}
-		else{
-			if(verbose>3) printf("      no hVertices found\n");
-		}
-
-		//VerVerticesOnGeometricEdge
-		if(bamgmesh->VerticesOnGeometricEdge){
-			if(verbose>3) printf("      processing VerticesOnGeometricEdge\n");
-			NbVerticesOnGeomEdge=bamgmesh->NumVerticesOnGeometricEdge;
-			VerticesOnGeomEdge= new  VertexOnGeom[NbVerticesOnGeomEdge] ;
-			for (i=0;i<NbVerticesOnGeomEdge;i++){
-				Int4  i1,i2;
-				Real8 s;
-				i1=(Int4)bamgmesh->VerticesOnGeometricEdge[i*3+0]-1; //for C indexing
-				i2=(Int4)bamgmesh->VerticesOnGeometricEdge[i*3+1]-1; //for C indexing
-				s =(Int4)bamgmesh->VerticesOnGeometricEdge[i*3+2];
-				VerticesOnGeomEdge[i]=VertexOnGeom(vertices[i1],Gh.edges[i2],s);
-			}
-		}
-		else{
-			if(verbose>3) printf("      no VertexOnGeometricEdge found\n");
-		}
-
-		//Edges
-		if (bamgmesh->Edges){
-			int i1,i2;
-			R2 zero2(0,0);
-			Real4 *len =0;
-
-			if(verbose>3) printf("      processing Edges\n");
-			nbe=bamgmesh->NumEdges;
-			edges = new Edge[nbe];
-
-			if (!hvertices) {
-				len = new Real4[nbv];
-				for(i=0;i<nbv;i++)
-				 len[i]=0;
-			}
-
-			for (i=0;i<nbe;i++){
-				i1=(int)bamgmesh->Edges[i*3+0]-1; //-1 for C indexing
-				i2=(int)bamgmesh->Edges[i*3+1]-1; //-1 for C indexing
-				edges[i].v[0]= vertices +i1;
-				edges[i].v[1]= vertices +i2;
-				edges[i].adj[0]=0;
-				edges[i].adj[1]=0;
-				R2 x12 = vertices[i2].r-vertices[i1].r;
-				Real8 l12=sqrt( (x12,x12));        
-
-				if (!hvertices) {
-					vertices[i1].color++;
-					vertices[i2].color++;
-					len[i1]+= l12;
-					len[i2] += l12;
-				}
-				Hmin = Min(Hmin,l12);
-			}
-
-			// definition  the default of the given mesh size 
-			if (!hvertices){
-				for (i=0;i<nbv;i++) 
-				 if (vertices[i].color > 0) 
-				  vertices[i].m=  Metric(len[i] /(Real4) vertices[i].color);
-				 else 
-				  vertices[i].m=  Metric(Hmin);
-				delete [] len;
-			}
-
-			// construction of edges[].adj 
-			for (i=0;i<nbv;i++){ 
-				vertices[i].color = (vertices[i].color ==2) ? -1 : -2;
-			}
-			for (i=0;i<nbe;i++){
-				for (j=0;j<2;j++) { 
-					Vertex *v=edges[i].v[j];
-					Int4 i0=v->color,j0;
-					if(i0==-1){
-						v->color=i*2+j;
-					}
-					else if (i0>=0) {// i and i0 edge are adjacent by the vertex v
-						j0 =  i0%2;
-						i0 =  i0/2;
-						assert( v ==  edges[i0 ].v[j0]);
-						edges[i ].adj[ j ] =edges +i0;
-						edges[i0].adj[ j0] =edges +i ;
-						assert(edges[i0].v[j0] == v);
-						v->color = -3;
-					}
-				}
-			}
-		}
-		else{
-			if(verbose>3) printf("      no Edges found\n");
-		}
-
-		//EdgeOnGeometricEdge
-		if(bamgmesh->EdgesOnGeometricEdge){
-			if(verbose>3) printf("      processing EdgesOnGeometricEdge\n");
-			int i1,i2,i,j;
-			i2=bamgmesh->NumEdgesOnGeometricEdge;
-			for (i1=0;i1<i2;i1++) {
-				i=(int)bamgmesh->EdgesOnGeometricEdge[i*2+0];
-				j=(int)bamgmesh->EdgesOnGeometricEdge[i*2+1];
-				if(!(i>0 && j >0 && i <= nbe && j <= Gh.nbe)) {
-					throw ErrorException(__FUNCT__,exprintf("EdgesOnGeometricEdge error: We must have : (i>0 && j >0 && i <= nbe && j <= Gh.nbe)"));
-				}
-				edges[i-1].on = Gh.edges + j-1;
-			}
-		}
-		else{
-			if(verbose>3) printf("      no EdgesOnGeometricEdge found\n");
-		}
-
-		//SubDomain
-		if(bamgmesh->SubDomains){
-			Int4 i3,head,sens;
-			if(verbose>3) printf("      processing SubDomains\n");
-			NbSubDomains=bamgmesh->NumSubDomains;
-			subdomains = new SubDomain [ NbSubDomains ];
-			for (i=0;i<NbSubDomains;i++) {
-				i3  =(int)bamgmesh->SubDomains[i*3+0];
-				head=(int)bamgmesh->SubDomains[i*3+1]-1;//C indexing
-				sens=(int)bamgmesh->SubDomains[i*3+2];
-				if (i3!=23) throw ErrorException(__FUNCT__,exprintf("Bad Subdomain definition: first number should be 3"));
-				if (head<0 || head>=nbt) throw ErrorException(__FUNCT__,exprintf("Bad Subdomain definition: head should in [1 %i] (triangle number)",nbt));
-				subdomains[i].head = triangles+head;
-			}
-		}
-		else{
-			if(verbose>3) printf("      no SubDomains found\n");
-		}
-
-		/*Recreate geometry if needed*/
-		if(1!=0) {
-			printf("Warning: mesh present but no geometry found. Reconstructing...\n");
-			/*Recreate geometry: */
-			ConsGeometry(bamgopts->MaximalAngleOfCorner*Pi/180);
-			Gh.AfterRead();
-		}
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::WriteMesh {{{1*/
-	void Triangles::WriteMesh(BamgMesh* bamgmesh,BamgOpts* bamgopts){
-
-		int i,j;
-		int verbose;
-
-		verbose=bamgopts->verbose;
-		Int4 *reft = new Int4[nbt];
-		Int4 nbInT = ConsRefTriangle(reft);
-
-		//Vertices
-		if(verbose>3) printf("      writing Vertices\n");
-		bamgmesh->NumVertices=nbv;
-		xfree((void**)&bamgmesh->Vertices);
-		if (nbv){
-			bamgmesh->Vertices=(double*)xmalloc(3*nbv*sizeof(double));
-			for (i=0;i<nbv;i++){
-				bamgmesh->Vertices[i*3+0]=vertices[i].r.x;
-				bamgmesh->Vertices[i*3+1]=vertices[i].r.y;
-				bamgmesh->Vertices[i*3+2]=vertices[i].ref();
-			}
-		}
-		else{
-			bamgmesh->Vertices=NULL;
-		}
-
-		//Edges
-		if(verbose>3) printf("      writing Edges\n");
-		bamgmesh->NumEdges=nbe;
-		xfree((void**)&bamgmesh->Edges);
-		if (nbe){
-			bamgmesh->Edges=(double*)xmalloc(3*nbe*sizeof(double));
-			for (i=0;i<nbe;i++){
-				bamgmesh->Edges[i*3+0]=Number(edges[i][0])+1; //back to M indexing
-				bamgmesh->Edges[i*3+1]=Number(edges[i][1])+1; //back to M indexing
-				bamgmesh->Edges[i*3+2]=edges[i].ref;
-			}
-		}
-		else{
-			bamgmesh->Edges=NULL;
-		}
-
-		//CrackedEdges
-		if(verbose>3) printf("      writing CrackedEdges\n");
-		bamgmesh->NumCrackedEdges=NbCrackedEdges;
-		xfree((void**)&bamgmesh->CrackedEdges);
-		if (NbCrackedEdges){
-			bamgmesh->CrackedEdges=(double*)xmalloc(2*NbCrackedEdges*sizeof(double));
-			for (i=0;i<NbCrackedEdges;i++){
-				bamgmesh->CrackedEdges[i*2+0]=Number(CrackedEdges[i].a.edge)+1; //back to M indexing
-				bamgmesh->CrackedEdges[i*2+1]=Number(CrackedEdges[i].b.edge)+1; //back to M indexing
-			}
-		}
-		else{
-			bamgmesh->CrackedEdges=NULL;
-		}
-
-		//Triangles
-		if(verbose>3) printf("      writing Triangles\n");
-		Int4 k=nbInT-NbOfQuad*2;
-		Int4 num=0;
-		bamgmesh->NumTriangles=k;
-		xfree((void**)&bamgmesh->Triangles);
-		if (k){
-			bamgmesh->Triangles=(double*)xmalloc(4*k*sizeof(double));
-			for (i=0;i<nbt;i++){
-				Triangle &t=triangles[i];
-				if (reft[i]>=0 && !( t.Hidden(0) || t.Hidden(1) || t.Hidden(2) )){
-					bamgmesh->Triangles[num*4+0]=Number(t[0])+1; //back to M indexing
-					bamgmesh->Triangles[num*4+1]=Number(t[1])+1; //back to M indexing
-					bamgmesh->Triangles[num*4+2]=Number(t[2])+1; //back to M indexing
-					bamgmesh->Triangles[num*4+3]=subdomains[reft[i]].ref;
-					num=num+1;
-				}
-			}
-		}
-		else{
-			bamgmesh->Triangles=NULL;
-		}
-
-		//Quadrilaterals
-		if(verbose>3) printf("      writing Quadrilaterals\n");
-		bamgmesh->NumQuadrilaterals=NbOfQuad;
-		xfree((void**)&bamgmesh->Quadrilaterals);
-		if (NbOfQuad){
-			bamgmesh->Quadrilaterals=(double*)xmalloc(5*NbOfQuad*sizeof(double));
-			for (i=0;i<nbt;i++){
-				Triangle &t =triangles[i];
-				Triangle* ta;
-				Vertex *v0,*v1,*v2,*v3;
-				if (reft[i]<0) continue;
-				if ((ta=t.Quadrangle(v0,v1,v2,v3)) !=0 && &t<ta) { 
-					bamgmesh->Quadrilaterals[i*5+0]=Number(v0)+1; //back to M indexing
-					bamgmesh->Quadrilaterals[i*5+1]=Number(v1)+1; //back to M indexing
-					bamgmesh->Quadrilaterals[i*5+2]=Number(v2)+1; //back to M indexing
-					bamgmesh->Quadrilaterals[i*5+3]=Number(v3)+1; //back to M indexing
-					bamgmesh->Quadrilaterals[i*5+4]=subdomains[reft[i]].ref;
-				}
-			}
-		}
-		else{
-			bamgmesh->Quadrilaterals=NULL;
-		}
-
-		//SubDomains
-		if(verbose>3) printf("      writing SubDomains\n");
-		bamgmesh->NumSubDomains=NbSubDomains;
-		xfree((void**)&bamgmesh->SubDomains);
-		if (NbSubDomains){
-			bamgmesh->SubDomains=(double*)xmalloc(4*NbSubDomains*sizeof(double));
-			for (i=0;i<NbSubDomains;i++){
-				bamgmesh->SubDomains[i*4+0]=3;
-				bamgmesh->SubDomains[i*4+1]=reft[Number(subdomains[i].head)];
-				bamgmesh->SubDomains[i*4+2]=1;
-				bamgmesh->SubDomains[i*4+3]=subdomains[i].ref;
-			}
-		}
-		else{
-			bamgmesh->SubDomains=NULL;
-		}
-
-		//SubDomainsFromGeom
-		if(verbose>3) printf("      writing SubDomainsFromGeom\n");
-		bamgmesh->NumSubDomainsFromGeom=Gh.NbSubDomains;
-		xfree((void**)&bamgmesh->SubDomainsFromGeom);
-		if (Gh.NbSubDomains){
-			bamgmesh->SubDomainsFromGeom=(double*)xmalloc(4*Gh.NbSubDomains*sizeof(double));
-			for (i=0;i<Gh.NbSubDomains;i++){
-				bamgmesh->SubDomainsFromGeom[i*4+0]=2;
-				bamgmesh->SubDomainsFromGeom[i*4+1]=Number(subdomains[i].edge)+1; //back to Matlab indexing
-				bamgmesh->SubDomainsFromGeom[i*4+2]=subdomains[i].sens;
-				bamgmesh->SubDomainsFromGeom[i*4+3]=Gh.subdomains[i].ref;
-			}
-		}
-		else{
-			bamgmesh->SubDomainsFromGeom=NULL;
-		}
-
-		//VerticesOnGeomVertex
-		if(verbose>3) printf("      writing VerticesOnGeometricVertex\n");
-		bamgmesh->NumVerticesOnGeometricVertex=NbVerticesOnGeomVertex;
-		xfree((void**)&bamgmesh->VerticesOnGeometricVertex);
-		if (NbVerticesOnGeomVertex){
-			bamgmesh->VerticesOnGeometricVertex=(double*)xmalloc(2*NbVerticesOnGeomVertex*sizeof(double));
-			for (i=0;i<NbVerticesOnGeomVertex;i++){
-				VertexOnGeom &v=VerticesOnGeomVertex[i];
-				if (!v.OnGeomVertex()){
-					throw ErrorException(__FUNCT__,exprintf("A vertices supposed to be OnGeometricVertex is actually not"));
-				}
-				bamgmesh->VerticesOnGeometricVertex[i*2+0]=Number((Vertex*)v)+1; //back to Matlab indexing
-				bamgmesh->VerticesOnGeometricVertex[i*2+1]=Gh.Number(( GeometricalVertex*)v)+1; //back to Matlab indexing
-			}
-		}
-		else{
-			bamgmesh->VerticesOnGeometricVertex=NULL;
-		}
-
-		//VertexOnGeometricEdge
-		if(verbose>3) printf("      writing VerticesOnGeometricEdge\n");
-		bamgmesh->NumVerticesOnGeometricEdge=NbVerticesOnGeomEdge;
-		xfree((void**)&bamgmesh->VerticesOnGeometricEdge);
-		if (NbVerticesOnGeomEdge){
-			bamgmesh->VerticesOnGeometricEdge=(double*)xmalloc(3*NbVerticesOnGeomEdge*sizeof(double));
-			for (i=0;i<NbVerticesOnGeomEdge;i++){
-				const VertexOnGeom &v=VerticesOnGeomEdge[i];
-				if (!v.OnGeomEdge()){
-					throw ErrorException(__FUNCT__,exprintf("A vertices supposed to be OnGeometricEdge is actually not"));
-				}
-				bamgmesh->VerticesOnGeometricEdge[i*3+0]=Number((Vertex*)v)+1; //back to Matlab indexing
-				bamgmesh->VerticesOnGeometricEdge[i*3+1]=Gh.Number((const GeometricalEdge*)v)+1; //back to Matlab indexing
-				bamgmesh->VerticesOnGeometricEdge[i*3+2]=(double)v;
-			}
-		}
-		else{
-			bamgmesh->VerticesOnGeometricEdge=NULL;
-		}
-
-		//EdgesOnGeometricEdge
-		if(verbose>3) printf("      writing EdgesOnGeometricEdge\n");
-		k=0;
-		for (i=0;i<nbe;i++){
-			if (edges[i].on) k=k+1;
-		}
-		bamgmesh->NumEdgesOnGeometricEdge=k;
-		xfree((void**)&bamgmesh->EdgesOnGeometricEdge);
-		if (k){
-			bamgmesh->EdgesOnGeometricEdge=(double*)xmalloc(2*(int)k*sizeof(double));
-			int count=0;
-			for (i=0;i<nbe;i++){
-				if (edges[i].on){
-					bamgmesh->EdgesOnGeometricEdge[count*2+0]=(double)i+1; //back to Matlab indexing
-					bamgmesh->EdgesOnGeometricEdge[count*2+1]=(double)Gh.Number(edges[i].on)+1; //back to Matlab indexing
-					count=count+1;
-				}
-			}
-		}
-		else{
-			bamgmesh->EdgesOnGeometricEdge=NULL;
-		}
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::ReadMetric{{{1*/
-	void Triangles::ReadMetric(BamgOpts* bamgopts,const Real8 hmin1=1.0e-30,const Real8 hmax1=1.0e30,const Real8 coef=1) {
-		int  i,j;
-
-		if(bamgopts->verbose>3) printf("      processing metric\n");
-
-		Real8 hmin = Max(hmin1,MinimalHmin());
-		Real8 hmax = Min(hmax1,MaximalHmax());
-
-		//for now we only use j==3
-		j=3;
-
-		for (i=0;i<nbv;i++){
-			Real8 h;
-			if (j == 1){
-				h=bamgopts->metric[i];
-				vertices[i].m=Metric(Max(hmin,Min(hmax, h*coef)));
-			}
-			else if (j==3){
-				Real8 a,b,c;	     
-				a=bamgopts->metric[i*3+0];
-				b=bamgopts->metric[i*3+1];
-				c=bamgopts->metric[i*3+2];
-				MetricAnIso M(a,b,c);
-				MatVVP2x2 Vp(M/coef);
-
-				Vp.Maxh(hmin);
-				Vp.Minh(hmax);
-				vertices[i].m = Vp;
-			}
-		}
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::WriteMetric{{{1*/
-	void Triangles::WriteMetric(BamgOpts* bamgopts) {
-		int i;
-		xfree((void**)&bamgopts->metric);
-		if (bamgopts->iso){
-			bamgopts->metric=(double*)xmalloc(1*nbv*sizeof(double));
-			for (i=0;i<nbv;i++){
-				MatVVP2x2 V=vertices[i].m;
-				bamgopts->metric[i]=V.hmin();
-			}
-		}
-		else {
-			bamgopts->metric=(double*)xmalloc(3*nbv*sizeof(double));
-			for (i=0;i<nbv;i++){
-				bamgopts->metric[i*3+0]=vertices[i].m.a11;
-				bamgopts->metric[i*3+1]=vertices[i].m.a21;
-				bamgopts->metric[i*3+2]=vertices[i].m.a22;
-			}
-		}
-	}
-	/*}}}1*/
-
-	/*Others*/
-	/*FUNCTION Triangles::ConsGeometry{{{1*/
-	void Triangles::ConsGeometry(Real8 cutoffradian,int *equiedges) // construct a geometry if no geo 
-	  {
-		//  if equiedges existe taille nbe 
-		//   equiedges[i]/2 == i  original
-		//   equiedges[i]/2 = j  =>   equivalence entre i et j => meme maillage
-		//   equiedges[i]%2   : 0 meme sens , 1 pas meme sens 
-		//       
-		// --------------------------
-		long int verbosity=0;
-		if (verbosity>1) 
-		 cout << "  -- construction of the geometry from the 2d mesh " << endl;
-		if (nbt<=0 || nbv <=0 ) { MeshError(101);}
-
-		// construction of the edges 
-		//  Triangles * OldCurrentTh =CurrentTh;
-		CurrentTh=this;
-		//  Int4 NbTold = nbt;
-		// generation of the integer coor
-		// generation of the adjacence of the triangles
-		if (cutoffradian>=0)
-		 Gh.MaximalAngleOfCorner = cutoffradian;
-		SetOfEdges4 * edge4= new SetOfEdges4(nbt*3,nbv);
-		Int4 * st = new Int4[nbt*3];
-		Int4 i,k;
-		int j; 
-		if (Gh.name) delete Gh.name;
-		Gh.name = new char [ name ? strlen(name) + 15 : 50 ];
-		Gh.name[0]=0;
-		strcat(Gh.name,"cons from: ");
-		if (name) strcat(Gh.name,name);
-		else strcat(Gh.name," a mesh with no name");
-		for (i=0;i<nbt*3;i++)
-		 st[i]=-1;
-		Int4 kk =0;
-
-		Int4 nbeold = nbe;
-		for (i=0;i<nbe;i++)
-		  {
-			//      cout << i << " " << Number(edges[i][0]) << " " << Number(edges[i][1]) << endl;
-			edge4->addtrie(Number(edges[i][0]),Number(edges[i][1]));
-		  }
-		if (nbe !=  edge4->nb())
-		  { 
-			cerr << " Some Double edge in the mesh, the number is " << nbe 
-			  << " nbe4=" << edge4->nb()  << endl;
-			MeshError(1002);
-		  }
-		for (i=0;i<nbt;i++)
-		 for  (j=0;j<3;j++)
-			{
-			 // Int4 i0,i1;
-			 Int4 k =edge4->addtrie(Number(triangles[i][VerticesOfTriangularEdge[j][0]]),
-						 Number(triangles[i][VerticesOfTriangularEdge[j][1]]));
-			 Int4 invisible = triangles[i].Hidden(j);
-			 if(st[k]==-1)
-			  st[k]=3*i+j;
-			 else if(st[k]>=0) {
-				 assert( ! triangles[i].TriangleAdj(j) && !triangles[st[k] / 3].TriangleAdj((int) (st[k]%3)));
-
-				 triangles[i].SetAdj2(j,triangles + st[k] / 3,(int) (st[k]%3));
-				 if (invisible)  triangles[i].SetHidden(j);
-				 if (k<nbe) {
-					 triangles[i].SetLocked(j);
-				 }
-				 st[k]=-2-st[k]; }
-			 else {
-				 cerr << " The edge (" 
-					<< Number(triangles[i][VerticesOfTriangularEdge[j][0]])
-					<< " , " 
-					<< Number(triangles[i][VerticesOfTriangularEdge[j][1]])
-					<< " ) is in more than 2 triangles " <<k <<endl;
-				 cerr << " Edge " << j << " Of Triangle " << i << endl;
-				 cerr << " Edge " << (-st[k]+2)%3 << " Of Triangle " << (-st[k]+2)/3  << endl;
-				 cerr << " Edge " << triangles[(-st[k]+2)/3].NuEdgeTriangleAdj((int)((-st[k]+2)%3))
-					<< " Of Triangle " <<  Number(triangles[(-st[k]+2)/3].TriangleAdj((int)((-st[k]+2)%3))) 
-					<< endl;
-				 MeshError(9999);}	
-
-
-			}
-		Int4 nbedges = edge4->nb(); // the total number of edges 
-		delete edge4;
-		edge4 =0;
-
-		if(verbosity>5) {
-			if (name)
-			 cout << "    On Mesh " << name << endl;
-			cout << "    - The number of Vertices  = " << nbv << endl;
-			cout << "    - The number of Triangles = " << nbt << endl;
-			cout << "    - The number of given edge = " << nbe << endl;
-			cout << "    - The number of all edges = " << nbedges << endl;
-			cout << "    - The Euler number = 1-Nb Of Hole = " << nbt-nbedges+nbv << endl; }
-
-
-			// check the consistant of edge[].adj and the geometrical required  vertex
-			k=0;
-			kk=0;
-			Int4 it;
-
-			for (i=0;i<nbedges;i++)
-			 if (st[i] <-1) // edge internal
-				{ 
-				 it =  (-2-st[i])/3;
-				 j  =  (int) ((-2-st[i])%3);
-				 Triangle & tt = * triangles[it].TriangleAdj(j);
-				 //cout << it << " c="  << triangles[it].color <<  " " << Number(tt) << " c="  << tt.color << endl;
-				 if (triangles[it].color != tt.color|| i < nbeold) // Modif FH 06122055 // between 2 sub domai
-				  k++;
-				}
-			 else if (st[i] >=0) // edge alone 
-			  // if (i >= nbeold) 
-			  kk++;
-
-			if(verbosity>4 && (k+kk) )
-			 cout << "    Nb of  ref edge " << kk+k << " (internal " << k << ")"
-				<< " in file " << nbe  << endl;
-			k += kk;
-			kk=0;
-			if (k)
-			  {
-
-				//      if (nbe) {
-				//	cerr << k << " boundary edges  are not defined as edges " << endl;
-				//	MeshError(9998);
-				// }
-				// construction of the edges 
-				nbe = k;
-				Edge * edgessave = edges;
-				edges = new Edge[nbe];
-				k =0;
-				// construction of the edges 
-				if(verbosity>4)
-				 cout << "    Construction of the edges  " << nbe << endl;
-
-				for (i=0;i<nbedges;i++)
-				  { 
-					Int4  add= -1;
-
-					if (st[i] <-1) // edge internal
-					  { 
-						it =  (-2-st[i])/3;
-						j  =  (int) ((-2-st[i])%3);
-						Triangle & tt = * triangles[it].TriangleAdj(j);
-						if (triangles[it].color !=  tt.color || i < nbeold) // Modif FH 06122055
-						 add=k++;
-					  }
-					else if (st[i] >=0) // edge alone 
-					  {
-						it = st[i]/3;
-						j  = (int) (st[i]%3);
-						add=k++;
-					  }
-
-					if (add>=0 && add < nbe)
-					  {
-
-						edges[add].v[0] = &triangles[it][VerticesOfTriangularEdge[j][0]];
-						edges[add].v[1] = &triangles[it][VerticesOfTriangularEdge[j][1]];
-						edges[add].on=0; 
-						if (i<nbeold) // in file edge // Modif FH 06122055 
-						  {
-							edges[add].ref = edgessave[i].ref; 		      
-							edges[add].on = edgessave[i].on; //  HACK pour recuperer les aretes requise midf FH avril 2006 ???? 
-						  }
-						else
-						 edges[add].ref = Min(edges[add].v[0]->ref(),edges[add].v[1]->ref()); // no a good choice
-					  }
-				  }
-				assert(k==nbe);
-				if (edgessave) delete [] edgessave;
-			  }
-
-			// construction of edges[].adj 
-			for (i=0;i<nbv;i++) 
-			 vertices[i].color =0;
-			for (i=0;i<nbe;i++)
-			 for (j=0;j<2;j++) 
-			  edges[i].v[j]->color++;
-
-			for (i=0;i<nbv;i++) 
-			 vertices[i].color = (vertices[i].color ==2) ? -1 : -2;
-			for (i=0;i<nbe;i++)
-			 for (j=0;j<2;j++) 
-				{ 
-				 Vertex *v=edges[i].v[j];
-				 Int4 i0=v->color,j0;
-				 if(i0<0)
-				  edges[i ].adj[ j ]=0;  // Add FH Jan 2008   
-				 if(i0==-1)
-				  v->color=i*2+j;
-				 else if (i0>=0) {// i and i0 edge are adjacent by the vertex v
-					 j0 =  i0%2;
-					 i0 =  i0/2;
-					 assert( v ==  edges[i0 ].v[j0]);
-					 edges[i ].adj[ j ] =edges +i0;
-					 edges[i0].adj[ j0] =edges +i ;
-					 assert(edges[i0].v[j0] == v);
-					 //	    if(verbosity>8)
-					 //  cout << " edges adj " << i0 << " "<< j0 << " <-->  "  << i << " " << j << endl;
-					 v->color = -3;}
-				}
-			// now reconstruct the sub domain info 
-			assert(!NbSubDomains);
-			NbSubDomains=0;
-
-			  { 
-				Int4 it;
-				// find all the sub domain
-				Int4 *colorT = new Int4[nbt];
-				Triangle *tt,*t;
-				Int4 k;
-				for ( it=0;it<nbt;it++)
-				 colorT[it]=-1;
-				for (it=0;it<nbt;it++)
-				  {
-					if (colorT[it]<0) 
-					  {
-						colorT[it]=NbSubDomains;
-						Int4 level =1,j,jt,kolor=triangles[it].color;
-						st[0]=it; // stack 
-						st[1]=0;
-						k=1;
-						while (level>0)
-						 if( ( j=st[level]++) <3)
-							{ 
-							 t = &triangles[st[level-1]];
-							 tt=t->TriangleAdj((int)j);
-
-							 if ( ! t->Locked(j) && tt && (colorT[jt = Number(tt)] == -1) && ( tt->color==kolor))
-								{
-								 colorT[jt]=NbSubDomains;
-								 st[++level]=jt;
-								 st[++level]=0;
-								 k++;
-								}
-							}
-						 else 
-						  level-=2;
-						if (verbosity>5) 
-						 cout << "   Nb of triangles " << k << " of Subdomain "  
-							<<  NbSubDomains << " " << kolor << endl;
-						NbSubDomains++;
-					  }
-				  }
-				if (verbosity> 3)
-				 cout << "   The Number of sub domain = " << NbSubDomains << endl;
-
-				Int4 isd;
-				subdomains = new SubDomain[NbSubDomains];
-				for (isd=0;isd<NbSubDomains;isd++)
-				  {
-					subdomains[isd].head =0;
-				  }
-				k=0;
-				for (it=0;it<nbt;it++)
-				 for (int j=0;j<3;j++)
-					{
-					 tt=triangles[it].TriangleAdj(j);
-					 if ((!tt || tt->color != triangles[it].color) && !subdomains[isd=colorT[it]].head)
-						{
-						 subdomains[isd].head = triangles+it;
-						 subdomains[isd].ref =  triangles[it].color;
-						 subdomains[isd].sens = j; // hack
-						 subdomains[isd].edge = 0;
-						 k++;
-						}
-					}  
-				assert(k== NbSubDomains);
-
-				delete [] colorT;
-
-
-			  }      
-			delete [] st;
-			// now make the geometry
-			// 1 compress the vertices 
-			Int4 * colorV = new Int4[nbv];
-			for (i=0;i<nbv;i++) 
-			 colorV[i]=-1;
-			for (i=0;i<nbe;i++)
-			 for ( j=0;j<2;j++)
-			  colorV[Number(edges[i][j])]=0;
-			k=0;
-			for (i=0;i<nbv;i++) 
-			 if(!colorV[i])
-			  colorV[i]=k++;
-
-			Gh.nbv=k;
-			Gh.nbe = nbe;
-			Gh.vertices = new GeometricalVertex[k];
-			Gh.edges = new GeometricalEdge[nbe];
-			Gh.NbSubDomains = NbSubDomains;
-			Gh.subdomains = new GeometricalSubDomain[NbSubDomains];
-			if (verbosity>3)
-			 cout << "    Nb of  vertices  = " << Gh.nbv << " Nb of edges = " << Gh.nbe << endl;
-			NbVerticesOnGeomVertex = Gh.nbv;
-			VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];
-			NbVerticesOnGeomEdge =0;
-			VerticesOnGeomEdge =0;
-			  {
-				Int4 j;
-				for (i=0;i<nbv;i++) 
-				 if((j=colorV[i])>=0)
-					{
-
-					 Vertex & v = Gh.vertices[j];
-					 v = vertices[i];
-					 v.color =0;
-					 VerticesOnGeomVertex[j] = VertexOnGeom(vertices[i], Gh.vertices[j]);
-					}
-
-			  }
-			edge4= new SetOfEdges4(nbe,nbv);  
-
-			Real4 * len = new Real4[Gh.nbv];
-			for(i=0;i<Gh.nbv;i++)
-			 len[i]=0;
-
-			Gh.pmin =  Gh.vertices[0].r;
-			Gh.pmax =  Gh.vertices[0].r;
-			// recherche des extrema des vertices pmin,pmax
-			for (i=0;i<Gh.nbv;i++) {
-				Gh.pmin.x = Min(Gh.pmin.x,Gh.vertices[i].r.x);
-				Gh.pmin.y = Min(Gh.pmin.y,Gh.vertices[i].r.y);
-				Gh.pmax.x = Max(Gh.pmax.x,Gh.vertices[i].r.x);
-				Gh.pmax.y = Max(Gh.pmax.y,Gh.vertices[i].r.y);
-			}
-
-			R2 DD05 = (Gh.pmax-Gh.pmin)*0.05;
-			Gh.pmin -=  DD05;
-			Gh.pmax +=  DD05;
-
-			Gh.coefIcoor= (MaxICoor)/(Max(Gh.pmax.x-Gh.pmin.x,Gh.pmax.y-Gh.pmin.y));
-			assert(Gh.coefIcoor >0);
-
-			Real8 hmin = HUGE_VAL;
-			int kreq=0;
-			for (i=0;i<nbe;i++)
-			  {
-				Int4 i0 = Number(edges[i][0]);
-				Int4 i1 = Number(edges[i][1]);
-				Int4 j0 =	 colorV[i0];
-				Int4 j1 =  colorV[i1];
-
-				Gh.edges[i].v[0] = Gh.vertices +  j0;
-				Gh.edges[i].v[1] = Gh.vertices +  j1;
-				Gh.edges[i].flag = 0;
-				Gh.edges[i].tg[0]=R2();
-				Gh.edges[i].tg[1]=R2();
-				bool requis= edges[i].on; 
-				if(requis) kreq++;
-				edges[i].on =  Gh.edges + i;
-				if(equiedges && i < nbeold ) {
-					int j=equiedges[i]/2;
-					int sens=equiedges[i]%2;
-					if(i!=j && equiedges[i]>=0) {
-						if(verbosity>9)  
-						 cout << " Edges Equi " << i << " <=> " << j << " sens = " << sens  << endl;
-						if( sens==0)
-						 Gh.edges[i].SetEqui();
-						else 
-						 Gh.edges[i].SetReverseEqui();
-						Gh.edges[i].link= & Gh.edges[j];
-						//assert(sens==0);//  meme sens pour l'instant
-					}
-
-				}
-				if(requis)  {  // correction fevr 2009 JYU ...
-					Gh.edges[i].v[0]->SetRequired();
-					Gh.edges[i].v[1]->SetRequired();
-					Gh.edges[i].SetRequired(); // fin modif ... 
-				}
-				R2 x12 = Gh.vertices[j0].r-Gh.vertices[j1].r;
-				Real8 l12=Norme2(x12);        
-				hmin = Min(hmin,l12);
-
-				Gh.vertices[j1].color++;
-				Gh.vertices[j0].color++;
-
-				len[j0]+= l12;
-				len[j1] += l12;
-				hmin = Min(hmin,l12);
-
-				Gh.edges[i].ref  = edges[i].ref;
-
-				k = edge4->addtrie(i0,i1);
-
-				assert(k == i);
-
-			  }
-
-
-			for (i=0;i<Gh.nbv;i++) 
-			 if (Gh.vertices[i].color > 0) 
-			  Gh.vertices[i].m=  Metric(len[i] /(Real4) Gh.vertices[i].color);
-			 else 
-			  Gh.vertices[i].m=  Metric(hmin);
-			delete [] len;
-			for (i=0;i<NbSubDomains;i++)
-			  {
-				Int4 it = Number(subdomains[i].head);
-				int j = subdomains[i].sens;
-				Int4 i0 = Number(triangles[it][VerticesOfTriangularEdge[j][0]]);
-				Int4 i1 = Number(triangles[it][VerticesOfTriangularEdge[j][1]]);
-				k = edge4->findtrie(i0,i1);
-				if(k>=0)
-				  {
-					subdomains[i].sens = (vertices + i0 == edges[k].v[0]) ? 1 : -1;
-					subdomains[i].edge = edges+k;
-					Gh.subdomains[i].edge = Gh.edges + k;
-					Gh.subdomains[i].sens  =  subdomains[i].sens;
-					Gh.subdomains[i].ref =  subdomains[i].ref;
-				  }
-				else
-				 MeshError(103);
-			  }
-
-			delete edge4;
-			delete [] colorV;
-			//  -- unset adj
-			for (i=0;i<nbt;i++)
-			 for ( j=0;j<3;j++)
-			  triangles[i].SetAdj2(j,0,triangles[i].GetAllflag(j));
-
-	  }
-	/*}}}1*/
-	/*FUNCTION Triangles::ProjectOnCurve{{{1*/
-	GeometricalEdge*   Triangles::ProjectOnCurve( Edge & BhAB, Vertex &  vA, Vertex & vB,
-				Real8 theta,Vertex & R,VertexOnEdge &  BR,VertexOnGeom & GR) {
-		void *pA=0,*pB=0;
-		Real8 tA=0,tB=0;
-		R2 A=vA,B=vB;
-		Vertex * pvA=&vA, * pvB=&vB;
-		if (vA.vint == IsVertexOnVertex)
-		  {
-			//  cout << " Debut vertex = " << BTh.Number(vA.onbv) ;
-			pA=vA.onbv;
-		  }
-		else if (vA.vint == IsVertexOnEdge)
-		  {
-			pA=vA.onbe->be;
-			tA=vA.onbe->abcisse;
-			// cout << " Debut edge = " << BTh.Number(vA.onbv) << " " << tA ;
-
-		  }
-		else
-		  {cerr << "ProjectOnCurve On Vertex " << BTh.Number(vA) << " " << endl;
-			cerr << " forget call to SetVertexFieldOnBTh" << endl;
-			MeshError(-1);
-		  } 
-
-		if (vB.vint == IsVertexOnVertex)
-		  {
-			// cout << " Fin vertex = " << BTh.Number(vB.onbv) << endl;
-			pB=vB.onbv;
-		  }
-		else if(vB.vint == IsVertexOnEdge)
-		  {
-			pB=vB.onbe->be;
-			tB=vB.onbe->abcisse;
-			// cout << " Fin edge = " << BTh.Number(vB.onbe->be) << " " <<  tB ;
-
-		  }
-		else
-		  {cerr << "ProjectOnCurve On Vertex " << BTh.Number(vB) << " " << endl;
-			cerr << " forget call to SetVertexFieldOnBTh" << endl;
-			MeshError(-1);
-		  } 
-		Edge * e = &BhAB;
-		assert( pA && pB && e);
-		// be carefull the back ground edge e is on same geom edge 
-		// of the initiale edge def by the 2 vertex A B;
-		assert(e>=BTh.edges && e<BTh.edges+BTh.nbe);// Is a background Mesh;   
-		// walk on BTh edge 
-		//assert(0 /* not finish ProjectOnCurve with BackGround Mesh*/);
-		// 1 first find a back ground edge contening the vertex A
-		// 2 walk n back gound boundary to find the final vertex B
-
-		if( vA.vint == IsVertexOnEdge) 
-		  { // find the start edge 
-			e = vA.onbe->be;	 
-
-		  } 
-		else if (vB.vint == IsVertexOnEdge) 
-		  {
-			theta = 1-theta;
-			Exchange(tA,tB);
-			Exchange(pA,pB);
-			Exchange(pvA,pvB);
-			Exchange(A,B);
-			e =  vB.onbe->be;
-
-			// cout << " EXCHANGE  A et B) " << endl;
-		  } 
-		else
-		  { // do the search by walking 
-			assert(0 /* A FAIRE */);
-		  }
-
-		// find the direction of walking with sens of edge and pA,PB;
-		R2 AB=B-A;
-
-		Real8 cosE01AB = (( (R2) (*e)[1] - (R2) (*e)[0] ) , AB);
-		int kkk=0;
-		int sens = (cosE01AB>0) ? 1 : 0;
-
-		//   Real8 l=0; // length of the edge AB
-		Real8 abscisse = -1;
-
-		for (int cas=0;cas<2;cas++)
-		  {// 2 times algo:
-			//    1 for computing the length l
-			//    2 for find the vertex 
-			int  iii;
-			Vertex  *v0=pvA,*v1; 
-			Edge *neee,*eee;
-			Real8 lg =0; // length of the curve 
-			Real8 te0;
-			// we suppose take the curve's abcisse 
-			// cout << kkk << " e = " << BTh.Number(e) << "  v0=  " 
-			//    << BTh.Number(v0) << " v1 = " << BTh.Number((*e)[sens]) << endl;
-			for ( eee=e,iii=sens,te0=tA;
-						eee && ((( void*) eee) != pB) && (( void*) (v1=&((*eee)[iii]))) != pB ;
-						neee = eee->adj[iii],iii = 1-neee->Intersection(*eee),eee = neee,v0=v1,te0=1-iii )   
-			  { 
-				//	cout << kkk << " eee = " << BTh.Number(eee) << "  v0=  " 
-				//     << BTh.Number(v0) << " v1 = " << BTh.Number(v1) << endl;
-
-				assert(kkk++<100);
-				assert(eee);
-				Real8 lg0 = lg;
-				Real8 dp = LengthInterpole(v0->m,v1->m,(R2) *v1 - (R2) *v0);
-				lg += dp;
-				if (cas && abscisse <= lg)
-				  { // ok we find the geom edge 
-					Real8 sss  =   (abscisse-lg0)/dp;
-					Real8 thetab = te0*(1-sss)+ sss*iii;
-					assert(thetab>=0 && thetab<=1);
-					BR = VertexOnEdge(&R,eee,thetab);
-
-					// cout << Number(R) << " = " <<  thetab << " on  " <<  BTh.Number(eee)
-					//	 << " = " << R << endl;
-
-					return  Gh.ProjectOnCurve(*eee,thetab,R,GR);
-
-				  }
-			  }
-			// we find the end 
-			if (v1 != pvB) 
-			  {
-				if (( void*) v1 == pB)
-				 tB = iii;
-
-				Real8 lg0 = lg;
-				assert(eee);
-				v1 = pvB;
-				Real8 dp = LengthInterpole(v0->m,v1->m,(R2) *v1 - (R2) *v0);
-				lg += dp;	
-				abscisse = lg*theta;
-				if (abscisse <= lg && abscisse >= lg0 ) // small optimisation we know the lenght because end
-				  { // ok we find the geom edge 
-					Real8 sss  =   (abscisse-lg0)/dp;
-					Real8 thetab = te0*(1-sss)+ sss*tB;
-					assert(thetab>=0 && thetab<=1);
-					BR = VertexOnEdge(&R,eee,thetab);
-
-					//	cout << kkk << " eee = " << BTh.Number(eee) << "  v0=  " 
-					//     << BTh.Number(v0) << " " << te0
-					//      << " v1 = " << BTh.Number(v1) <<  " " << tB  << endl;
-
-					//out << Number(R) << " Opt  = " <<  thetab << " on  " <<  BTh.Number(eee) 
-					//	    << " = " << R << endl;
-
-					return  Gh.ProjectOnCurve(*eee,thetab,R,GR);
-				  }
-			  }
-			abscisse = lg*theta;
-
-		  }
-		cerr << " Big Bug" << endl;
-		MeshError(678);
-		return 0; // just for the compiler 
-
-	}                  
-	/*}}}1*/
-	/*FUNCTION Triangles::MakeQuadrangles{{{1*/
-	void Triangles::MakeQuadrangles(double costheta){
-		long int verbosity=0;
-
-		if (verbosity>2) 
-		 cout << "  -- MakeQuadrangles costheta = " << costheta << endl;
-		if (verbosity>5)  
-		 cout << "    (in)  Nb of Quadrilaterals = " << NbOfQuad 
-			<< " Nb Of Triangles = " << nbt-NbOutT- NbOfQuad*2 
-			<< " Nb of outside triangles = " << NbOutT << endl;
-
-		if (costheta >1) {
-			if (verbosity>5)
-			 cout << "     do nothing costheta >1 "<< endl;
-			return;}
-
-
-			Int4 nbqq = (nbt*3)/2;
-			DoubleAndInt4  *qq = new DoubleAndInt4[nbqq];
-
-			Int4 i,ij;
-			int j;
-			Int4 k=0;
-			for (i=0;i<nbt;i++)
-			 for (j=0;j<3;j++)
-			  if ((qq[k].q=triangles[i].QualityQuad(j))>=costheta)
-				qq[k++].i3j=i*3+j;
-			//  sort  qq
-			HeapSort(qq,k);
-
-			Int4 kk=0;
-			for (ij=0;ij<k;ij++)
-			  { 
-				//      cout << qq[ij].q << " " << endl;
-				i=qq[ij].i3j/3;
-				j=(int) (qq[ij].i3j%3);
-				// optisamition no float computation  
-				if (triangles[i].QualityQuad(j,0) >=costheta) 
-				 triangles[i].SetHidden(j),kk++;
-			  }
-			NbOfQuad = kk;
-			if (verbosity>2) 
-			  {
-				cout << "    (out)  Nb of Quadrilaterals = " << NbOfQuad 
-				  << " Nb Of Triangles = " << nbt-NbOutT- NbOfQuad*2 
-				  << " Nb of outside triangles = " << NbOutT << endl;
-			  }
-			delete [] qq;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::SplitElement{{{1*/
-	int  Triangles::SplitElement(int choice){
-		long int verbosity=0;
-
-		Direction NoDirOfSearch;
-		const  int withBackground = &BTh != this && &BTh;
-		if (verbosity>2) 
-		 cout << "  -- SplitElement " << (choice? " Q->4Q and T->4T " : " Q->4Q or T->3Q " ) << endl;;
-		if (verbosity>5)
-		 cout << endl << "    (in)  Nb of Quadrilaterals = " << NbOfQuad 
-			<< " Nb Of Triangles = " << nbt-NbOutT- NbOfQuad*2 
-			<< " Nb of outside triangles = " << NbOutT << endl;
-
-		ReNumberingTheTriangleBySubDomain();
-		//int nswap =0;
-		const Int4 nfortria( choice ? 4 : 6);
-		if(withBackground) 
-		  {
-			BTh.SetVertexFieldOn();
-			SetVertexFieldOnBTh();
-		  }
-		else
-		 BTh.SetVertexFieldOn();
-
-		Int4 newnbt=0,newnbv=0;
-		Int4 * kedge = 0;
-		Int4 newNbOfQuad=NbOfQuad;
-		Int4 * ksplit= 0, * ksplitarray=0;
-		Int4 kkk=0;
-		int ret =0;
-		if (nbvx<nbv+nbe) return 1;//   
-		Triangles *  OCurrentTh= CurrentTh;
-		CurrentTh = this;
-		// 1) create  the new points by spliting the internal edges 
-		// set the 
-		Int4 nbvold = nbv;
-		Int4 nbtold = nbt;
-		Int4 NbOutTold  = NbOutT;
-		Int4  NbEdgeOnGeom=0;
-		Int4 i;
-
-		nbt = nbt - NbOutT; // remove all the  the ouside triangles 
-		Int4 nbtsave = nbt;
-		Triangle * lastT = triangles + nbt;
-		for (i=0;i<nbe;i++)
-		 if(edges[i].on) NbEdgeOnGeom++;
-		Int4 newnbe=nbe+nbe;
-		//  Int4 newNbVerticesOnGeomVertex=NbVerticesOnGeomVertex;
-		Int4 newNbVerticesOnGeomEdge=NbVerticesOnGeomEdge+NbEdgeOnGeom;
-		// Int4 newNbVertexOnBThVertex=NbVertexOnBThVertex;
-		Int4 newNbVertexOnBThEdge=withBackground ? NbVertexOnBThEdge+NbEdgeOnGeom:0;
-
-		// do allocation for pointeur to the geometry and background
-		VertexOnGeom * newVerticesOnGeomEdge = new VertexOnGeom[newNbVerticesOnGeomEdge];
-		VertexOnEdge *newVertexOnBThEdge = newNbVertexOnBThEdge ?  new VertexOnEdge[newNbVertexOnBThEdge]:0;
-		if (NbVerticesOnGeomEdge)
-		 memcpy(newVerticesOnGeomEdge,VerticesOnGeomEdge,sizeof(VertexOnGeom)*NbVerticesOnGeomEdge);
-		if (NbVertexOnBThEdge)
-		 memcpy(newVertexOnBThEdge,VertexOnBThEdge,sizeof(VertexOnEdge)*NbVertexOnBThEdge);
-		Edge *newedges = new Edge [newnbe];
-		//  memcpy(newedges,edges,sizeof(Edge)*nbe);
-		SetOfEdges4 * edge4= new SetOfEdges4(nbe,nbv);
-		Int4 k=nbv;
-		Int4 kk=0;
-		Int4 kvb = NbVertexOnBThEdge;
-		Int4 kvg = NbVerticesOnGeomEdge;
-		Int4 ie =0;
-		Edge ** edgesGtoB=0;
-		if (withBackground)
-		 edgesGtoB= BTh.MakeGeometricalEdgeToEdge();
-		Int4 ferr=0;
-		for (i=0;i<nbe;i++)
-		 newedges[ie].on=0;
-
-		for (i=0;i<nbe;i++)
-		  {
-			GeometricalEdge *ong =  edges[i].on;
-
-			newedges[ie]=edges[i];
-			newedges[ie].adj[0]=newedges+(edges[i].adj[0]-edges) ;
-			newedges[ie].adj[1]=newedges + ie +1;
-			R2 A = edges[i][0],B = edges[i][1];
-			// cout << " ie = " << ie <<"  v0 = " <<  Number(newedges[ie][0]) << endl;
-
-
-			kk += (i == edge4->addtrie(Number(edges[i][0]),Number(edges[i][1])));
-			if (ong) // a geometrical edges 
-			  { 
-				if (withBackground)
-				  {
-					// walk on back ground mesh 
-					//  newVertexOnBThEdge[ibe++] = VertexOnEdge(vertices[k],bedge,absicsseonBedge); 
-					// a faire -- difficile 
-					// the first PB is to now a background edge between the 2 vertices
-					assert(edgesGtoB); 
-					// cout << " ie = " << ie <<"  v0 = " <<  Number(newedges[ie][0]) << endl;
-					ong= ProjectOnCurve(*edgesGtoB[Gh.Number(edges[i].on)],
-								edges[i][0],edges[i][1],0.5,vertices[k],
-								newVertexOnBThEdge[kvb],
-								newVerticesOnGeomEdge[kvg++]);
-					vertices[k].ReferenceNumber= edges[i].ref;
-					vertices[k].DirOfSearch =   NoDirOfSearch;        
-					;
-					// get the Info on background mesh 
-					Real8 s =        newVertexOnBThEdge[kvb];
-					Vertex &  bv0  = newVertexOnBThEdge[kvb][0];
-					Vertex &  bv1  = newVertexOnBThEdge[kvb][1];
-					// compute the metrix of the new points 
-					vertices[k].m =  Metric(1-s,bv0,s,bv1); 
-					kvb++;
-					// cout << " ie = " << ie <<"  v0 = " <<  Number(newedges[ie][0]) << endl;
-				  }
-				else 
-				  {
-					ong=Gh.ProjectOnCurve(edges[i],
-								0.5,vertices[k],newVerticesOnGeomEdge[kvg++]);
-					// vertices[k].i = toI2( vertices[k].r);
-					vertices[k].ReferenceNumber = edges[i].ref;
-					vertices[k].DirOfSearch = NoDirOfSearch;
-					vertices[k].m =  Metric(0.5,edges[i][0],0.5,edges[i][1]);	      
-				  }  
-			  }
-			else // straigth line edge ---
-			  { 
-				vertices[k].r = ((R2) edges[i][0] + (R2)  edges[i][1] )*0.5;
-				vertices[k].m =  Metric(0.5,edges[i][0],0.5,edges[i][1]);
-				vertices[k].on = 0;
-			  }
-			//vertices[k].i = toI2( vertices[k].r);
-			R2 AB =  vertices[k].r;
-			R2 AA = (A+AB)*0.5;
-			R2 BB = (AB+B)*0.5;
-			vertices[k].ReferenceNumber = edges[i].ref;
-			vertices[k].DirOfSearch = NoDirOfSearch;
-
-			newedges[ie].on = Gh.Contening(AA,ong);
-			newedges[ie++].v[1]=vertices+k;
-
-			newedges[ie]=edges[i];
-			newedges[ie].adj[0]=newedges + ie -1;
-			newedges[ie].adj[1]=newedges+(edges[i].adj[1]-edges) ;
-			newedges[ie].on =  Gh.Contening(BB,ong);
-			newedges[ie++].v[0]=vertices+k;
-			// cout << " ie = " << ie-2 << " vm " << k << " v0 = " <<  Number(newedges[ie-2][0])
-			//	   << " v1 = " << Number(newedges[ie-1][1])  
-			//	   << " ong =" << ong-Gh.edges 
-			//	   << " on 0 =" <<  newedges[ie-2].on -Gh.edges << AA
-			//	   << " on 1 =" <<  newedges[ie-1].on -Gh.edges << BB 
-			//	   << endl;
-			k++;
-		  }
-		if (edgesGtoB) delete [] edgesGtoB;
-		edgesGtoB=0;
-
-		newnbv=k;
-		newNbVerticesOnGeomEdge=kvg;
-		if (newnbv> nbvx) goto Error;// bug 
-
-		nbv = k;
-
-
-		kedge = new Int4[3*nbt+1];
-		ksplitarray = new Int4[nbt+1];
-		ksplit = ksplitarray +1; // because ksplit[-1] == ksplitarray[0]
-
-		for (i=0;i<3*nbt;i++)
-		 kedge[i]=-1;
-
-		//  
-
-		for (i=0;i<nbt;i++)
-		  {  
-
-			Triangle & t = triangles[i];
-			assert(t.link);
-			for(int j=0;j<3;j++)
-			  {
-				const TriangleAdjacent ta = t.Adj(j);
-				const Triangle & tt = ta;
-				if (&tt >= lastT)
-				 t.SetAdj2(j,0,0);// unset adj
-				const Vertex & v0 = t[VerticesOfTriangularEdge[j][0]];
-				const Vertex & v1 = t[VerticesOfTriangularEdge[j][1]];
-				Int4  ke =edge4->findtrie(Number(v0),Number(v1));
-				if (ke>0) 
-				  {
-					Int4 ii = Number(tt);
-					int  jj = ta;
-					Int4 ks = ke + nbvold;
-					kedge[3*i+j] = ks;
-					if (ii<nbt) // good triangle
-					 kedge[3*ii+jj] = ks;
-					Vertex &A=vertices[ks];
-					Real8 aa,bb,cc,dd;
-					if ((dd=Area2(v0.r,v1.r,A.r)) >=0)
-					  { // warning PB roundoff error 
-						if (t.link && ( (aa=Area2( A.r    , t[1].r , t[2].r )) < 0.0 
-										||   (bb=Area2( t[0].r , A.r    , t[2].r )) < 0.0  
-										||   (cc=Area2( t[0].r , t[1].r , A.r    )) < 0.0))
-						 ferr++, cerr << " Error : " <<  ke + nbvold << " not in triangle " 
-							<< i << " In=" << !!t.link
-							<< " " <<  aa  << " " << bb << " " << cc << " " << dd << endl;
-
-					  }
-
-					else
-					  {
-						if (tt.link && ( (aa=Area2( A.r     , tt[1].r , tt[2].r )) < 0 
-										||   (bb=Area2( tt[0].r , A.r     , tt[2].r )) < 0 
-										||   (cc=Area2( tt[0].r , tt[1].r , A.r     )) < 0)) 
-						 ferr++, cerr << " Warning : " <<  ke + nbvold << " not in triangle " << ii 
-							<< " In=" << !!tt.link 
-							<< " " <<  aa  << " " << bb << " " << cc << " " << dd << endl;
-
-					  } 
-
-				  }
-			  }
-		  }
-		if(ferr)
-		  {
-			cerr << " Number of triangles with P2 interpolation Probleme " << ferr << endl;;
-			MeshError(9);
-		  }
-
-		for (i=0;i<nbt;i++)
-		  {
-			ksplit[i]=1; // no split by default
-			const Triangle & t = triangles[ i];
-			// cout << " Triangle " << i << " " << t  << !!t.link << ":: " ;
-			int nbsplitedge =0;
-			int nbinvisible =0;
-			int invisibleedge=0;
-			int kkk[3];      
-			for (int j=0;j<3;j++)
-			  {
-				if (t.Hidden(j)) invisibleedge=j,nbinvisible++;
-
-				const TriangleAdjacent ta = t.Adj(j);
-				const Triangle & tt = ta;
-
-
-				const Vertex & v0 = t[VerticesOfTriangularEdge[j][0]];
-				const Vertex & v1 = t[VerticesOfTriangularEdge[j][1]];
-				//  cout << " ke = " << kedge[3*i+j]  << " " << Number(v0) << " " << Number(v1) << "/ ";
-				if ( kedge[3*i+j] < 0) 
-				  {
-					Int4  ke =edge4->findtrie(Number(v0),Number(v1));
-					//  cout << ":" << ke << "," << !!t.link << " " <<  &tt ;
-					if (ke<0) // new 
-					  {
-						if (&tt) // internal triangles all the boundary 
-						  { // new internal edges 
-							Int4 ii = Number(tt);
-							int  jj = ta;
-
-							kedge[3*i+j]=k;// save the vertex number 
-							kedge[3*ii+jj]=k;
-							if (k<nbvx) 
-							  {
-								vertices[k].r = ((R2) v0+(R2) v1 )/2;
-								//vertices[k].i = toI2( vertices[k].r);
-								vertices[k].ReferenceNumber=0;
-								vertices[k].DirOfSearch =NoDirOfSearch;
-								vertices[k].m =  Metric(0.5,v0,0.5,v1);
-							  }
-							k++;
-							kkk[nbsplitedge++]=j;		      
-						  } // tt 
-						else
-						 cerr <<endl <<  " Bug " <<i<< " " << j << " t=" << t << endl;
-
-					  } // ke<0	       
-					else
-					  { // ke >=0
-						kedge[3*i+j]=nbvold+ke;
-						kkk[nbsplitedge++]=j;// previously splited
-					  }
-				  }
-				else 
-				 kkk[nbsplitedge++]=j;// previously splited
-
-			  } 
-			assert (nbinvisible<2);
-			// cout << " " <<  nbinvisible << " " <<  nbsplitedge << endl;
-			switch (nbsplitedge) {
-				case 0: ksplit[i]=10; newnbt++; break;   // nosplit
-				case 1: ksplit[i]=20+kkk[0];newnbt += 2; break; // split in 2 
-				case 2: ksplit[i]=30+3-kkk[0]-kkk[1];newnbt += 3; break; // split in 3 
-				case 3:
-						  if (nbinvisible) ksplit[i]=40+invisibleedge,newnbt += 4;
-						  else   ksplit[i]=10*nfortria,newnbt+=nfortria;
-						  break;
-			} 
-			assert(ksplit[i]>=40);
-		  }
-		//  now do the element split
-		newNbOfQuad = 4*NbOfQuad;
-		nbv = k;
-		//  cout << " Nbv = " << nbv << endl;
-		kkk = nbt;
-		ksplit[-1] = nbt;
-		// look on  old true  triangles 
-
-		for (i=0;i<nbtsave;i++)
-		  {
-			//     cout << "Triangle " << i << " " << ksplit[i] << ":" << triangles[i]
-			//	   << "  ----------------------------------------------- " <<endl;
-			// Triangle * tc=0;
-			int  nbmkadj=0;
-			Int4 mkadj [100];
-			mkadj[0]=i;
-			Int4 kk=ksplit[i]/10;
-			int  ke=(int) (ksplit[i]%10);
-			assert(kk<7 && kk >0);
-
-			// def the numbering   k (edge) i vertex 
-			int k0 = ke;
-			int k1 = NextEdge[k0];
-			int k2 = PreviousEdge[k0];
-			int i0 = OppositeVertex[k0];
-			int i1 = OppositeVertex[k1];
-			int i2 = OppositeVertex[k2];
-
-			Triangle &t0=triangles[i];
-			Vertex * v0=t0(i0);           
-			Vertex * v1=t0(i1);           
-			Vertex * v2=t0(i2);
-
-			// cout << "nbmkadj " << nbmkadj << " it=" << i <<endl;
-			assert(nbmkadj< 10);
-			// --------------------------
-			TriangleAdjacent ta0(t0.Adj(i0)),ta1(t0.Adj(i1)),ta2(t0.Adj(i2));
-			// save the flag Hidden
-			int hid[]={t0.Hidden(0),t0.Hidden(1),t0.Hidden(2)};
-			// un set all adj -- save Hidden flag --
-			t0.SetAdj2(0,0,hid[0]);
-			t0.SetAdj2(1,0,hid[1]);
-			t0.SetAdj2(2,0,hid[2]);
-			// --  remake 
-			switch  (kk) {
-				case 1: break;// nothing 
-				case 2: // 
-						  {
-							Triangle &t1=triangles[kkk++];
-							t1=t0;
-							assert (kedge[3*i+i0]>=0);
-							Vertex * v3 = vertices + kedge[3*i+k0];
-
-							t0(i2) = v3;
-							t1(i1) = v3;
-							t0.SetAllFlag(k2,0);
-							t1.SetAllFlag(k1,0);
-						  } 
-						break; 
-				case 3: //
-						  {
-							Triangle &t1=triangles[kkk++];
-							Triangle &t2=triangles[kkk++];
-							t2=t1=t0;
-							assert (kedge[3*i+k1]>=0);
-							assert (kedge[3*i+k2]>=0);
-
-							Vertex * v01 = vertices + kedge[3*i+k2];
-							Vertex * v02 = vertices + kedge[3*i+k1]; 
-							t0(i1) = v01; 
-							t0(i2) = v02; 
-							t1(i2) = v02;
-							t1(i0) = v01; 
-							t2(i0) = v02; 
-							t0.SetAllFlag(k0,0);
-							t1.SetAllFlag(k1,0);
-							t1.SetAllFlag(k0,0);
-							t2.SetAllFlag(k2,0);
-						  } 
-						break;
-				case 4: // 
-				case 6: // split in 4 
-						  {
-							Triangle &t1=triangles[kkk++];
-							Triangle &t2=triangles[kkk++];
-							Triangle &t3=triangles[kkk++];
-							t3=t2=t1=t0;
-							assert(kedge[3*i+k0] >=0 && kedge[3*i+k1] >=0 && kedge[3*i+k2] >=0);
-							Vertex * v12 = vertices + kedge[3*i+k0];
-							Vertex * v02 = vertices + kedge[3*i+k1]; 
-							Vertex * v01 = vertices + kedge[3*i+k2];
-							// cout << Number(t0(i0))  << " " << Number(t0(i1)) 
-							//     << " " <<  Number(t0(i2)) 
-							//     << " " <<  kedge[3*i+k0] 
-							//     << " " <<  kedge[3*i+k1] 
-							//     << " " <<  kedge[3*i+k2] << endl;
-							t0(i1) = v01;
-							t0(i2) = v02;
-							t0.SetAllFlag(k0,hid[k0]);
-
-							t1(i0) = v01;
-							t1(i2) = v12;
-							t0.SetAllFlag(k1,hid[k1]);
-
-							t2(i0) = v02;
-							t2(i1) = v12;
-							t2.SetAllFlag(k2,hid[k2]);
-
-							t3(i0) = v12;
-							t3(i1) = v02;
-							t3(i2) = v01;
-
-							t3.SetAllFlag(0,hid[0]);	   
-							t3.SetAllFlag(1,hid[1]);	   
-							t3.SetAllFlag(2,hid[2]);
-
-							if ( kk == 6)
-							  {
-
-								Triangle &t4=triangles[kkk++];
-								Triangle &t5=triangles[kkk++];
-
-								t4 = t3;
-								t5 = t3;
-
-								t0.SetHidden(k0);
-								t1.SetHidden(k1);
-								t2.SetHidden(k2);
-								t3.SetHidden(0);
-								t4.SetHidden(1);
-								t5.SetHidden(2);
-
-								if (nbv < nbvx ) 
-								  {
-									vertices[nbv].r = ((R2) *v01 + (R2) *v12  + (R2) *v02 ) / 3.0;
-									vertices[nbv].ReferenceNumber =0;
-									vertices[nbv].DirOfSearch =NoDirOfSearch;
-									//vertices[nbv].i = toI2(vertices[nbv].r);
-									Real8 a3[]={1./3.,1./3.,1./3.};
-									vertices[nbv].m = Metric(a3,v0->m,v1->m,v2->m);
-									Vertex * vc =  vertices +nbv++;
-									t3(i0) = vc;
-									t4(i1) = vc;
-									t5(i2) = vc;
-
-								  }
-								else
-								 goto Error; 
-							  }
-
-						  } 
-						break;         
-			}
-
-			// cout << "  -- " << i << " " << nbmkadj << " " << kkk << " " << tc << endl;
-			//  t0.SetDetf();
-			// save all the new triangles
-			mkadj[nbmkadj++]=i;
-			Int4 jj;
-			if (t0.link) 
-			 for (jj=nbt;jj<kkk;jj++)
-				{
-				 triangles[jj].link=t0.link;
-				 t0.link= triangles+jj;
-				 mkadj[nbmkadj++]=jj;
-				 // triangles[jj].SetDet();
-				}
-			// cout << "  -- " << i << " " << nbmkadj << endl;
-			assert(nbmkadj<=13);// 13 = 6 + 4 + 3
-
-			if (kk==6)  newNbOfQuad+=3;
-			//	 triangles[i].Draw();       
-
-			for (jj=ksplit[i-1];jj<kkk;jj++)
-			 // triangles[jj].SetDet();
-			 //	   triangles[jj].Draw();
-
-
-
-			 nbt = kkk;
-			ksplit[i]= nbt; // save last adresse of the new triangles
-			kkk = nbt;
-
-		  }
-
-		//  cout << " nv = " << nbv << " nbt = " << nbt << endl;
-		for (i=0;i<nbv;i++)
-		 vertices[i].m = vertices[i].m*2.;
-		//
-		if(withBackground)
-		 for (i=0;i<BTh.nbv;i++)
-		  BTh.vertices[i].m =  BTh.vertices[i].m*2.;
-
-
-		ret = 2;
-		if (nbt>= nbtx) goto Error; // bug 
-		if (nbv>= nbvx) goto Error; // bug 
-		// generation of the new triangles 
-
-		SetIntCoor("In SplitElement"); 
-
-		ReMakeTriangleContainingTheVertex();
-		if(withBackground)
-		 BTh.ReMakeTriangleContainingTheVertex();
-
-		delete [] edges;
-		edges = newedges;
-		nbe = newnbe;
-		NbOfQuad = newNbOfQuad;
-
-		for (i=0;i<NbSubDomains;i++)
-		  { 
-			Int4 k = subdomains[i].edge- edges;
-			subdomains[i].edge =  edges+2*k; // spilt all edge in 2 
-		  }
-
-		if (ksplitarray) delete [] ksplitarray;
-		if (kedge) delete [] kedge;
-		if (edge4) delete edge4;
-		if (VerticesOnGeomEdge) delete [] VerticesOnGeomEdge;
-		VerticesOnGeomEdge= newVerticesOnGeomEdge;
-		if(VertexOnBThEdge) delete []  VertexOnBThEdge;
-		VertexOnBThEdge = newVertexOnBThEdge;
-		NbVerticesOnGeomEdge = newNbVerticesOnGeomEdge;
-		NbVertexOnBThEdge=newNbVertexOnBThEdge;
-		//  ReMakeTriangleContainingTheVertex();
-
-		FillHoleInMesh();
-
-		if (verbosity>2)
-		 cout << "    (out) Nb of Quadrilaterals = " << NbOfQuad 
-			<< " Nb Of Triangles = " << nbt-NbOutT- NbOfQuad*2 
-			<< " Nb of outside triangles = " << NbOutT << endl;
-
-		CurrentTh=OCurrentTh;
-		return 0; //ok
-
-Error:
-		nbv = nbvold;
-		nbt = nbtold;
-		NbOutT = NbOutTold;
-		// cleaning memory ---
-		delete newedges;
-		if (ksplitarray) delete [] ksplitarray;
-		if (kedge) delete [] kedge;
-		if (newVerticesOnGeomEdge) delete [] newVerticesOnGeomEdge;
-		if (edge4) delete edge4;
-		if(newVertexOnBThEdge) delete []  newVertexOnBThEdge;
-
-
-		CurrentTh= OCurrentTh;
-		return ret; // ok 
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::swap{{{1*/
-	int Triangle::swap(Int2 a,int koption){
-		if(a/4 !=0) return 0;// arete lock or MarkUnSwap
-
-		register Triangle *t1=this,*t2=at[a];// les 2 triangles adjacent
-		register Int1 a1=a,a2=aa[a];// les 2 numero de l arete dans les 2 triangles
-		if(a2/4 !=0) return 0; // arete lock or MarkUnSwap
-
-		register Vertex  *sa=t1->ns[VerticesOfTriangularEdge[a1][0]];
-		register Vertex  *sb=t1->ns[VerticesOfTriangularEdge[a1][1]];
-		register Vertex  *s1=t1->ns[OppositeVertex[a1]];
-		register Vertex  *s2=t2->ns[OppositeVertex[a2]];
-
-		Icoor2 det1=t1->det , det2=t2->det ;
-		Icoor2 detT = det1+det2;
-		Icoor2 detA = Abs(det1) + Abs(det2);
-		Icoor2 detMin = Min(det1,det2);
-
-		int OnSwap = 0;       
-		// si 2 triangle infini (bord) => detT = -2;
-		if (sa == 0) {// les deux triangles sont frontieres
-			det2=bamg::det(s2->i,sb->i,s1->i);
-			OnSwap = det2 >0;}
-		else if (sb == 0) { // les deux triangles sont frontieres
-			det1=bamg::det(s1->i,sa->i,s2->i);
-			OnSwap = det1 >0;}
-		else if(( s1 != 0) && (s2 != 0) ) {
-			det1 = bamg::det(s1->i,sa->i,s2->i);
-			det2 = detT - det1;
-			OnSwap = (Abs(det1) + Abs(det2)) < detA;
-
-			Icoor2 detMinNew=Min(det1,det2);
-			//     if (detMin<0 && (Abs(det1) + Abs(det2) == detA)) OnSwap=BinaryRand();// just for test   
-			if (! OnSwap &&(detMinNew>0)) {
-				OnSwap = detMin ==0;
-				if (! OnSwap) {
-					int  kopt = koption;
-					while (1)
-					 if(kopt) {
-						 // critere de Delaunay pure isotrope
-						 register Icoor2 xb1 = sb->i.x - s1->i.x,
-									 x21 = s2->i.x - s1->i.x,
-									 yb1 = sb->i.y - s1->i.y,
-									 y21 = s2->i.y - s1->i.y,
-									 xba = sb->i.x - sa->i.x, 
-									 x2a = s2->i.x - sa->i.x,
-									 yba = sb->i.y - sa->i.y,
-									 y2a = s2->i.y - sa->i.y;
-						 register double
-							cosb12 =  double(xb1*x21 + yb1*y21),
-									 cosba2 =  double(xba*x2a + yba*y2a) ,
-									 sinb12 = double(det2),
-									 sinba2 = double(t2->det);
-
-
-						 // angle b12 > angle ba2 => cotg(angle b12) < cotg(angle ba2)
-						 OnSwap =  ((double) cosb12 * (double)  sinba2) <  ((double) cosba2 * (double) sinb12);
-						 //  	 if(CurrentTh) 
-						 //  	   cout << "swap " << CurrentTh->Number(sa) << " " << CurrentTh->Number(sb) << " " ;
-						 //  	 cout <<  cosb12 << " " <<  sinba2 << " "  <<  cosba2 << " " << sinb12 
-						 //  	      << " Onswap = " <<  OnSwap << endl;
-						 break;
-					 }
-					 else 
-						{	
-						 // critere de Delaunay anisotrope 
-						 Real8 som;
-						 I2 AB=(I2) *sb - (I2) *sa;
-						 I2 MAB2=((I2) *sb + (I2) *sa);
-						 R2 MAB(MAB2.x*0.5,MAB2.y*0.5);
-						 I2 A1=(I2) *s1 - (I2) *sa;
-						 I2 D = (I2) * s1 - (I2) * sb ;
-						 R2 S2(s2->i.x,s2->i.y);
-						 R2 S1(s1->i.x,s1->i.y);
-							{
-							 Metric M=s1->m;
-							 R2 ABo = M.Orthogonal(AB);
-							 R2 A1o = M.Orthogonal(A1);
-							 // (A+B)+ x ABo = (S1+B)/2+ y A1 
-							 // ABo x - A1o y =  (S1+B)/2-(A+B)/2 = (S1-B)/2 = D/2
-							 double dd = Abs(ABo.x*A1o.y)+Abs(ABo.y*A1o.x);
-							 double d = (ABo.x*A1o.y - ABo.y*A1o.x)*2; // because D/2
-							 if (Abs(d) > dd*1.e-3) {
-								 R2 C(MAB+ABo*((D.x*A1o.y - D.y*A1o.x)/d));
-								 som  = M(C - S2)/M(C - S1);
-							 } else 
-								{kopt=1;continue;}
-
-							}
-							{
-							 Metric M=s2->m;
-							 R2 ABo = M.Orthogonal(AB);
-							 R2 A1o = M.Orthogonal(A1);
-							 // (A+B)+ x ABo = (S1+B)/2+ y A1 
-							 // ABo x - A1o y =  (S1+B)/2-(A+B)/2 = (S1-B)/2 = D/2 
-							 double dd = Abs(ABo.x*A1o.y)+Abs(ABo.y*A1o.x);
-							 double d = (ABo.x*A1o.y - ABo.y*A1o.x)*2; // because D/2
-							 if(Abs(d) > dd*1.e-3) {
-								 R2 C(MAB+ABo*((D.x*A1o.y - D.y*A1o.x)/d));
-								 som  += M(C - S2)/M(C -  S1);
-							 } else 
-								{kopt=1;continue;}
-							}
-						 OnSwap = som < 2;
-						 break;
-						}
-
-				} // OnSwap 
-			} // (! OnSwap &&(det1 > 0) && (det2 > 0) )
-		}
-		if( OnSwap ) 
-		 bamg::swap(t1,a1,t2,a2,s1,s2,det1,det2);
-		else {
-			NbUnSwap ++;
-			t1->SetMarkUnSwap(a1);     
-		}
-		return OnSwap;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::MetricAt{{{1*/
-	Metric Triangles::MetricAt(const R2 & A) const { 
-		I2 a = toI2(A);
-		Icoor2 deta[3];
-		Triangle * t =FindTriangleContening(a,deta);
-		if (t->det <0) { // outside
-			double ba,bb;
-			TriangleAdjacent edge= CloseBoundaryEdge(a,t,ba,bb) ;
-			return Metric(ba,*edge.EdgeVertex(0),bb,*edge.EdgeVertex(1));}
-		else { // inside
-			Real8   aa[3];
-			Real8 s = deta[0]+deta[1]+deta[2];
-			aa[0]=deta[0]/s;
-			aa[1]=deta[1]/s;
-			aa[2]=deta[2]/s;
-			return Metric(aa,(*t)[0],(*t)[1],(*t)[2]);
-		}
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::Add{{{1*/
-	void Triangles::Add( Vertex & s,Triangle * t, Icoor2 * det3) {
-		// -------------------------------------------
-		//             s2
-		//                                            !
-		//             /|\                            !
-		//            / | \                           !
-		//           /  |  \                          !
-		//    tt1   /   |   \ tt0                     !
-		//         /    |s   \                        !
-		//        /     .     \                       !
-		//       /  .      `   \                      !
-		//      / .           ` \                     !
-		//      ----------------                      !
-		//   s0       tt2       s1
-		//-------------------------------------------- 
-
-		Triangle * tt[3]; // the 3 new Triangles
-		Vertex &s0 = (* t)[0], &s1=(* t)[1], &s2=(* t)[2];
-		Icoor2  det3local[3];
-		int infv = &s0 ?  ((  &s1 ? ( &s2  ? -1 : 2) : 1  )) : 0;
-		// infv = ordre of the infini vertex (null)
-		register int nbd0 =0; // number of zero det3
-		register int izerodet=-1,iedge; // izerodet = egde contening the vertex s
-		Icoor2 detOld = t->det;
-
-		if ( ( infv <0 ) && (detOld <0) ||  ( infv >=0  ) && (detOld >0) ) 
-		  {
-			cerr << "  infv " << infv << " det = " << detOld << endl;
-			cerr << Number(s) << " "<< Number(s0) << " "  
-			  << Number(s1) << " "  << Number(s2) << endl;
-			MeshError(3);
-		  }
-
-		// if det3 do not exist then constuct det3
-		if (!det3) { 
-			det3 = det3local; // alloc 
-			if ( infv<0 ) {
-				det3[0]=bamg::det(s ,s1,s2);
-				det3[1]=bamg::det(s0,s ,s2);
-				det3[2]=bamg::det(s0,s1,s );}
-			else { 
-				// one of &s1  &s2  &s0 is NULL so (&si || &sj) <=> !&sk
-				det3[0]=  &s0 ? -1  : bamg::det(s ,s1,s2) ;
-				det3[1]=  &s1 ? -1 : bamg::det(s0,s ,s2) ;
-				det3[2]=  &s2 ? -1 : bamg::det(s0,s1,s ) ;}}
-
-
-				if (!det3[0]) izerodet=0,nbd0++;
-				if (!det3[1]) izerodet=1,nbd0++;
-				if (!det3[2]) izerodet=2,nbd0++;
-
-				if  (nbd0 >0 ) // point s on a egde or on a vertex 
-				 if (nbd0 == 1) {
-					 iedge = OppositeEdge[izerodet];
-					 TriangleAdjacent ta = t->Adj(iedge);
-
-					 // the point is on the edge 
-					 // if the point is one the boundary 
-					 // add the point in outside part 
-					 if ( t->det >=0) { // inside triangle
-						 if ((( Triangle *) ta)->det < 0 ) {
-							 // add in outside triangle 
-							 Add(s,( Triangle *) ta);
-							 return;}
-					 }}
-				 else {
-					 cerr << " bug  " << nbd0 <<endl;
-					 cerr << " Bug double points in " << endl ;
-					 cerr << " s = " << Number(s) << " " <<  s << endl;
-					 cerr << " s0 = "<< Number(s0) << " "  << s0 << endl;
-					 cerr << " s1 = "<< Number(s1) << " "  << s1 << endl;
-					 cerr << " s2 = "<< Number(s2) << " "  << s2 << endl;
-					 MeshError(5,this);}
-
-					 // remove de MarkUnSwap edge
-					 t->SetUnMarkUnSwap(0);     
-					 t->SetUnMarkUnSwap(1);     
-					 t->SetUnMarkUnSwap(2);
-
-					 tt[0]= t;
-					 tt[1]= &triangles[nbt++];
-					 tt[2]= &triangles[nbt++];
-
-					 if (nbt>nbtx) {
-						 cerr << " No enougth triangles " << endl;
-						 MeshError(999,this);
-					 }
-
-					 *tt[1]=   *tt[2]= *t;
-					 // gestion of the link
-					 tt[0]->link=tt[1];
-					 tt[1]->link=tt[2]; 
-
-					 (* tt[0])(OppositeVertex[0])=&s;
-					 (* tt[1])(OppositeVertex[1])=&s;
-					 (* tt[2])(OppositeVertex[2])=&s;
-
-					 tt[0]->det=det3[0];
-					 tt[1]->det=det3[1];
-					 tt[2]->det=det3[2];         
-
-					 //  update adj des triangles externe 
-					 tt[0]->SetAdjAdj(0);
-					 tt[1]->SetAdjAdj(1);
-					 tt[2]->SetAdjAdj(2);
-					 //  update des adj des 3 triangle interne
-					 const int i0 = 0;
-					 const int i1= NextEdge[i0];
-					 const int i2 = PreviousEdge[i0];
-
-					 tt[i0]->SetAdj2(i2,tt[i2],i0);
-					 tt[i1]->SetAdj2(i0,tt[i0],i1);
-					 tt[i2]->SetAdj2(i1,tt[i1],i2);
-
-					 tt[0]->SetTriangleContainingTheVertex();
-					 tt[1]->SetTriangleContainingTheVertex();
-					 tt[2]->SetTriangleContainingTheVertex();
-
-
-					 // swap if the point s is on a edge
-					 if(izerodet>=0) {
-						 //  cout << " the point s is on a edge =>swap " << iedge << " "  << *tt[izerodet] << endl;
-						 int rswap =tt[izerodet]->swap(iedge);
-
-						 if (!rswap) 
-							{
-							 cout << " Pb swap the point s is on a edge =>swap " << iedge << " "  << *tt[izerodet] << endl;
-							}
-						 assert(rswap);
-					 }
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::SplitInternalEdgeWithBorderVertices{{{1*/
-	Int4  Triangles::SplitInternalEdgeWithBorderVertices(){
-		Int4 NbSplitEdge=0;
-		SetVertexFieldOn();  
-		Int4 it;
-		Int4 nbvold=nbv;
-		long int verbosity=2;
-		for (it=0;it<nbt;it++)
-		  {
-			Triangle &t=triangles[it];
-			if (t.link)
-			 for (int j=0;j<3;j++)
-			  if(!t.Locked(j) && !t.Hidden(j)){
-				  Triangle &tt = *t.TriangleAdj(j);
-				  if ( &tt && tt.link && it < Number(tt)) 
-					 { // an internal edge 
-					  Vertex &v0 = t[VerticesOfTriangularEdge[j][0]];
-					  Vertex &v1 = t[VerticesOfTriangularEdge[j][1]];
-					  if (v0.on && v1.on)
-						 {
-						  R2 P= ((R2) v0 + (R2) v1)*0.5;
-						  if ( nbv<nbvx) {
-							  vertices[nbv].r = P;
-							  vertices[nbv++].m = Metric(0.5,v0.m,0.5,v1.m);
-							  vertices[nbv].ReferenceNumber=0;
-							  vertices[nbv].DirOfSearch = NoDirOfSearch ;
-						  }
-						  NbSplitEdge++;
-						  if (verbosity>7)
-							cout <<" Internal edge with two vertices on boundary" 
-							  << Number(v0) << " " << Number(v1) << " by " <<  endl;
-						 }
-					 }
-			  }
-		  }
-		ReMakeTriangleContainingTheVertex();    
-		if (nbvold!=nbv) 
-		  {
-			Int4  iv = nbvold;
-			Int4 NbSwap = 0;
-			Icoor2 dete[3];  
-			for (Int4 i=nbvold;i<nbv;i++) 
-			  {// for all the new point
-				Vertex & vi = vertices[i];
-				vi.i = toI2(vi.r);
-				vi.r = toR2(vi.i);
-				//      if (!quadtree->ToClose(vi,seuil,hi,hj)) {
-				// a good new point 
-				vi.ReferenceNumber=0; 
-				vi.DirOfSearch =NoDirOfSearch;
-				//	cout << " Add " << Number(vi) << " " << vi 
-				// << "   " <<  Number(vi) << " <--> " << Number(vi) <<endl;
-				Triangle *tcvi = FindTriangleContening(vi.i,dete);
-				if (tcvi && !tcvi->link) {
-					cout << i <<  " PB insert point " << Number(vi) << vi << Number(vi) 
-					  << " tcvi = " << tcvi << " " << tcvi->link << endl;
-					cout << (*tcvi)[1] <<  (*tcvi)[2] << endl;
-					tcvi = FindTriangleContening(vi.i,dete);
-					cout << (*tcvi)[1] <<  (*tcvi)[2] << endl;
-					MeshError(1001,this);
-				}
-
-
-				quadtree->Add(vi);
-				assert (tcvi && tcvi->det >= 0) ;// internal 
-				Add(vi,tcvi,dete);
-				NbSwap += vi.Optim(1);          
-				iv++;
-				//      }
-			  }
-			if (verbosity>3) 
-			  {
-				cout << "    Nb Of New Point " << iv ;
-				cout << " Nb swap = " << NbSwap << " to  split internal edges with border vertices" ;}
-
-				nbv = iv;
-		  }
-		if (NbSplitEdge >  nbv-nbvold)
-		 cout << " Warning not enough vertices  to split all internal edges "  << endl
-			<< "    we lost " << NbSplitEdge - ( nbv-nbvold) << " Edges Sorry " << endl;
-		if (verbosity>2)
-		 cout << "SplitInternalEdgeWithBorderVertices: Number of splited edge " << NbSplitEdge << endl;
-		return  NbSplitEdge;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::InsertNewPoints{{{1*/
-	Int4 Triangles::InsertNewPoints(Int4 nbvold,Int4 & NbTSwap) {
-		long int verbosity=2;
-		Real8 seuil= 1.414/2 ;// for two close point 
-		Int4 i;
-		// insertion part --- 
-
-		const Int4 nbvnew = nbv-nbvold;
-		if (verbosity>5) 
-		 cout << "    Try to Insert the " <<nbvnew<< " new points " << endl;  
-		Int4 NbSwap=0;
-		Icoor2 dete[3];
-
-		// construction d'un ordre aleatoire 
-		if (! nbvnew) 
-		 return 0; 
-		if (nbvnew) {
-			const Int4 PrimeNumber= AGoodNumberPrimeWith(nbv)  ;
-			Int4 k3 = rand()%nbvnew ; 
-			for (Int4 is3=0; is3<nbvnew; is3++) {
-				register Int4 j = nbvold +(k3 = (k3 + PrimeNumber)% nbvnew);
-				register Int4 i = nbvold+is3; 
-				ordre[i]= vertices + j;
-				ordre[i]->ReferenceNumber=i;
-			}
-			// be carefull 
-			Int4  iv = nbvold;
-			for (i=nbvold;i<nbv;i++) 
-			  {// for all the new point
-				Vertex & vi = *ordre[i];
-				vi.i = toI2(vi.r);
-				vi.r = toR2(vi.i);
-				Real4 hx,hy;
-				vi.m.Box(hx,hy);
-				Icoor1 hi=(Icoor1) (hx*coefIcoor),hj=(Icoor1) (hy*coefIcoor);
-				if (!quadtree->ToClose(vi,seuil,hi,hj)) 
-				  {
-					// a good new point 
-					Vertex & vj = vertices[iv];
-					Int4 j = vj.ReferenceNumber; 
-					assert( &vj== ordre[j]);
-					if(i!=j)
-					  { //  for valgring 
-						Exchange(vi,vj);
-						Exchange(ordre[j],ordre[i]);
-					  }
-					vj.ReferenceNumber=0; 
-					//	cout << " Add " << Number(vj) << " " << vj 
-					// << "   " <<  Number(vi) << " <--> " << Number(vj) <<endl;
-					Triangle *tcvj = FindTriangleContening(vj.i,dete);
-					if (tcvj && !tcvj->link) 
-					  {
-						cerr << i <<  " PB insert point " << Number(vj) << vj << Number(vi) 
-						  << " tcvj = " << tcvj << " " << tcvj->link << endl;
-						cerr << (*tcvj)[1] <<  (*tcvj)[2] << endl;
-						tcvj = FindTriangleContening(vj.i,dete);
-						cout << (*tcvj)[1] <<  (*tcvj)[2] << endl;
-						MeshError(1001,this);
-					  }
-
-
-					quadtree->Add(vj);
-					assert (tcvj && tcvj->det >= 0) ;// internal 
-					Add(vj,tcvj,dete);
-					NbSwap += vj.Optim(1);          
-					iv++;
-				  }
-			  } 
-			if (verbosity>3) {
-				cout << "    Nb Of New Point " << iv << " Nb Of To close Points " << nbv-iv ;
-				cout << " Nb swap = " << NbSwap << " after " ;}
-
-				nbv = iv;
-		}
-
-		for (i=nbvold;i<nbv;i++) 
-		 NbSwap += vertices[i].Optim(1);  
-		if (verbosity>3) 
-		 cout << " NbSwap = " <<  NbSwap << endl;
-
-
-		NbTSwap +=  NbSwap ;
-		return nbv-nbvold;
-
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::NewPoints{{{1*/
-	void  Triangles::NewPoints(Triangles & Bh,int KeepBackVertex) {
-		long int verbosity=2;
-		Int4 nbtold(nbt),nbvold(nbv);
-		if (verbosity>2) 
-		 cout << "  -- Triangles::NewPoints ";
-		if (verbosity>3)cout <<  " nbv (in)  on Boundary  = " << nbv  <<endl;
-		Int4 i,k;
-		int j;
-		Int4 *first_np_or_next_t = new Int4[nbtx];
-		Int4 NbTSwap =0;
-		//    insert old point
-		nbtold = nbt;
-
-		if (KeepBackVertex && (&Bh != this) && (nbv+Bh.nbv< nbvx)) 
-		  {
-			//   Bh.SetVertexFieldOn();
-			for (i=0;i<Bh.nbv;i++)
-			  { 
-				Vertex & bv = Bh[i];
-				if (!bv.on) {
-					vertices[nbv].r = bv.r;
-					vertices[nbv++].m = bv.m;}
-			  }
-			int nbv1=nbv;
-			Bh.ReMakeTriangleContainingTheVertex();     
-			InsertNewPoints(nbvold,NbTSwap)   ;            
-			if (verbosity>2)
-			 cout <<  "      (Nb of Points from background mesh  = " 
-				<< nbv-nbvold  << " / " << nbv1-nbvold << ")" << endl;
-		  }  
-		else 
-		 Bh.ReMakeTriangleContainingTheVertex();     
-
-		Triangle *t;
-		// generation of the list of next Triangle 
-		// at 1 time we test all the triangles
-		Int4 Headt =0,next_t;
-		for(i=0;i<nbt;i++)
-		 first_np_or_next_t[i]=-(i+1);
-		// end list i >= nbt 
-		// the list of test triangle is 
-		// the next traingle on i is  -first_np_or_next_t[i]
-		int iter=0;
-		// Big loop 
-		do {
-			iter++;
-			nbtold = nbt;
-			nbvold = nbv;
-
-			// default size of  IntersectionTriangle
-
-			i=Headt;
-			next_t=-first_np_or_next_t[i];
-			for(t=&triangles[i];i<nbt;t=&triangles[i=next_t],next_t=-first_np_or_next_t[i]) 
-			  { // for each triangle  t
-				// we can change first_np_or_next_t[i]
-				//      cout << " Do the triangle " << i << " Next_t=" << next_t << endl;
-				assert(i>=0 && i < nbt );
-				first_np_or_next_t[i] = iter; 
-				for(j=0;j<3;j++)
-				  { // for each edge 
-					TriangleAdjacent tj(t,j);
-					Vertex & vA = * tj.EdgeVertex(0);
-					Vertex & vB = * tj.EdgeVertex(1);
-
-					if (!t->link) continue;// boundary
-					if (t->det <0) continue;
-					if (t->Locked(j)) continue;
-
-					TriangleAdjacent tadjj = t->Adj(j);	  
-					Triangle * ta= tadjj;
-
-					if (ta->det <0) continue;	  
-
-					R2 A = vA;
-					R2 B = vB;
-
-					k=Number(ta);
-
-					if(first_np_or_next_t[k]==iter)  // this edge is done before 
-					 continue; // next edge of the triangle 
-
-					//const Int4 NbvOld = nbv;
-					lIntTria.SplitEdge(Bh,A,B);
-					lIntTria.NewPoints(vertices,nbv,nbvx);
-				  } // end loop for each edge 
-
-			  }// for triangle   
-
-			if (!InsertNewPoints(nbvold,NbTSwap)) 
-			 break;
-
-			for (i=nbtold;i<nbt;i++)
-			 first_np_or_next_t[i]=iter;
-
-			Headt = nbt; // empty list 
-			for (i=nbvold;i<nbv;i++) 
-			  { // for all the triangle contening the vertex i
-				Vertex * s  = vertices + i;
-				TriangleAdjacent ta(s->t, EdgesVertexTriangle[s->vint][1]);
-				Triangle * tbegin= (Triangle*) ta;
-				Int4 kt;
-				do { 
-					kt = Number((Triangle*) ta);
-					if (first_np_or_next_t[kt]>0) 
-					 first_np_or_next_t[kt]=-Headt,Headt=kt;
-					assert( ta.EdgeVertex(0) == s);
-					ta = Next(Adj(ta));
-				} while ( (tbegin != (Triangle*) ta)); 
-			  }   
-
-		} while (nbv!=nbvold);
-
-		delete []  first_np_or_next_t;
-
-		Int4 NbSwapf =0,NbSwp;
-
-		// bofbof 
-
-
-		NbSwp = NbSwapf;
-		for (i=0;i<nbv;i++)
-		 NbSwapf += vertices[i].Optim(0);
-		/*
-			for (i=0;i<nbv;i++)
-			NbSwapf += vertices[i].Optim(0);
-			for (i=0;i<nbv;i++)
-			NbSwapf += vertices[i].Optim(0);
-			for (i=0;i<nbv;i++)
-			NbSwapf += vertices[i].Optim(0);
-			for (i=0;i<nbv;i++)
-			NbSwapf += vertices[i].Optim(0);
-			*/
-		NbTSwap +=  NbSwapf ;
-		if (verbosity>3) cout << "   " ;
-		if (verbosity>2) 
-		 cout << " Nb Of Vertices =" << nbv << " Nb of triangles = " << nbt-NbOutT 
-			<< " NbSwap final = " << NbSwapf << " Nb Total Of Swap = " << NbTSwap << endl;
-
-
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::NewPointsOld{{{1*/
-	void  Triangles::NewPointsOld(Triangles & Bh) {
-		long int verbosity=2;
-		Real8 seuil= 0.7 ;// for two neart point 
-		if (verbosity>1) 
-		 cout << " begin :  Triangles::NewPointsOld " << endl;
-		Int4 i,k;
-		int j;
-		Int4 BeginNewPoint[3];
-		Int4 EndNewPoint[3];
-#ifdef TRACETRIANGLE
-		Int4 trace=0;
-#endif
-		int step[3];
-		Int4 *first_np_or_next_t = new Int4[nbtx];
-		Int4 ColorEdge[3];
-		Int4 color=-1;
-		Triangle *t;
-		// generation of the list of next Triangle 
-		// at 1 time we test all the triangles
-		Int4 Headt =0,next_t;
-		for(i=0;i<nbt;i++)
-		 first_np_or_next_t[i]=-(i+1);
-		// end list i >= nbt 
-		// the list of test triangle is 
-		// the next Triangle on i is  -first_np_or_next_t[i]
-		Int4 nbtold,nbvold;
-
-		// Big loop 
-		do {
-			nbtold = nbt;
-			nbvold = nbv;
-			// default size of  IntersectionTriangle
-
-			i=Headt;
-			next_t=-first_np_or_next_t[i];
-			for(t=&triangles[i];i<nbt;t=&triangles[i=next_t],next_t=-first_np_or_next_t[i]) 
-			  { // for each triangle  t
-				// we can change first_np_or_next_t[i]
-#ifdef TRACETRIANGLE
-				trace =  TRACETRIANGLE <0 ? 1 : i == TRACETRIANGLE;
-#endif
-				//      cout << " Do the triangle " << i << " Next_t=" << next_t << endl;
-				assert(i>=0 && i < nbt );
-				first_np_or_next_t[i] = nbv; // to save the fist new point of triangle
-				for(j=0;j<3;j++)
-				  { // for each edge 
-					TriangleAdjacent tj(t,j);
-					// color++;// the color is 3i+j
-					color = 3*i + j ;;
-					ColorEdge[j]=color;
-					BeginNewPoint[j]=nbv;
-					EndNewPoint[j]=nbv-1;
-					step[j]=1;// right sens 
-					Vertex & vA = * tj.EdgeVertex(0);
-					Vertex & vB = * tj.EdgeVertex(1);
-
-#ifdef TRACETRIANGLE
-					if(trace) {
-						cout << " i " << Number(vA) <<" j "<<  Number(vB) 
-						  << " "  << t->Locked(j) ;
-					}
-#endif
-					if (!t->link) continue;// boundary
-					if (t->det <0) continue;
-					if (t->Locked(j)) continue;
-
-					TriangleAdjacent tadjj = t->Adj(j);	  
-					Triangle * ta= tadjj;
-
-					if (ta->det <0) continue;	  
-
-					R2 A = vA;
-					R2 B = vB;
-
-					k=Number(ta);
-					// the 2 opposite vertices 
-					const Vertex & vC1  =  *tj.OppositeVertex();
-					const Vertex & vC2 = *tadjj.OppositeVertex();
-
-#ifdef TRACETRIANGLE
-					trace = trace || k == TRACETRIANGLE;
-					if(trace) {
-						cout << "Test Arete " << i << " AB = " << A << B 
-						  << "i "  <<Number(vA)<< "j" <<Number(vB); 
-						cout << " link" <<(int)t->link << " ta=" << Number( ta) 
-						  << " det " <<ta->det ;
-						cout << " hA = " <<vA.m.h << " hB = " <<vB.m.h ;
-						cout << " loc " << ta->Locked(j) << endl;
-					}
-#endif
-
-					if(first_np_or_next_t[k]>0) { // this edge is done before 
-						// find the color of the edge and begin , end of newpoint
-						register int kk = t->NuEdgeTriangleAdj(j);
-						assert ((*t)(VerticesOfTriangularEdge[j][0]) == (*ta)(VerticesOfTriangularEdge[kk][1]));
-						assert ((*t)(VerticesOfTriangularEdge[j][1]) == (*ta)(VerticesOfTriangularEdge[kk][0]));
-						register Int4 kolor =3*k + kk;
-						ColorEdge[j]=kolor;
-						register Int4 kkk= 1;
-						step[j]=-1;// other sens 
-						BeginNewPoint[j]=0;
-						EndNewPoint[j]=-1; // empty list          
-						for (Int4 iv=first_np_or_next_t[k];iv<nbv;iv++) 
-						 if (vertices[iv].color > kolor) 
-						  break; // the color is passed            
-						 else if (vertices[iv].color == kolor) {
-							 EndNewPoint[j]=iv; 
-							 if (kkk) // one time test
-							  kkk=0,BeginNewPoint[j]=iv;}
-							 continue; // next edge of the triangle 
-					} // end  if( k < i) 
-
-
-					const Int4 NbvOld = nbv;
-					lIntTria.SplitEdge(Bh,A,B);
-					// Int4 NbvNp =
-					lIntTria.NewPoints(vertices,nbv,nbvx);
-					Int4 nbvNew=nbv;
-					nbv = NbvOld;
-					for (Int4 iv=NbvOld;iv<nbvNew;iv++) {
-						vertices[nbv].color = color;
-						vertices[nbv].ReferenceNumber=nbv;// circular link
-						R2 C =  vertices[iv].r;
-						vertices[nbv].r =  C;
-						vertices[nbv].m =  vertices[iv].m ;
-						// test if the new point is not to close to the 2 opposite vertex
-						R2 CC1 = C-vC1 , CC2 = C-vC2;
-						if (   (  (vC1.m(CC1) + vertices[nbv].m(CC1)) >  seuil)
-									&& (  (vC2.m(CC2) + vertices[nbv].m(CC2)) >  seuil) )
-						 nbv++;
-					}
-
-					EndNewPoint[j] = nbv-1;
-				  } // end loop for each edge 
-
-#ifdef TRACETRIANGLE
-				if(trace) {
-					// verification des point cree 
-					cout << "\n ------------ " << t->link << " " << t->det 
-					  << " b " << BeginNewPoint[0] << " " << BeginNewPoint[1]
-					  << " " << BeginNewPoint[2] << " " 
-					  << " e " << EndNewPoint[0] << " " << EndNewPoint[1] 
-					  << " " << EndNewPoint[2] << " " 
-					  << " s " << step[0] << " " << step[1] << " " << step[2] << " " 
-					  <<  endl;
-				}
-#endif
-
-				if (!t->link) continue;// boundary
-				if (t->det<=0) continue;// outside 
-				//      continue;
-				for(int j0=0;j0<3;j0++)
-				 for (Int4 i0= BeginNewPoint[j0]; i0 <= EndNewPoint[j0];i0++)
-					{
-					 // find the neart  point one the opposite edge 
-					 // to compute i1
-					 Vertex & vi0 = vertices[i0];
-					 int kstack = 0;
-					 Int4 stack[10];
-					 //   Int4 savRef[10];
-					 int j1 = j0; 
-					 while (j0 != (j1 = NextEdge[j1])) {//loop on the 2 other edge
-						 // computation of the intersection of edge j1 and DOrto
-						 // take the good sens 
-
-						 if (BeginNewPoint[j1]> EndNewPoint[j1])
-						  continue; // 
-						 else if (EndNewPoint[j1] - BeginNewPoint[j1] <1) {
-							 for (Int4 ii1= BeginNewPoint[j1];ii1<=EndNewPoint[j1];ii1++)
-							  stack[kstack++] = ii1;
-							 continue;}
-
-
-							 int k0,k1;
-							 if (step[j1]<0) k0=1,k1=0; // reverse
-							 else k0=0,k1=1; 
-							 R2 V10 = (R2)(*t)[VerticesOfTriangularEdge[j1][k0]];
-							 R2 V11 = (R2)(*t)[VerticesOfTriangularEdge[j1][k1]];
-							 R2 D = V11-V10;
-							 Real8 c0 =  vi0.m(D,(R2) vi0);
-
-							 Real8 c10 =  vi0.m(D,V10);
-							 Real8 c11 =  vi0.m(D,V11);
-
-							 Real8 s;
-							 //cout << " --i0 = " << i0  << D  << V10 << V11 << endl ;
-							 //cout << "   c10 " <<  c10 << " c0 " << c0 << " c11 " << c11 << endl;
-							 if (( c10 < c0 ) && (c0 < c11)) 
-							  s = (c11-c0)/(c11-c10);
-							 else if  (( c11 < c0 ) && (c0 < c10)) 
-							  s = (c11-c0) /(c11-c10);
-							 else break;
-							 R2 VP = V10*s + V11*(1-s);
-							 int sss = (c11-c10) >0 ? 1 : -1;
-							 // find the 2 point by dichotomie
-							 //cout << "   t =" << Number(t) << " c0 " << c0  ;
-							 Int4 ii0 =  BeginNewPoint[j1];
-							 Int4 ii1 =  EndNewPoint[j1];	     
-							 Real8 ciii=-1,cii0=-1,cii1=-1  ;
-							 if ( sss * ((cii0=vi0.m(D,(R2) vertices[ii0]))- c0) >0 )  
-							  stack[kstack++] = ii0;//cout << " add+0 " << ii0;
-							 else if ( sss * ((cii1=  vi0.m(D ,(R2) vertices[ii1]))- c0) < 0 )  
-							  stack[kstack++] = ii1;//cout << " add+1 " << ii1;
-							 else {
-								 while ((ii1-ii0)> 1) {
-									 Int4 iii = (ii0+ii1)/2;
-									 ciii = vi0.m( D ,(R2) vertices[iii]);
-									 //cout << " (iii = " << iii << " " <<  ciii << ") ";
-									 if ( sss * (ciii - c0) <0 )  ii0 = iii;
-									 else ii1 = iii;}	        	      
-									 stack[kstack++] = ii0;// cout << " add0 " << ii0;
-									 if (ii1 != ii0)  stack[kstack++] = ii1;//cout << " add1 " << ii1;
-							 }
-							 if (kstack >5) // bug ?
-							  cout << "NewPoints: bug????? " << kstack << " stack  " << stack[kstack]<< endl;
-					 }
-
-					 stack[kstack++] = -1; // to stop
-					 Int4 i1;
-					 kstack =0; 
-					 while( (i1=stack[kstack++]) >= 0) 
-						{ // the two parameter is i0 and i1 
-						 assert(i1 < nbv && i1 >= 0);
-						 assert(i0 < nbv && i0 >= 0);
-						 assert(i1 != i0);
-						 R2 v01 = (R2) vertices[i1]- (R2) vertices[i0];
-						 Real8 d01 = (vertices[i0].m(v01) + vertices[i1].m(v01));
-
-
-#ifdef TRACETRIANGLE
-						 if(trace) {
-							 cout << "\n test j" << j <<" "  << i0 
-								<< " " << i1 << " d01=" << d01 <<endl;}
-#endif
-						 assert (i0 >= nbvold);
-						 assert (i1 >= nbvold);
-						 assert(i0 != i1);
-						 if (d01 == 0) 
-						  break; 
-						 if ( d01 < seuil) 
-						  if (i1<nbvold) {
-							  // remove all the points i0;
-							  register Int4 ip,ipp;
-							  for  (ip=i0;i0 != (ipp = vertices[ip].ReferenceNumber);ip=ipp)
-								vertices[ip].ReferenceNumber = -1;// mark remove
-							  vertices[ip].ReferenceNumber = -1;// mark remove
-						  }
-						  else {
-							  // remove on of two points
-							  register Int4 ip0, ip1, ipp0,ipp1;
-							  register int kk0=1,kk1=1;
-							  // count the number of common points to compute weight w0,w1
-							  for  (ip0=i0;i0 != (ipp0 = vertices[ip0].ReferenceNumber);ip0=ipp0) kk0++;
-							  for  (ip1=i1;i1 != (ipp1 = vertices[ip1].ReferenceNumber);ip1=ipp1) kk1++;
-
-							  register Real8 w0 = ((Real8) kk0)/(kk0+kk1);
-							  register Real8 w1 = ((Real8) kk1)/(kk0+kk1);
-
-							  // make a circular link
-							  Exchange(vertices[i0].ReferenceNumber,vertices[i1].ReferenceNumber);
-							  // the new coordinate 
-							  R2 C //= vertices[i0] ;
-							  =  vertices[i0].r *w0 + vertices[i1].r* w1;
-
-#ifdef TRACETRIANGLE
-							  if(trace) {
-								  cout << "\n ref = "<< vertices[i0].ref << " " <<vertices[i1].ref <<endl;
-							  }
-#endif    
-							  // update the new point points of the list 
-							  for  (ip0=i0;i0 != (ipp0 = vertices[ip0].ReferenceNumber);ip0=ipp0)
-								vertices[ip0].r = C;	      
-							  vertices[ip0].r = C;
-						  }
-						}
-					} // for (i0= ....
-			  }// for triangle   
-
-			// remove of all the double points
-
-			Int4 ip,ipp,kkk=nbvold;
-			for (i=nbvold;i<nbv;i++) 
-			 if (vertices[i].ReferenceNumber>=0) {// good points
-				 //  cout <<" i = " << i ;
-				 for  (ip=i;i != (ipp = vertices[ip].ReferenceNumber);ip=ipp)
-				  vertices[ip].ReferenceNumber = -1;// mark remove
-				 vertices[ip].ReferenceNumber = -1;// mark remove
-				 // cout << i << " ---> " << kkk << endl;        
-				 vertices[kkk] = vertices[i];
-				 vertices[kkk].i = toI2(vertices[kkk].r);
-				 vertices[kkk++].ReferenceNumber = 0;
-
-			 } 
-
-			// insertion part --- 
-
-			const Int4 nbvnew = kkk-nbvold;
-
-			cout << "    Remove " << nbv - kkk  << " to close  vertex " ;
-			cout << " and   Insert the " <<nbvnew<< " new points " << endl;  
-			nbv = kkk;
-			Int4 NbSwap=0;
-			Icoor2 dete[3];
-
-			// construction d'un ordre aleatoire 
-			if (! nbvnew) 
-			 break; 
-			if (nbvnew) {
-				const Int4 PrimeNumber= AGoodNumberPrimeWith(nbv)  ;
-				Int4 k3 = rand()%nbvnew ; 
-				for (Int4 is3=0; is3<nbvnew; is3++) 
-				 ordre[nbvold+is3]= &vertices[nbvold +(k3 = (k3 + PrimeNumber)% nbvnew)];
-
-				for (i=nbvold;i<nbv;i++) 
-				  { Vertex * vi = ordre[i];
-					Triangle *tcvi = FindTriangleContening(vi->i,dete);
-					//     Vertex * nv =  quadtree->NearestVertex(vi->i.x,vi->i.y);
-					//      cout << " Neart Vertex of "  << Number(vi)<< vi->i << " is " 
-					//   << Number(nv) << nv->i  << endl;
-					// Int4  kt = Number(tcvi);
-					// 
-
-					quadtree->Add(*vi); //
-					assert (tcvi->det >= 0) ;// internal 
-					Add(*vi,tcvi,dete),NbSwap += vi->Optim(1);          
-				  }  
-			}
-			cout << " Nb swap = " << NbSwap << " after " ;
-
-			for (i=nbvold;i<nbv;i++) 
-			 NbSwap += vertices[i].Optim(1);  
-			cout << NbSwap << endl;
-
-			for (i=nbtold;i<nbt;i++)
-			 first_np_or_next_t[i]=1;
-
-			Headt = nbt; // empty list 
-			for (i=nbvold;i<nbv;i++) 
-			  { // for all the triangle contening the vertex i
-				Vertex * s  = vertices + i;
-				TriangleAdjacent ta(s->t, EdgesVertexTriangle[s->vint][1]);
-				Triangle * tbegin= (Triangle*) ta;
-				Int4 kt;
-				do { 
-					kt = Number((Triangle*) ta);
-					if (first_np_or_next_t[kt]>0) 
-					 first_np_or_next_t[kt]=-Headt,Headt=kt;
-					assert( ta.EdgeVertex(0) == s);
-					ta = Next(Adj(ta));
-				} while ( (tbegin != (Triangle*) ta)); 
-			  }
-
-
-		} while (nbv!=nbvold);
-		delete []  first_np_or_next_t;
-		cout << " end :  Triangles::NewPoints old  nbv=" << nbv << endl;
-
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::Insert{{{1*/
-	void Triangles::Insert() {
-		long int verbosity=2;
-		if (verbosity>2) cout << "  -- Insert initial " << nbv << " vertices " << endl ;
-		Triangles * OldCurrentTh =CurrentTh;
-
-		CurrentTh=this;
-		double time0=CPUtime(),time1,time2,time3;
-		SetIntCoor();
-		Int4 i;
-		for (i=0;i<nbv;i++) 
-		 ordre[i]= &vertices[i] ;
-
-		// construction d'un ordre aleatoire 
-		const Int4 PrimeNumber= AGoodNumberPrimeWith(nbv) ;
-		Int4 k3 = rand()%nbv ; 
-		for (int is3=0; is3<nbv; is3++) 
-		 ordre[is3]= &vertices[k3 = (k3 + PrimeNumber)% nbv];
-
-
-
-
-		for (i=2 ; det( ordre[0]->i, ordre[1]->i, ordre[i]->i ) == 0;) 
-		 if  ( ++i >= nbv) {
-			 cerr << " All the vertices are aline " << endl;
-			 MeshError(998,this); }
-
-			 // echange i et 2 dans ordre afin 
-			 // que les 3 premiers ne soit pas aligne
-			 Exchange( ordre[2], ordre[i]);
-
-			 // on ajoute un point a l'infini pour construire le maillage
-			 // afin d'avoir une definition simple des aretes frontieres
-			 nbt = 2;
-
-
-			 // on construit un maillage trivale forme
-			 // d'une arete et de 2 triangles
-			 // construit avec le 2 aretes orientes et 
-			 Vertex *  v0=ordre[0], *v1=ordre[1];
-
-			 triangles[0](0) = 0; // sommet pour infini 
-			 triangles[0](1) = v0;
-			 triangles[0](2) = v1;
-
-			 triangles[1](0) = 0;// sommet pour infini 
-			 triangles[1](2) = v0;
-			 triangles[1](1) = v1;
-			 const int e0 = OppositeEdge[0];
-			 const int e1 = NextEdge[e0];
-			 const int e2 = PreviousEdge[e0];
-			 triangles[0].SetAdj2(e0, &triangles[1] ,e0);
-			 triangles[0].SetAdj2(e1, &triangles[1] ,e2);
-			 triangles[0].SetAdj2(e2, &triangles[1] ,e1);
-
-			 triangles[0].det = -1;  // faux triangles
-			 triangles[1].det = -1;  // faux triangles
-
-			 triangles[0].SetTriangleContainingTheVertex();
-			 triangles[1].SetTriangleContainingTheVertex();
-
-			 triangles[0].link=&triangles[1];
-			 triangles[1].link=&triangles[0];
-
-			 //  nbtf = 2;
-			 if (  !quadtree )  quadtree = new QuadTree(this,0);
-			 quadtree->Add(*v0);
-			 quadtree->Add(*v1);
-
-			 // on ajoute les sommets un Ò un 
-			 Int4 NbSwap=0;
-
-			 time1=CPUtime();
-
-			 if (verbosity>3) cout << "  -- Begin of insertion process " << endl;
-
-			 for (Int4 icount=2; icount<nbv; icount++) {
-				 Vertex *vi  = ordre[icount];
-				 //    cout << " Insert " << Number(vi) << endl;
-				 Icoor2 dete[3];
-				 Triangle *tcvi = FindTriangleContening(vi->i,dete);
-				 quadtree->Add(*vi); 
-				 Add(*vi,tcvi,dete);
-				 NbSwap += vi->Optim(1,0);
-
-			 }// fin de boucle en icount
-			 time2=CPUtime();
-			 if (verbosity>3) 
-			  cout << "    NbSwap of insertion " <<    NbSwap 
-				 << " NbSwap/Nbv " <<  (float) NbSwap / (float) nbv 
-				 << " NbUnSwap " << NbUnSwap << " Nb UnSwap/Nbv " 
-				 << (float)NbUnSwap /(float) nbv 
-				 <<endl;
-			 NbUnSwap = 0;
-			 // construction d'un ordre aleatoire 
-			 //  const int PrimeNumber= (nbv % 999983) ? 1000003: 999983 ;
-#ifdef NBLOOPOPTIM
-
-			 k3 = rand()%nbv ; 
-			 for (int is4=0; is4<nbv; is4++) 
-			  ordre[is4]= &vertices[k3 = (k3 + PrimeNumber)% nbv];
-
-			 double timeloop = time2 ;
-			 for(int Nbloop=0;Nbloop<NBLOOPOPTIM;Nbloop++) 
-				{
-				 double time000 = timeloop;
-				 Int4  NbSwap = 0;
-				 for (int is1=0; is1<nbv; is1++) 
-				  NbSwap += ordre[is1]->Optim(0,0);
-				 timeloop = CPUtime();
-				 if (verbosity>3) 
-				  cout << "    Optim Loop "<<Nbloop<<" NbSwap: " <<  NbSwap 
-					 << " NbSwap/Nbv " 	   <<  (float) NbSwap / (float) nbv 
-					 << " CPU=" << timeloop - time000 << "  s, " 
-					 << " NbUnSwap/Nbv " << (float)NbUnSwap /(float) nbv  
-					 <<  endl;
-				 NbUnSwap = 0;
-				 if(!NbSwap) break;
-				}
-			 ReMakeTriangleContainingTheVertex(); 
-			 // because we break the TriangleContainingTheVertex
-#endif
-			 time3=CPUtime();
-			 if (verbosity>4) 
-			  cout << "    init " << time1 - time0 << " initialisation,  " 
-				 << time2 - time1 << "s, insert point  " 
-				 << time3 -time2 << "s, optim " << endl
-				 << "     Init Total Cpu Time = " << time3 - time0 << "s " << endl;
-
-			 CurrentTh=OldCurrentTh;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::ForceBoundary{{{1*/
-	void Triangles::ForceBoundary() {
-		long int verbosity=2;
-		if (verbosity > 2)
-		 cout << "  -- ForceBoundary  nb of edge " << nbe << endl;
-		int k=0;
-		Int4  nbfe=0,nbswp=0,Nbswap=0;
-		for (Int4 t = 0; t < nbt; t++)  
-		 if (!triangles[t].det)
-		  k++,cerr << " det T" << t << " = " << 0 << endl;
-		if (k!=0) {
-			cerr << " ther is  " << k << "  triangles of mes = 0 " << endl;
-			MeshError(11,this);}
-
-			TriangleAdjacent ta(0,0);
-			for (Int4 i = 0; i < nbe; i++) 
-			  {
-				nbswp =  ForceEdge(edges[i][0],edges[i][1],ta);
-
-				if ( nbswp < 0) 	k++;
-				else Nbswap += nbswp;
-				if (nbswp) nbfe++;
-				if ( nbswp < 0 && k < 5)
-				  {
-					cerr << " Missing  Edge " << i << " v0 =  " << Number(edges[i][0]) << edges[i][0].r
-					  <<" v1= " << Number(edges[i][1]) << edges[i][1].r << " " << edges[i].on->Cracked() << "  " << (Triangle *) ta ;
-					if(ta.t)
-					  {
-						Vertex *aa = ta.EdgeVertex(0), *bb = ta.EdgeVertex(1);  
-						cerr << " crossing with  [" << Number(aa) << ", " << Number(bb) << "]\n";
-					  }
-					else cerr << endl;
-
-				  }
-				if ( nbswp >=0 && edges[i].on->Cracked())
-				 ta.SetCracked();
-			  }
-
-
-			if (k!=0) {
-				cerr << " they is " << k << " lost edges " << endl;
-				cerr << " The boundary is crossing may be!" << endl;
-				MeshError(10,this);
-			}
-			for (Int4 j=0;j<nbv;j++)
-			 Nbswap +=  vertices[j].Optim(1,0);
-			if (verbosity > 3)
-			 cout << "     Nb of inforced edge = " << nbfe << " Nb of Swap " << Nbswap << endl;
-
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::FindSubDomain{{{1*/
-	void Triangles::FindSubDomain(int OutSide=0) {
-		long int verbosity=0;
-
-		if (verbosity >2)
-		  {
-			if (OutSide)
-			 cout << "  -- Find all external sub-domain ";	
-			else
-			 cout << "  -- Find all internal sub-domain ";
-			if(verbosity>99)
-			  {
-
-				for(int i=0;i<nbt;++i)
-				 cout << i<< " " << triangles[i] << endl;
-			  }
-
-		  }
-		// if (verbosity > 4) cout << " OutSide=" << OutSide << endl;
-		short * HeapArete = new short[nbt];
-		Triangle  **  HeapTriangle = new Triangle*  [nbt];
-		Triangle *t,*t1;
-		Int4 k,it;
-
-		for (Int4 itt=0;itt<nbt;itt++) 
-		 triangles[itt].link=0; // par defaut pas de couleur
-
-		Int4  NbSubDomTot =0;
-		for ( it=0;it<nbt;it++)  { 
-			if ( ! triangles[it].link  ) {
-				t = triangles + it;
-				NbSubDomTot++;; // new composante connexe
-				Int4 i = 0; // niveau de la pile 
-				t->link = t ; // sd forme d'un triangle cicular link
-
-				HeapTriangle[i] =t ; 
-				HeapArete[i] = 3;
-
-				while (i >= 0) // boucle sur la pile
-				  { while ( HeapArete[i]--) // boucle sur les 3 aretes 
-					  { 
-						int na =  HeapArete[i];
-						Triangle * tc =  HeapTriangle[i]; // triangle courant
-						if( ! tc->Locked(na)) // arete non frontiere
-						  {
-							Triangle * ta = tc->TriangleAdj(na) ; // næ triangle adjacent
-							if (ta->link == 0 ) // non deja chainer => on enpile
-							  { 
-								i++;
-								ta->link = t->link ;  // on chaine les triangles
-								t->link = ta ;  // d'un meme sous domaine          
-								HeapArete[i] = 3; // pour les 3 triangles adjacents
-								HeapTriangle[i] = ta;
-							  }}
-					  } // deplie fin de boucle sur les 3 adjacences
-					i--;
-				  }          
-			}      
-		}
-
-		// supression de tous les sous domaine infini <=>  contient le sommet NULL
-		it =0;
-		NbOutT = 0;
-		while (it<nbt) {
-			if (triangles[it].link) 
-			  { 
-				if (!( triangles[it](0) &&  triangles[it](1) &&  triangles[it](2) )) 
-				  {
-					// infini triangle 
-					NbSubDomTot --;
-					//  cout << " triangle infini " << it << triangles[it] << endl;
-					t=&triangles[it];
-					NbOutT--;  // on fait un coup de trop. 
-					while  (t){ // cout << Number(t) << " " << endl;
-						NbOutT++;
-						t1=t;
-						t=t->link;
-						t1->link=0;}//while (t)
-				  }
-			  }   
-			it++;} // end while (it<nbt)
-			if (nbt == NbOutT ||  !NbSubDomTot) 
-			  {
-				cout << "\n error : " <<  NbOutT << " " << NbSubDomTot <<" " << nbt << endl;
-				cerr << "Error: The boundary is not close => All triangles are outside " << endl;
-				MeshError(888,this);
-			  }
-
-			delete [] HeapArete;
-			delete [] HeapTriangle;
-
-
-			if (OutSide|| !Gh.subdomains || !Gh.NbSubDomains ) 
-			  { // No geom sub domain
-				Int4 i;
-				if (subdomains) delete [] subdomains;
-				subdomains = new SubDomain[ NbSubDomTot];
-				NbSubDomains=  NbSubDomTot;
-				for ( i=0;i<NbSubDomains;i++) {
-					subdomains[i].head=NULL;
-					subdomains[i].ref=i+1;
-				}
-				Int4 * mark = new Int4[nbt];
-				for (it=0;it<nbt;it++)
-				 mark[it]=triangles[it].link ? -1 : -2;
-
-				it =0;
-				k = 0;
-				while (it<nbt) {
-					if (mark[it] == -1) {
-						t1 = & triangles[it];
-						t = t1->link;
-						mark[it]=k;
-						subdomains[k].head = t1;
-						// cout << " New -- " << Number(t1) << " " << it << endl;
-						do {// cout << " k " << k << " " << Number(t) << endl;
-							mark[Number(t)]=k;
-							t=t->link;
-						} while (t!=t1);
-						mark[it]=k++;}
-						//    else if(mark[it] == -2 ) triangles[it].Draw(999);
-						it++;} // end white (it<nbt)
-						assert(k== NbSubDomains);
-						if(OutSide) 
-						  {
-							//  to remove all the sub domain by parity adjacents
-							//  because in this case we have only the true boundary edge
-							// so teh boundary is manifold
-							Int4 nbk = NbSubDomains;
-							while (nbk)
-							 for (it=0;it<nbt && nbk ;it++)
-							  for (int na=0;na<3 && nbk ;na++)
-								 {
-								  Triangle *ta = triangles[it].TriangleAdj(na);
-								  Int4 kl = ta ? mark[Number(ta)] : -2;
-								  Int4 kr = mark[it];
-								  if(kr !=kl) {
-									  //cout << kl << " " << kr << " rl "  << subdomains[kl].ref
-									  // << " rr " << subdomains[kr].ref ;
-									  if (kl >=0 && subdomains[kl].ref <0 && kr >=0 && subdomains[kr].ref>=0)
-										nbk--,subdomains[kr].ref=subdomains[kl].ref-1;
-									  if (kr >=0 && subdomains[kr].ref <0 && kl >=0 && subdomains[kl].ref>=0)
-										nbk--,subdomains[kl].ref=subdomains[kr].ref-1;
-									  if(kr<0 && kl >=0 && subdomains[kl].ref>=0)
-										nbk--,subdomains[kl].ref=-1;
-									  if(kl<0 && kr >=0 && subdomains[kr].ref>=0)
-										nbk--,subdomains[kr].ref=-1;
-									  //   cout << " after \t "   
-									  //	 << kl << subdomains[kl].ref << " rr " << kr 
-									  // << subdomains[kr].ref << endl;
-								  }
-								 }
-							//  cout << subdomains[0].ref << subdomains[1].ref << endl;
-							Int4  j=0;
-							for ( i=0;i<NbSubDomains;i++)
-							 if((-subdomains[i].ref) %2) { // good 
-								 //cout << " sudom ok  = " << i << " " << subdomains[i].ref
-								 // << " " << (-subdomains[i].ref) %2 << endl;
-								 if(i != j) 
-								  Exchange(subdomains[i],subdomains[j]);
-								 j++;}
-							 else
-								{ //cout << " remove sub domain " << i << endl;
-								 t= subdomains[i].head;
-								 while  (t){// cout << Number(t) << " " << endl;
-									 NbOutT++;
-									 t1=t;
-									 t=t->link;
-									 t1->link=0;}//while (t)
-								}
-
-							if(verbosity>4)
-							 cout << " Number of remove sub domain (OutSideMesh) =" << NbSubDomains-j << endl;
-							NbSubDomains=j;
-						  }
-
-						delete []  mark; 
-
-			  }
-			else
-			  { // find the head for all sub domaine
-				if (Gh.NbSubDomains != NbSubDomains && subdomains)
-				 delete [] subdomains, subdomains=0;
-				if (! subdomains  ) 
-				 subdomains = new SubDomain[ Gh.NbSubDomains];
-				NbSubDomains =Gh.NbSubDomains;
-				if(verbosity>4)
-				 cout << "     find the " << NbSubDomains << " sub domain " << endl;
-				Int4 err=0;
-				ReMakeTriangleContainingTheVertex();
-				Int4 * mark = new Int4[nbt];
-				Edge **GeometricalEdgetoEdge = MakeGeometricalEdgeToEdge();
-
-				for (it=0;it<nbt;it++)
-				 mark[it]=triangles[it].link ? -1 : -2;
-				Int4 inew =0;
-				for (Int4 i=0;i<NbSubDomains;i++) 
-				  {
-					GeometricalEdge &eg = *Gh.subdomains[i].edge;
-					subdomains[i].ref = Gh.subdomains[i].ref;
-					int ssdlab = subdomains[i].ref;
-					// by carefull is not easy to find a edge create from a GeometricalEdge 
-					// see routine MakeGeometricalEdgeToEdge
-					Edge &e = *GeometricalEdgetoEdge[Gh.Number(eg)];
-					assert(&e);
-					Vertex * v0 =  e(0),*v1 = e(1);
-					Triangle *t  = v0->t;
-					int sens = Gh.subdomains[i].sens;
-					// test if ge and e is in the same sens 
-					//	cout << " geom edge = " <<  Gh.Number(eg) <<" @" << &eg << " ref = " << subdomains[i].ref 
-					//     << " ref edge =" << eg.ref << " sens " << sens ;
-					if (((eg[0].r-eg[1].r),(e[0].r-e[1].r))<0)
-					 sens = -sens ;
-					subdomains[i].sens = sens;
-					subdomains[i].edge = &e;
-					//	cout << " sens " << sens << " in geom " << eg[0].r << eg[1].r << " in mesh  " << e[0].r << e[1].r << endl;
-					//	cout << "  v0 , v1 = " << Number(v0) << " "  << Number(v1) << endl;
-					assert(t && sens);
-
-					TriangleAdjacent  ta(t,EdgesVertexTriangle[v0->vint][0]);// previous edges
-
-					while (1) 
-					  {
-						assert( v0 == ta.EdgeVertex(1) );
-						//	 cout << " recherche " << Number( ta.EdgeVertex(0)) << endl;
-						if (ta.EdgeVertex(0) == v1) { // ok we find the edge
-							if (sens>0)  
-							 subdomains[i].head=t=Adj(ta);
-							else 
-							 subdomains[i].head=t=ta;
-							//cout << "      triangle  =" << Number(t) << " = " << (*t)[0].r <<  (*t)[1].r <<  (*t)[2].r << endl;
-							if(t<triangles || t >= triangles+nbt || t->det < 0 
-										|| t->link == 0) // Ajoute aout 200 
-							  {
-								cerr << " Error in the def of sub domain "<<i
-								  << " form border " << NbSubDomains - i  << "/" << NbSubDomains
-								  << ": Bad sens  " << Gh.Number(eg) <<" "<< sens <<  endl;  
-								err++;
-								break;}
-								Int4 it = Number(t);
-								if (mark[it] >=0) {
-									if(verbosity>10)
-									 cerr << "     Warning: the sub domain " << i << " ref = " << subdomains[i].ref 
-										<< " is previouly defined with "  <<mark[it] << " ref = " << subdomains[mark[it]].ref
-										<< " skip this def " << endl;
-									break;}
-									if(i != inew) 
-									 Exchange(subdomains[i],subdomains[inew]);
-									inew++;
-									Triangle *tt=t;
-									Int4 kkk=0;
-									do 
-									  {
-										kkk++;
-										assert(mark[Number(tt)]<0);
-										mark[Number(tt)]=i;
-										tt=tt->link;
-									  } while (tt!=t);
-									if(verbosity>7)
-									 cout << "     Nb de triangles dans le sous domaine " << i << " de ref " << subdomains[i].ref << " = " << kkk << endl;
-									break;}
-									ta = Previous(Adj(ta));         
-									if(t == (Triangle *) ta) {
-										err++;
-										cerr << " Error in the def of sub domain " << i 
-										  << " edge=" << Gh.Number(eg) << " " << sens << endl;
-										break;}
-										//         cout << " NB of remove subdomain " << NbSubDomTot-NbSubDomains<< endl;
-
-					  }
-
-				  }
-				if (err) MeshError(777,this);
-
-				if (inew < NbSubDomains) {
-					if (verbosity>5) 
-					 cout << "     Warning: We remove " << NbSubDomains-inew << " SubDomains " << endl;
-					NbSubDomains=inew;}
-
-
-					for (it=0;it<nbt;it++)
-					 if ( mark[it] ==-1 ) 
-					  NbOutT++,triangles[it].link =0;
-					delete [] GeometricalEdgetoEdge;
-					delete [] mark;
-
-			  }
-			NbOutT=0;
-			for (it=0;it<nbt;it++) 
-			 if(!triangles[it].link)  NbOutT++;
-			if (verbosity> 4)
-			 cout << "    " ;
-			if (verbosity> 2)
-			 cout << " Nb of Sub borned Domain  = " <<  NbSubDomTot << " NbOutTriangles = " << NbOutT <<endl;
-
-
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::ReNumberingVertex{{{1*/
-	void Triangles::ReNumberingVertex(Int4 * renu) {
-		// warning be carfull because pointeur
-		// from on mesh to over mesh 
-		//  --  so do ReNumbering a the beginning
-		Vertex * ve = vertices+nbv;
-		Int4 it,ie,i;
-
-		for ( it=0;it<nbt;it++) 
-		 triangles[it].ReNumbering(vertices,ve,renu);
-
-		for ( ie=0;ie<nbe;ie++) 
-		 edges[ie].ReNumbering(vertices,ve,renu);
-
-		for (i=0;i< NbVerticesOnGeomVertex;i++)
-		  {
-			Vertex *v = VerticesOnGeomVertex[i].mv;
-			if (v>=vertices && v < ve)
-			 VerticesOnGeomVertex[i].mv=vertices+renu[Number(v)];
-		  }
-
-		for (i=0;i< NbVerticesOnGeomEdge;i++)
-		  {
-			Vertex *v =VerticesOnGeomEdge[i].mv;
-			if (v>=vertices && v < ve)
-			 VerticesOnGeomEdge[i].mv=vertices+renu[Number(v)];
-		  }
-
-		for (i=0;i< NbVertexOnBThVertex;i++)
-		  {
-			Vertex *v=VertexOnBThVertex[i].v;
-			if (v>=vertices && v < ve)
-			 VertexOnBThVertex[i].v=vertices+renu[Number(v)];
-		  }
-
-		for (i=0;i< NbVertexOnBThEdge;i++)
-		  {
-			Vertex *v=VertexOnBThEdge[i].v;
-			if (v>=vertices && v < ve)
-			 VertexOnBThEdge[i].v=vertices+renu[Number(v)];
-		  }
-
-		// move the Vertices without a copy of the array 
-		// be carefull not trivial code 
-		Int4 j;
-		for ( it=0;it<nbv;it++) // for all sub cycles of the permutation renu
-		 if (renu[it] >= 0) // a new sub cycle
-			{ 
-			 i=it;
-			 Vertex ti=vertices[i],tj;
-			 while ( (j=renu[i]) >= 0) 
-				{ // i is old, and j is new 
-				 renu[i] = -1-renu[i]; // mark 
-				 tj = vertices[j]; // save new
-				 vertices[j]= ti; // new <- old
-				 i=j;     // next 
-				 ti = tj;
-				}  
-			}
-		if (quadtree) 
-		  {  delete quadtree;
-			quadtree = new QuadTree(this);
-		  }
-		for ( it=0;it<nbv;it++)
-		 renu[i]= -renu[i]-1;
-
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::ReNumberingTheTriangleBySubDomain{{{1*/
-	void Triangles::ReNumberingTheTriangleBySubDomain(bool justcompress) {
-		long int verbosity=0;
-		Int4 *renu= new Int4[nbt];
-		register Triangle *t0,*t,*te=triangles+nbt;
-		register Int4 k=0,it,i,j;
-
-		for ( it=0;it<nbt;it++) 
-		 renu[it]=-1; // outside triangle 
-		for ( i=0;i<NbSubDomains;i++)
-		  { 
-			t=t0=subdomains[i].head;
-			assert(t0); // no empty sub domain
-			do { 
-				Int4 kt = Number(t);
-				assert(kt>=0 && kt < nbt );
-				assert(renu[kt]==-1);
-				renu[kt]=k++;
-			}
-			while (t0 != (t=t->link));
-		  }
-		if (verbosity>9)
-		 cout << " number of inside triangles " << k << " nbt = " << nbt << endl;
-		// take is same numbering if possible    
-		if(justcompress)
-		 for ( k=0,it=0;it<nbt;it++) 
-		  if(renu[it] >=0 ) 
-			renu[it]=k++;
-
-		// put the outside triangles at the end
-		for ( it=0;it<nbt;it++) 
-		 if (renu[it]==-1) 
-		  renu[it]=k++;
-
-		assert(k == nbt);
-		// do the change on all the pointeur 
-		for ( it=0;it<nbt;it++)
-		 triangles[it].ReNumbering(triangles,te,renu);
-
-		for ( i=0;i<NbSubDomains;i++)
-		 subdomains[i].head=triangles+renu[Number(subdomains[i].head)];
-
-		// move the Triangles  without a copy of the array 
-		// be carefull not trivial code 
-		for ( it=0;it<nbt;it++) // for all sub cycles of the permutation renu
-		 if (renu[it] >= 0) // a new sub cycle
-			{ 
-			 i=it;
-			 Triangle ti=triangles[i],tj;
-			 while ( (j=renu[i]) >= 0) 
-				{ // i is old, and j is new 
-				 renu[i] = -1; // mark 
-				 tj = triangles[j]; // save new
-				 triangles[j]= ti; // new <- old
-				 i=j;     // next 
-				 ti = tj;
-				}  
-			}
-		delete [] renu;
-		nt = nbt - NbOutT;
-
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::ConsRefTriangle{{{1*/
-	Int4  Triangles::ConsRefTriangle(Int4 *reft) const {
-		long int verbosity=0;
-		assert(reft);
-		register Triangle *t0,*t;
-		register Int4 k=0, num;   
-		for (Int4 it=0;it<nbt;it++) 
-		 reft[it]=-1; // outside triangle 
-		for (Int4 i=0;i<NbSubDomains;i++)
-		  { 
-			t=t0=subdomains[i].head;
-			assert(t0); // no empty sub domain
-			// register Int4 color=i+1;// because the color 0 is outside triangle
-			do { k++;
-				num = Number(t);
-				assert(num>=0 &&num < nbt);
-				reft[num]=i;
-				//  cout << Number(t0) << " " <<Number(t)<< " "  << i << endl;
-			}
-			while (t0 != (t=t->link));
-		  }
-		//  NbOutT = nbt - k;
-		if (verbosity>5) 
-		 cout << " Nb of Sub Domain =" << NbSubDomains  << " Nb of In Triangles " << k 
-			<< " Nbt = " << nbt << " Out Triangles = " << nbt - k <<  endl;
-
-		return k;   
-
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::GeomToTriangles1{{{1*/
-	void Triangles::GeomToTriangles1(Int4 inbvx,int KeepBackVertices) { 
-		Gh.NbRef++;// add a ref to Gh
-
-
-		/************************************************************************* 
-		// methode in 2 step
-		// 1 - compute the number of new edge to allocate
-		// 2 - construct the edge
-remark: 
-in this part we suppose to have a background mesh with the same
-geometry 
-
-To construct the discretisation of the new mesh we have to 
-rediscretize the boundary of background Mesh 
-because we have only the pointeur from the background mesh to the geometry.
-We need the abcisse of the background mesh vertices on geometry
-so a vertex is 
-0 on GeometricalVertex ;
-1 on GeometricalEdge + abcisse
-2 internal 
-
-		 *************************************************************************/
-		assert(&BTh.Gh == &Gh);
-
-		long int verbosity=0;
-		BTh.NbRef++; // add a ref to BackGround Mesh
-		PreInit(inbvx);
-		BTh.SetVertexFieldOn();
-		int * bcurve = new int[Gh.NbOfCurves]; // 
-
-		// we have 2 ways to make the loop 
-		// 1) on the geometry 
-		// 2) on the background mesh
-		//  if you do the loop on geometry, we don't have the pointeur on background,
-		//  and if you do the loop in background we have the pointeur on geometry
-		// so do the walk on  background
-		//  Int4 NbVerticesOnGeomVertex;
-		//  VertexOnGeom * VerticesOnGeomVertex;  
-		//  Int4 NbVerticesOnGeomEdge;
-		//  VertexOnGeom * VerticesOnGeomEdge;
-
-
-		NbVerticesOnGeomVertex=0;
-		NbVerticesOnGeomEdge=0;
-		//1 copy of the  Required vertex
-		int i; 
-		for ( i=0;i<Gh.nbv;i++)
-		 if (Gh[i].Required()) NbVerticesOnGeomVertex++;
-
-		VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];
-		VertexOnBThVertex = new VertexOnVertex[NbVerticesOnGeomVertex];
-		//
-		if( NbVerticesOnGeomVertex >= nbvx) 
-		  {
-			cerr << " Too much vertices on geometry " << NbVerticesOnGeomVertex << " >= " << nbvx << endl; 
-			MeshError(1,this);
-		  }
-		assert(vertices);
-		for (i=0;i<Gh.nbv;i++)
-		 if (Gh[i].Required()) {//Gh  vertices Required
-			 vertices[nbv] =  Gh[i];
-			 vertices[nbv].i = I2(0,0);
-			 Gh[i].to = vertices + nbv;// save Geom -> Th
-			 VerticesOnGeomVertex[nbv]= VertexOnGeom(vertices[nbv],Gh[i]);
-			 // cout << "--------- "  <<Number(Gh[i].to) << " " << Gh[i].to << " " << i << endl;
-			 nbv++;}
-		 else Gh[i].to=0;
-		// 
-		for (i=0;i<BTh.NbVerticesOnGeomVertex;i++)
-		  { 
-			VertexOnGeom & vog = BTh.VerticesOnGeomVertex[i];
-			if (vog.IsRequiredVertex()) {
-				GeometricalVertex * gv = vog;
-				Vertex *bv = vog;
-				assert(gv->to);// use of Geom -> Th
-				VertexOnBThVertex[NbVertexOnBThVertex++] = VertexOnVertex(gv->to,bv);
-				gv->to->m = bv->m; // for taking the metrix of the background mesh
-				;}
-		  }
-		assert(NbVertexOnBThVertex == NbVerticesOnGeomVertex);
-		// new stuff FH with curve
-		//  find the begin of the curve in BTh
-		  {
-			Gh.UnMarkEdges();	
-			int bfind=0;
-			/*
-				cout << " nb curves = " << Gh.NbOfCurves << endl;
-				for(int i=0;i<Gh.NbOfCurves ;i++)
-				{
-				cout << " Curve " << i << " begin e=" << Gh.Number(Gh.curves[i].be) << " k=" << Gh.curves[i].kb 
-				<< "  end e= " << Gh.Number(Gh.curves[i].ee) << " k=" << Gh.curves[i].ke << endl;
-				}*/
-			for (int i=0;i<Gh.NbOfCurves;i++)
-			  {
-				bcurve[i]=-1; 
-			  }
-
-			for (int iedge=0;iedge<BTh.nbe;iedge++) 
-			  {      
-				Edge & ei = BTh.edges[iedge];
-				for(int je=0;je<2;je++) // for the 2 extremites
-				 if (!ei.on->Mark() && ei[je].on->IsRequiredVertex() )
-					{
-					 // a begin of curve 
-					 int nc = ei.on->CurveNumber;
-
-					 //cout << "curve " <<  nc << " v " << Gh.Number((GeometricalVertex *) *ei[je].on) << " "
-					 //     << " e "  << " " << Gh.Number(ei.on) << " vc " << Gh.Number((*Gh.curves[nc].be)[Gh.curves[nc].kb]) << endl;
-					 if(
-								 ei.on==Gh.curves[nc].be    && 
-								 (GeometricalVertex *) *ei[je].on == &(*Gh.curves[nc].be)[Gh.curves[nc].kb] //  same extremity 
-						)     
-						{ 
-						 // cout << " find " << endl;
-						 bcurve[nc]=iedge*2+je;
-						 bfind++;	
-						}      
-					}
-			  } 
-			assert( bfind==Gh.NbOfCurves);
-		  }          
-		// method in 2 + 1 step 
-		//  0.0) compute the length and the number of vertex to do allocation
-		//  1.0)  recompute the length
-		//  1.1)   compute the  vertex 
-		Int4 nbex=0,NbVerticesOnGeomEdgex=0;
-		for (int step=0; step <2;step++)
-		  {
-			Int4 NbOfNewPoints=0;
-			Int4 NbOfNewEdge=0;
-			Int4 iedge;
-			Gh.UnMarkEdges();	
-			/*   add Curve loop  FH    
-			// find a starting back groud edges to walk 
-			for (iedge=0;iedge<BTh.nbe;iedge++) {      
-			Edge & ei = BTh.edges[iedge];
-			for(int jedge=0;jedge<2;jedge++) // for the 2 extremites
-			if (!ei.on->Mark() && ei[jedge].on->IsRequiredVertex() )
-			{
-			*/  
-			// new code FH 2004 
-			Real8 L=0;
-			for (int icurve=0;icurve<Gh.NbOfCurves;icurve++)
-			  { 
-				iedge=bcurve[icurve]/2;
-				int jedge=bcurve[icurve]%2;
-				if( ! Gh.curves[icurve].master) continue; // we skip all equi curve
-				Edge & ei = BTh.edges[iedge];
-				// warning: ei.on->Mark() can be change in
-				// loop for(jedge=0;jedge<2;jedge++) 
-				// new curve  
-				// good the find a starting edge 
-				Real8 Lstep=0,Lcurve=0;// step between two points   (phase==1) 
-				Int4 NbCreatePointOnCurve=0;// Nb of new points on curve     (phase==1) 
-
-
-				//    cout.precision(16);
-				for(int phase=0;phase<=step;phase++) 
-				  {
-
-					for(Curve * curve= Gh.curves+icurve;curve;curve= curve->next)
-					  {
-
-						int icurveequi= Gh.Number(curve);
-
-						if( phase == 0 &&  icurveequi != icurve)  continue;
-
-						int k0=jedge,k1;
-						Edge * pe=  BTh.edges+iedge;
-						//GeometricalEdge *ong = ei.on;
-						int iedgeequi=bcurve[icurveequi]/2;
-						int jedgeequi=bcurve[icurveequi]%2;
-
-						int k0equi=jedgeequi,k1equi;		  
-						Edge * peequi= BTh.edges+iedgeequi;
-						GeometricalEdge *ongequi = peequi->on;
-
-						Real8 sNew=Lstep;// abcisse of the new points (phase==1) 
-						L=0;// length of the curve
-						Int4 i=0;// index of new points on the curve
-						register GeometricalVertex * GA0 = *(*peequi)[k0equi].on;
-						Vertex *A0;
-						A0 = GA0->to;  // the vertex in new mesh
-						Vertex *A1;
-						VertexOnGeom *GA1;
-						Edge * PreviousNewEdge = 0;
-						//  cout << "  --------------New Curve phase " << phase 
-						//       << "---------- A0=" << *A0 << ei[k0]  <<endl;
-						assert (A0-vertices>=0 && A0-vertices <nbv);
-						if(ongequi->Required() ) 
-						  {
-							GeometricalVertex *GA1 = *(*peequi)[1-k0equi].on;
-							A1 = GA1->to;  //
-						  }       
-						else 
-						 for(;;) 
-							{
-							 //   assert(pe && BTh.Number(pe)>=0 && BTh.Number(pe)<=BTh.nbe);
-							 Edge &ee=*pe; 
-							 Edge &eeequi=*peequi; 
-							 k1 = 1-k0; // next vertex of the edge 
-							 k1equi= 1 - k0equi;
-
-							 assert(pe  && ee.on);
-							 ee.on->SetMark();
-							 Vertex & v0=ee[0], & v1=ee[1];
-							 R2 AB= (R2) v1 - (R2) v0;
-							 Real8 L0=L,LAB;
-							 LAB =  LengthInterpole(v0.m,v1.m,AB);
-							 L+= LAB;    
-							 if (phase) {// computation of the new points
-								 while ((i!=NbCreatePointOnCurve) && sNew <= L) { 
-									 //    cout  << " L0= " << L0 << " L " << L << " sN=" 
-									 //         << sNew << " LAB=" << LAB << " NBPC =" <<NbCreatePointOnCurve<< " i " << i  << endl;
-									 assert (sNew >= L0);
-									 assert(LAB);
-
-
-									 assert(vertices && nbv<nbvx);
-									 assert(edges && nbe < nbex);
-									 assert(VerticesOnGeomEdge && NbVerticesOnGeomEdge < NbVerticesOnGeomEdgex);
-									 // new vertex on edge
-									 A1=vertices+nbv++;
-									 GA1=VerticesOnGeomEdge+NbVerticesOnGeomEdge;
-									 Edge *e = edges + nbe++;
-									 Real8 se= (sNew-L0)/LAB;
-									 assert(se>=0 && se < 1.000000001);
-									 se =  abscisseInterpole(v0.m,v1.m,AB,se,1);
-									 assert(se>=0 && se <= 1);
-									 //((k1==1) != (k1==k1equi))
-									 se = k1 ? se : 1. - se;
-									 se = k1==k1equi ? se : 1. - se;
-									 VertexOnBThEdge[NbVerticesOnGeomEdge++] = VertexOnEdge(A1,&eeequi,se); // save 
-									 ongequi = Gh.ProjectOnCurve(eeequi,se,*A1,*GA1); 
-									 A1->ReferenceNumber = eeequi.ref;
-									 A1->DirOfSearch =NoDirOfSearch;
-									 //cout << icurveequi << " " << i << " " <<  *A1 << endl;
-									 e->on = ongequi;
-									 e->v[0]=  A0;
-									 e->v[1]=  A1;
-									 if(verbosity>99)
-									  cout << i << "+ New P "<< nbv-1 << " "  <<sNew<< " L0=" << L0 
-										 << " AB=" << LAB << " s=" << (sNew-L0)/LAB << " se= "  
-										 << se <<" B edge " << BTh.Number(ee) << " signe = " << k1 <<" " << A1->r <<endl;
-
-									 e->ref = eeequi.ref;
-									 e->adj[0]=PreviousNewEdge;
-
-									 if (PreviousNewEdge)
-									  PreviousNewEdge->adj[1] =  e;
-									 PreviousNewEdge = e;
-									 A0=A1;
-									 sNew += Lstep;
-									 //   cout << " sNew = " << sNew << " L = " << L 
-									 //        << "  ------" <<NbCreatePointOnCurve << " " << i <<  endl;
-									 if (++i== NbCreatePointOnCurve) break;
-								 }
-
-							 }               
-							 assert(ee.on->CurveNumber==ei.on->CurveNumber);
-							 if(verbosity>98) cout <<  BTh.Number(ee) << " " << " on=" << *ee[k1].on << " "<< ee[k1].on->IsRequiredVertex() <<  endl;
-							 if ( ee[k1].on->IsRequiredVertex()) {
-								 assert(eeequi[k1equi].on->IsRequiredVertex());
-								 register GeometricalVertex * GA1 = *eeequi[k1equi].on;
-								 A1=GA1->to;// the vertex in new mesh
-								 assert (A1-vertices>=0 && A1-vertices <nbv);
-								 break;}
-								 if (!ee.adj[k1])
-									{cerr << "Error adj edge " << BTh.Number(ee) << ", nbe = "  << nbe 
-									 << " Gh.vertices " << Gh.vertices 
-										<< " k1 = " << k1 << " on=" << *ee[k1].on << endl;
-									 cerr << ee[k1].on->gv-Gh.vertices << endl;
-									}
-								 pe = ee.adj[k1]; // next edge
-								 k0 = pe->Intersection(ee); 
-								 peequi= eeequi.adj[k1equi];  // next edge
-								 k0equi=peequi->Intersection(eeequi);            
-							}// for(;;) end of the curve
-
-
-						if (phase) // construction of the last edge
-						  {
-							Edge *e = edges + nbe++;
-							if (verbosity>10) 
-							 cout << " Fin curve A1" << *A1 << " " << icurve << " <=> " << icurveequi <<"-----" <<
-								NbCreatePointOnCurve << " == " <<i<<endl;
-							e->on  = ongequi;
-							e->v[0]=  A0;
-							e->v[1]=	A1;
-							e->ref = peequi->ref;
-							e->adj[0]=PreviousNewEdge;
-							e->adj[1]=0;
-							if (PreviousNewEdge)
-							 PreviousNewEdge->adj[1] =  e;
-							PreviousNewEdge = e;
-
-							assert(i==NbCreatePointOnCurve);
-
-						  }
-					  } //  end loop on equi curve 
-
-					if (!phase)  { // 
-						Int4 NbSegOnCurve = Max((Int4)(L+0.5),(Int4) 1);// nb of seg
-						Lstep = L/NbSegOnCurve; 
-						Lcurve = L;
-						NbCreatePointOnCurve = NbSegOnCurve-1;
-
-						for(Curve * curve= Gh.curves+icurve;curve;curve= curve->next)
-						  {
-							NbOfNewEdge += NbSegOnCurve;
-							NbOfNewPoints += NbCreatePointOnCurve;
-						  }
-						if(verbosity>5)
-						 cout << icurve << " NbSegOnCurve = " <<  NbSegOnCurve << " Lstep=" 
-							<< Lstep <<" " << NbOfNewPoints<< " NBPC= " << NbCreatePointOnCurve <<endl;
-						// do'nt 
-						//  if(NbCreatePointOnCurve<1) break;
-					}
-				  }//for(phase;;)
-				/*  modif FH add Curve class  		  
-					 }}//for (iedge=0;iedge<BTh.nbe;iedge++) 
-					 */
-				// new code Curve class  	
-		  } //  end of curve loop 
-		// end new code	    
-		// do the allocation
-		if(step==0) 
-		  {
-			//if(!NbOfNewPoints) break;// nothing ????? bug 
-			if(nbv+NbOfNewPoints > nbvx) 
-			  {
-				cerr << " Too much vertices on geometry " << nbv+NbOfNewPoints  << " >= " << nbvx << endl;
-				MeshError(3,this);
-			  }
-			//cout << " NbOfNewEdge" << NbOfNewEdge << " NbOfNewPoints " << NbOfNewPoints << endl;
-			edges = new Edge[NbOfNewEdge];
-			nbex = NbOfNewEdge;
-			if(NbOfNewPoints) { // 
-				VerticesOnGeomEdge = new VertexOnGeom[NbOfNewPoints];
-				NbVertexOnBThEdge =NbOfNewPoints;
-				VertexOnBThEdge = new  VertexOnEdge[NbOfNewPoints];
-				NbVerticesOnGeomEdgex = NbOfNewPoints; }
-				NbOfNewPoints =0;
-				NbOfNewEdge = 0;
-		  }
-		  } // for(step;;)
-		assert(nbe);
-
-		delete [] bcurve;
-
-
-		Insert();
-		ForceBoundary();
-		FindSubDomain();
-
-		NewPoints(BTh,KeepBackVertices) ;
-		CurrentTh = 0;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::GeomToTriangles0{{{1*/
-	void Triangles::GeomToTriangles0(Int4 inbvx) {
-		Gh.NbRef++;// add a ref to GH
-
-
-		Int4 i,NbOfCurves=0,NbNewPoints,NbEdgeCurve;
-		Real8 lcurve, lstep,s;
-
-		R2 AB;
-		GeometricalVertex *a,*b;
-		Vertex *va,*vb;
-		GeometricalEdge * e;
-		PreInit(inbvx);
-		int  background = &BTh != this;
-		//  int  SameGeom = background && (&BTh.Gh == &Gh);
-		nbv = 0;
-		NbVerticesOnGeomVertex=0;
-		NbVerticesOnGeomEdge=0;
-		for (i=0;i<Gh.nbv;i++)
-		 if (Gh[i].Required() && Gh[i].IsThe() ) NbVerticesOnGeomVertex++;
-		VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];  
-		//
-		if( NbVerticesOnGeomVertex >= nbvx) 
-		  {
-			cerr << " Too much vertices on geometry " << NbVerticesOnGeomVertex << " >= " << nbvx << endl;
-			MeshError(1,this);
-		  }
-		for (i=0;i<Gh.nbv;i++)
-		 if (Gh[i].Required()&& Gh[i].IsThe()  ) {//Gh  vertices Required
-			 if (nbv < nbvx)
-			  vertices[nbv] = Gh[i];
-			 Gh[i].to = vertices + nbv;// save Geom -> Th
-			 VerticesOnGeomVertex[nbv]= VertexOnGeom(*Gh[i].to,Gh[i]);
-			 //  cout << "--------- "  <<Number(Gh[i].to) << " " << Gh[i].to << " " << i << endl;
-			 nbv++;
-		 }
-		//  assert( Gh.nbv < nbvx);
-
-		// Method in 2 step:  0 and 1 
-		// 1) compute de nb of edge 
-		// 2) construct the edge    
-		// generation of the curves
-		assert(! edges);
-		// 2 step 
-		// --step=0 to compute the number of edges + alloc at end
-		// --step=1 to construct the edges
-		for (int step=0;step<2;step++) 
-		  {//  for (int step=0;step<2;step++) 
-			Int4 nbex = 0;
-			nbe = 0;
-			Int4 NbVerticesOnGeomEdge0=NbVerticesOnGeomEdge;
-			//  cout <<  "  -------------- step =" << step << endl;
-			Gh.UnMarkEdges();	
-			NbOfCurves = 0;
-			for (i=0;i<Gh.nbe;i++) {
-				GeometricalEdge & ei = Gh.edges[i];   
-				if (!ei.Dup()) // a good curve (not dup )
-				 for(int j=0;j<2;j++) 
-				  if (!ei.Mark() && ei[j].Required()) { 
-					  // warning ei.Mark() can be change in loop for(j=0;j<2;j++) 
-					  //  cout << " New curve = " << NbOfCurves << endl;
-					  Int4 nbvend  =0;
-
-					  Edge * PreviousNewEdge=0;
-
-					  lstep = -1;//to do not create points
-					  if(ei.Required())
-						 {
-						  if (j==0)
-							if(step==0)
-							 nbe++;
-							else
-							  { 
-								e = & ei;
-								a=ei(0)->The();
-								b=ei(1)->The();
-								assert(edges);
-								edges[nbe].v[0]=a->to;
-								edges[nbe].v[1]=b->to;;
-								edges[nbe].ref = e->ref;
-								edges[nbe].on = e;
-								edges[nbe].adj[0] = 0;
-								edges[nbe].adj[1] = 0;
-								nbe++;}
-						 }
-					  else 
-						 { // on curve ------
-						  for ( int kstep=0;kstep<= step;kstep++)
-							 { // begin  for ( int kstep=0;kstep<= step;kstep++)
-							  // if 2nd step where 2 step
-							  // -- 1 compute le length of the curve
-							  // -- create the points and edge
-							  PreviousNewEdge=0;
-							  NbNewPoints=0;
-							  NbEdgeCurve=0;
-							  assert(nbvend < nbvx); 
-							  lcurve =0;
-							  s = lstep;
-							  int k=j;
-							  e = & ei;
-							  a=ei(k)->The();
-							  va = a->to;
-							  e->SetMark();
-							  //  cout << " New curve " ;
-
-							  // if SameGeo  We have go in the background geometry 
-							  // to find the discretisation of the curve
-
-							  for(;;) 
-								 { 
-								  k = 1-k;
-								  b= (*e)(k)->The();
-								  AB = b->r - a->r;
-								  Metric MA = background ? BTh.MetricAt(a->r) :a->m ;
-								  Metric MB =  background ? BTh.MetricAt(b->r) :b->m ;
-								  Real8 ledge = (MA(AB) + MB(AB))/2;
-								  // 
-								  const int MaxSubEdge = 10;
-								  int NbSubEdge = 1;
-								  Real8 lSubEdge[MaxSubEdge];
-								  R2 A,B;
-								  if (ledge < 1.5) 
-									lSubEdge[0] = ledge;
-								  else {
-									  NbSubEdge = Min( MaxSubEdge, (int) (ledge +0.5));
-									  A= a->r;
-									  Metric MAs =MA,MBs;
-									  // cout << " lSubEdge old=" << ledge 
-									  //      << " new " << A << MA << endl;
-									  ledge = 0; 
-									  Real8 x =0, xstep= 1. /  NbSubEdge;
-									  for (int kk=0; kk < NbSubEdge; kk++,A=B,MAs=MBs ) {
-										  x += xstep;
-										  B =  e->F(k ? x : 1-x);
-										  MBs= background ? BTh.MetricAt(B) :Metric(1-x, MA, x ,MB);
-										  AB = A-B;
-										  lSubEdge[kk]= (ledge += (MAs(AB)+MBs(AB))/2);
-										  // cout << "     " << lSubEdge[kk] << " x " << x  
-										  //      << " " << A << B << MA << MB<< endl ;
-									  }
-									  //  cout << endl;
-								  }
-
-								  Real8 lcurveb = lcurve+ ledge ;
-								  while (lcurve<=s && s <= lcurveb && nbv < nbvend)
-									 {
-									  // New points
-
-									  // Real8 aa=(lcurveb-s)/ledge;
-									  // Real8 bb=(s-lcurve)/ledge;
-
-									  Real8 ss = s-lcurve;
-									  // 1) find the SubEdge containing ss by dichotomie
-									  int kk0=-1,kk1=NbSubEdge-1,kkk;
-									  Real8 ll0=0,ll1=ledge,llk;
-									  while (kk1-kk0>1)
-										 {
-										  if (ss < (llk=lSubEdge[kkk=(kk0+kk1)/2]))
-											kk1=kkk,ll1=llk;
-										  else
-											kk0=kkk,ll0=llk;}
-										  assert(kk1 != kk0);
-
-										  Real8 sbb = (ss-ll0  )/(ll1-ll0);
-										  Real8 bb = (kk1+sbb)/NbSubEdge, aa=1-bb;
-
-										  // new vertex on edge
-										  vb = &vertices[nbv++];
-										  vb->m = Metric(aa,a->m,bb,b->m);
-										  vb->ReferenceNumber = e->ref;
-										  vb->DirOfSearch =NoDirOfSearch;
-										  Real8 abcisse = k ? bb : aa;
-										  vb->r =  e->F( abcisse );
-										  VerticesOnGeomEdge[NbVerticesOnGeomEdge++]= VertexOnGeom(*vb,*e,abcisse);        
-
-										  // to take in account the sens of the edge
-
-										  s += lstep;
-										  edges[nbe].v[0]=va;
-										  edges[nbe].v[1]=vb;
-										  edges[nbe].ref = e->ref;
-										  edges[nbe].on = e;
-										  edges[nbe].adj[0] = PreviousNewEdge;
-										  if(PreviousNewEdge)
-											PreviousNewEdge->adj[1] = &edges[nbe];
-										  PreviousNewEdge = edges + nbe;
-										  nbe++;
-										  va = vb;
-									 }
-								  lcurve = lcurveb;
-								  e->SetMark();
-								  // cout << e-Gh.edges << ", " << k << " " 
-								  //      <<(*e)[k].r <<" " <<(*e)[1-k].r <<" " 
-								  //      << lcurve<< ";; " ;                          
-								  a=b;
-								  if (b->Required() ) break;
-								  int kprev=k;
-								  k = e->SensAdj[kprev];// next vertices
-								  e = e->Adj[kprev];
-								  assert(e);
-								 }// for(;;)
-							  vb = b->to;
-							  //            cout << endl;
-							  NbEdgeCurve = Max((Int4) (lcurve +0.5), (Int4) 1);
-							  NbNewPoints = NbEdgeCurve-1;
-							  if(!kstep)
-								 { NbVerticesOnGeomEdge0 += NbNewPoints;
-								  NbOfCurves++;}
-
-								  nbvend=nbv+NbNewPoints; 
-
-								  lstep = lcurve / NbEdgeCurve;
-								  //   cout <<"lstep " << lstep << " lcurve " 
-								  //    << lcurve << " NbEdgeCurve " << NbEdgeCurve << " " <<NbVerticesOnGeomEdge0<<" " <<NbVerticesOnGeomEdge<<" step =" <<step<<  endl;
-							 } 
-						  // end of curve --
-						  if (edges) { // last edges of the curves 
-							  edges[nbe].v[0]=va;
-							  edges[nbe].v[1]=vb;
-							  edges[nbe].ref = e->ref;
-							  edges[nbe].on = e;
-							  edges[nbe].adj[0] = PreviousNewEdge;
-							  edges[nbe].adj[1] = 0;
-							  if(PreviousNewEdge)
-								PreviousNewEdge->adj[1] = & edges[nbe];
-
-							  nbe++;}
-						  else
-							nbe += NbEdgeCurve;
-						 } // end on  curve ---
-				  } // if (edges[i][j].Corner())  
-			} // for (i=0;i<nbe;i++)
-			if(!step) {
-				// cout << "edges " << edges << " VerticesOnGeomEdge " <<VerticesOnGeomEdge << endl;
-				assert(!edges);
-				assert(!VerticesOnGeomEdge);
-				edges = new Edge[nbex=nbe];
-				if(NbVerticesOnGeomEdge0)
-				 VerticesOnGeomEdge = new VertexOnGeom[NbVerticesOnGeomEdge0];
-				assert(edges);
-				assert(VerticesOnGeomEdge || NbVerticesOnGeomEdge0 ==0);
-				// do the vertex on a geometrical vertex
-				NbVerticesOnGeomEdge0 = NbVerticesOnGeomEdge;       
-			}
-			else 
-			 assert(NbVerticesOnGeomEdge == NbVerticesOnGeomEdge0);
-			//     cout << " Nb of Curves = " << NbOfCurves << "nbe = " << nbe 
-			//	  << "== " << nbex << "  nbv = " << nbv <<  endl;
-			assert(nbex=nbe);
-		  } // for (step=0;step<2;step++)
-
-		Insert();
-		ForceBoundary();
-		FindSubDomain();
-
-		// NewPointsOld(*this) ;
-		NewPoints(*this,0) ;
-		CurrentTh = 0;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::MakeGeometricalEdgeToEdge{{{1*/
-	Edge** Triangles::MakeGeometricalEdgeToEdge() {
-		assert(Gh.nbe);
-		Edge **e= new (Edge* [Gh.nbe]);
-
-		Int4 i;
-		for ( i=0;i<Gh.nbe ; i++)
-		 e[i]=NULL;
-		for ( i=0;i<nbe ; i++) 
-		  { 
-			Edge * ei = edges+i;
-			GeometricalEdge *on = ei->on; 
-			e[Gh.Number(on)] = ei;    
-		  }
-		for ( i=0;i<nbe ; i++) 
-		 for (int ii=0;ii<2;ii++) { 
-			 Edge * ei = edges+i;
-			 GeometricalEdge *on = ei->on;
-			 int j= ii;
-			 while (!(*on)[j].Required()) { 
-				 //	cout << i << " " << ii << " j= " << j << " curve = " 
-				 //           <<  on->CurveNumber << "  " << Gh.Number(on) << " on " << j 
-				 //   << " s0 " << Gh.Number( (*on)[0]) << " s1  " << Gh.Number( (*on)[1]) 
-				 //   << " ->  " ;
-				 Adj(on,j); // next geom edge
-				 j=1-j;
-				 //       cout << Gh.Number(on) << "  " << j  << " e[ON] =  " <<  e[Gh.Number(on)] 
-				 //    << " s0 " << Gh.Number( (*on)[0]) << " s1  " << Gh.Number( (*on)[1]) << endl; 
-				 if (e[Gh.Number(on)])  break; // optimisation     
-				 e[Gh.Number(on)] = ei; 
-			 }
-		 }
-
-		int kk=0;
-		for ( i=0;i<Gh.nbe ; i++)
-		 if (!e[i]) 
-		  if(kk++<10) {
-			  cerr << " Bug -- the geometrical edge " << i << " is on no edge curve = " << Gh.edges[i].CurveNumber 
-				 << " s0 " << Gh.Number( Gh.edges[i][0]) << " s1  " << Gh.Number( Gh.edges[i][1]) << endl; 
-			  //	 assert( e[i]);
-		  }
-		if(kk) MeshError(997,this);
-
-		return e;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::SetIntCoor{{{1*/
-	void Triangles::SetIntCoor(const char * strfrom) {
-		pmin =  vertices[0].r;
-		pmax =  vertices[0].r;
-
-		// recherche des extrema des vertices pmin,pmax
-		Int4 i;
-		for (i=0;i<nbv;i++) {
-			pmin.x = Min(pmin.x,vertices[i].r.x);
-			pmin.y = Min(pmin.y,vertices[i].r.y);
-			pmax.x = Max(pmax.x,vertices[i].r.x);
-			pmax.y = Max(pmax.y,vertices[i].r.y);
-		}
-		R2 DD = (pmax-pmin)*0.05;
-		pmin = pmin-DD;
-		pmax = pmax+DD; 
-		coefIcoor= (MaxICoor)/(Max(pmax.x-pmin.x,pmax.y-pmin.y));
-		assert(coefIcoor >0);
-
-		// generation of integer coord  
-		for (i=0;i<nbv;i++) {
-			vertices[i].i = toI2(vertices[i].r);    
-		}
-
-		// computation of the det 
-		int Nberr=0;
-		for (i=0;i<nbt;i++)
-		  {
-			Vertex & v0 = triangles[i][0];
-			Vertex & v1 = triangles[i][1];
-			Vertex & v2 = triangles[i][2];
-			if ( &v0 && &v1 &&  &v2 ) // a good triangles;
-			  {
-				triangles[i].det= det(v0,v1,v2);
-				if (triangles[i].det <=0 && Nberr++ <10)
-				  {
-					if(Nberr==1)
-					 if (strfrom)
-					  cerr << "+++ Fatal Error " << strfrom << "(SetInCoor)  Error :  area of Triangle < 0 " << endl; 
-					 else 
-					  cerr << "+++  Fatal Error Triangle (in SetInCoor) area of Triangle < 0" << endl;
-					cerr << " Triangle " << i << "  det  (I2) = " << triangles[i].det ;
-					cerr << " (R2) " << Det(v1.r-v0.r,v2.r-v0.r);
-					cerr << "; The 3  vertices " << endl;
-					cerr << Number(v0) << " "  << Number(v1) << " " 
-					  << Number(v2) << " : " ;
-					cerr << v0.r << v1.r << v2.r << " ; ";
-					cerr << v0.i << v1.i << v2.i << endl;
-				  }
-			  }
-			else
-			 triangles[i].det= -1; // Null triangle; 
-		  }
-		if (Nberr) MeshError(899,this);
-
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::FillHoleInMesh{{{1*/
-	void Triangles::FillHoleInMesh() {
-
-		Triangles* OldCurrentTh =CurrentTh;
-		CurrentTh=this;
-
-		int verbosity=0;
-
-		// generation of the integer coordinate
-		  {
-
-			// find extrema coordinates of vertices pmin,pmax
-			Int4 i;
-			if(verbosity>2) printf("      Filling holes in mesh of %i vertices\n",nbv); 
-
-			//initialize ordre
-			assert(ordre);
-			for (i=0;i<nbv;i++) ordre[i]=0;
-
-			NbSubDomains =0;
-
-			/* generation of the adjacence of the triangles*/
-
-			SetOfEdges4* edge4= new SetOfEdges4(nbt*3,nbv);
-
-			//initialize st
-			Int4* st = new Int4[nbt*3];
-			for (i=0;i<nbt*3;i++) st[i]=-1;
-
-			//check number of edges
-			Int4 kk =0;
-			for (i=0;i<nbe;i++){
-				kk=kk+(i == edge4->addtrie(Number(edges[i][0]),Number(edges[i][1])));
-			}
-			if (kk != nbe) { 
-				throw ErrorException(__FUNCT__,exprintf("Some Double edge in the mesh, the number is %i",kk-nbe));
-			}
-
-			//
-			for (i=0;i<nbt;i++){
-				for (int j=0;j<3;j++) {
-					Int4 k =edge4->addtrie(Number(triangles[i][VerticesOfTriangularEdge[j][0]]),
-								Number(triangles[i][VerticesOfTriangularEdge[j][1]]));
-					Int4 invisible = triangles[i].Hidden(j);
-					if(st[k]==-1){
-						st[k]=3*i+j;
-					}
-					else if(st[k]>=0) {
-						assert( ! triangles[i].TriangleAdj(j) && !triangles[st[k] / 3].TriangleAdj((int) (st[k]%3)));
-
-						triangles[i].SetAdj2(j,triangles + st[k] / 3,(int) (st[k]%3));
-						if (invisible)  triangles[i].SetHidden(j);
-						if (k<nbe) {
-							triangles[i].SetLocked(j);
-						}
-						st[k]=-2-st[k]; 
-					}
-					else {
-						throw ErrorException(__FUNCT__,exprintf("The edge (%i , %i) belongs to more than 2 triangles",
-										Number(triangles[i][VerticesOfTriangularEdge[j][0]]),Number(triangles[i][VerticesOfTriangularEdge[j][1]])));
-					}
-				}
-			}
-			if(verbosity>5) {
-				printf("         info on Mesh %s:\n",name);
-				printf("            - number of vertices    = %i \n",nbv); 
-				printf("            - number of triangles   = %i \n",nbt); 
-				printf("            - number of given edges = %i \n",nbe); 
-				printf("            - number of all edges   = %i \n"  ,edge4->nb()); 
-				printf("            - Euler number 1 - nb of holes = %i \n"  ,nbt-edge4->nb()+nbv); 
-			}
-
-			// check the consistant of edge[].adj and the geometrical required  vertex
-			Int4 k=0;
-			for (i=0;i<edge4->nb();i++){
-				if (st[i] >=0){ // edge alone 
-					if (i < nbe) {
-						Int4 i0=edge4->i(i);
-						ordre[i0] = vertices+i0;
-						Int4 i1=edge4->j(i);
-						ordre[i1] = vertices+i1;
-					}
-					else {
-						k=k+1;
-						if (k <20) {
-							throw ErrorException(__FUNCT__,exprintf("Lost boundary edges %i : %i %i",i,edge4->i(i),edge4->j(i)));
-						}
-					}
-				}
-			}
-			if(k != 0) {
-				throw ErrorException(__FUNCT__,exprintf("%i boundary edges  are not defined as edges",k));
-			}
-
-			/* mesh generation with boundary points*/
-			Int4 nbvb = 0;
-			for (i=0;i<nbv;i++){ 
-				vertices[i].t=0;
-				vertices[i].vint=0;
-				if (ordre[i]){ 
-					ordre[nbvb++] = ordre[i];
-				}
-			}
-
-			Triangle* savetriangles= triangles;
-			Int4 savenbt=nbt;
-			Int4 savenbtx=nbtx;
-			SubDomain * savesubdomains = subdomains;
-			subdomains = 0;
-
-			Int4  Nbtriafillhole = 2*nbvb;
-			Triangle* triafillhole =new Triangle[Nbtriafillhole];
-			triangles =  triafillhole;
-
-			nbt=2;
-			nbtx= Nbtriafillhole;
-
-			for (i=2 ; det( ordre[0]->i, ordre[1]->i, ordre[i]->i ) == 0;) 
-			 if  ( ++i >= nbvb) {
-				 cerr << "FillHoleInMesh: All the vertices are aline " << nbvb << endl;
-				 MeshError(998,this); }
-				 Exchange( ordre[2], ordre[i]);
-
-				 Vertex *  v0=ordre[0], *v1=ordre[1];
-
-
-				 triangles[0](0) = 0; // sommet pour infini 
-				 triangles[0](1) = v0;
-				 triangles[0](2) = v1;
-
-				 triangles[1](0) = 0;// sommet pour infini 
-				 triangles[1](2) = v0;
-				 triangles[1](1) = v1;
-				 const int e0 = OppositeEdge[0];
-				 const int e1 = NextEdge[e0];
-				 const int e2 = PreviousEdge[e0];
-				 triangles[0].SetAdj2(e0, &triangles[1] ,e0);
-				 triangles[0].SetAdj2(e1, &triangles[1] ,e2);
-				 triangles[0].SetAdj2(e2, &triangles[1] ,e1);
-
-				 triangles[0].det = -1;  // faux triangles
-				 triangles[1].det = -1;  // faux triangles
-
-				 triangles[0].SetTriangleContainingTheVertex();
-				 triangles[1].SetTriangleContainingTheVertex();
-
-				 triangles[0].link=&triangles[1];
-				 triangles[1].link=&triangles[0];
-
-				 if (!quadtree ) 
-				  delete  quadtree; // ->ReInitialise();
-
-				 quadtree = new QuadTree(this,0);
-				 quadtree->Add(*v0);
-				 quadtree->Add(*v1);
-
-				 // We add the vertices one by one
-				 Int4 NbSwap=0;
-				 for (Int4 icount=2; icount<nbvb; icount++) {
-					 Vertex *vi  = ordre[icount];
-					 //	  cout << " Add vertex " <<  Number(vi) << endl;
-					 Icoor2 dete[3];
-					 Triangle *tcvi = FindTriangleContening(vi->i,dete);
-					 quadtree->Add(*vi); 
-					 Add(*vi,tcvi,dete);
-					 NbSwap += vi->Optim(1,1);
-				 }
-
-				 // inforce the boundary 
-				 TriangleAdjacent ta(0,0);
-				 Int4 nbloss = 0,knbe=0;
-				 for ( i = 0; i < nbe; i++){
-					 if (st[i] >=0){  // edge alone => on border ...  FH oct 2009
-						 Vertex & a=edges[i][0], & b =    edges[i][1];
-						 if (a.t && b.t) // le bug est la si maillage avec des bod non raffine 1.
-							{
-							 knbe++;
-							 if (ForceEdge(a,b,ta)<0)
-							  nbloss++;
-							}
-					 }
-				 }
-				 if(nbloss) {
-					 cerr << " we loss some  " << nbloss << " "  << " edges other " << knbe << endl;
-					 MeshError(1100,this);
-				 }
-
-				 FindSubDomain(1);
-				 // remove all the hole 
-				 // remove all the good sub domain
-				 Int4 krm =0;
-				 for (i=0;i<nbt;i++){
-					 if (triangles[i].link){ // remove triangles
-						 krm++;
-						 for (int j=0;j<3;j++)
-							{
-							 TriangleAdjacent ta =  triangles[i].Adj(j);
-							 Triangle & tta = * (Triangle *) ta;
-							 if(! tta.link) // edge between remove and not remove 
-								{ // change the link of ta;
-								 int ja = ta;
-								 Vertex *v0= ta.EdgeVertex(0);
-								 Vertex *v1= ta.EdgeVertex(1);
-								 Int4 k =edge4->addtrie(v0?Number(v0):nbv,v1? Number(v1):nbv);
-								 assert(st[k] >=0); 
-								 tta.SetAdj2(ja,savetriangles + st[k] / 3,(int) (st[k]%3));
-								 ta.SetLock();
-								 st[k]=-2-st[k]; 
-								}
-							}
-					 }
-				 }
-				 Int4 NbTfillHoll =0;
-				 for (i=0;i<nbt;i++){
-					 if (triangles[i].link) {
-						 triangles[i]=Triangle((Vertex *) NULL,(Vertex *) NULL,(Vertex *) NULL);
-						 triangles[i].color=-1;
-					 }
-					 else
-						{
-						 triangles[i].color= savenbt+ NbTfillHoll++;
-						}
-				 }
-				 // cout <<      savenbt+NbTfillHoll << " " <<  savenbtx  << endl;
-				 assert(savenbt+NbTfillHoll <= savenbtx );
-				 // copy of the outside triangles in saveTriangles 
-				 for (i=0;i<nbt;i++){
-					 if(triangles[i].color>=0) {
-						 savetriangles[savenbt]=triangles[i];
-						 savetriangles[savenbt].link=0;
-						 savenbt++;
-					 }
-				 }
-				 // gestion of the adj
-				 k =0;
-				 Triangle * tmax = triangles + nbt;
-				 for (i=0;i<savenbt;i++)  
-					{ 
-					 Triangle & ti = savetriangles[i];
-					 for (int j=0;j<3;j++)
-						{
-						 Triangle * ta = ti.TriangleAdj(j);
-						 int aa = ti.NuEdgeTriangleAdj(j);
-						 int lck = ti.Locked(j);
-						 if (!ta) k++; // bug 
-						 else if ( ta >= triangles && ta < tmax) 
-							{
-							 ta= savetriangles + ta->color;
-							 ti.SetAdj2(j,ta,aa);
-							 if(lck) ti.SetLocked(j);
-							}
-						}
-					}
-				 //	 OutSidesTriangles = triangles;
-				 //	Int4 NbOutSidesTriangles = nbt;
-
-				 // restore triangles;
-				 nbt=savenbt;
-				 nbtx=savenbtx;
-				 delete [] triangles;
-				 delete [] subdomains;
-				 triangles = savetriangles;
-				 subdomains = savesubdomains;
-				 //	 cout <<  triangles << " <> " << OutSidesTriangles << endl; 
-				 /*	 k=0;
-						 for (i=0;i<nbt;i++)
-						 for (int j=0;j<3;j++)
-						 if (!triangles[i].TriangleAdj(j))
-						 k++;
-						 */
-				 if (k) {
-					 cerr << "Error Nb of triangles edge alone = " << k << endl;
-					 MeshError(9997,this);
-				 }
-				 FindSubDomain();
-				 // cout << " NbTOld = " << NbTold << " ==  " << nbt - NbOutT << " " << nbt << endl;
-
-				 delete edge4;
-				 delete [] st;
-				 for (i=0;i<nbv;i++)
-				  quadtree->Add(vertices[i]);
-
-				 SetVertexFieldOn();
-
-				 for (i=0;i<nbe;i++)
-				  if(edges[i].on) 
-					for(int j=0;j<2;j++)
-					 if (!edges[i].adj[j])
-					  if(!edges[i][j].on->IsRequiredVertex()) {
-						  cerr << " Erreur adj et sommet requis edges [" << i <<  "][ " << j << "]= "
-							 <<  Number(edges[i][j]) << " : "  << " on = " << Gh.Number(edges[i].on) ;
-						  if (edges[i][j].on->OnGeomVertex())
-							cerr << " vertex " << Gh.Number(edges[i][j].on->gv);
-						  else if (edges[i][j].on->OnGeomEdge())
-							cerr << "Edges " << Gh.Number(edges[i][j].on->ge);
-						  else
-							cerr << " = " << edges[i][j].on ;
-						  cerr << endl;
-					  }
-		  }
-		CurrentTh=OldCurrentTh;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::Optim{{{1*/
-	Int4  Triangle::Optim(Int2 i,int koption) {
-		// turne around in positif sens
-		Int4 NbSwap =0;
-		Triangle  *t = this;
-		int k=0,j =OppositeEdge[i];
-		int jp = PreviousEdge[j];
-		// initialise   tp, jp the previous triangle & edge
-		Triangle *tp= at[jp];
-		jp = aa[jp]&3;
-		do {
-			//    cout << *t << " " <<  j  << "\n\t try swap " ;
-			while (t->swap(j,koption))
-			  {
-				NbSwap++;
-				assert(k++<20000);
-				t=  tp->at[jp];      // set unchange t qnd j for previous triangles
-				j=  NextEdge[tp->aa[jp]&3];
-				//   cout << "\n\t s  " <<  *t << " " << j << endl;
-			  }
-			// end on this  Triangle 
-			tp = t;
-			jp = NextEdge[j];
-
-			t=  tp->at[jp];      // set unchange t qnd j for previous triangles
-			j=  NextEdge[tp->aa[jp]&3];
-
-		} while( t != this);
-		return NbSwap;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::SmoothingVertex{{{1*/
-	void Triangles::SmoothingVertex(int nbiter,Real8 omega ) { 
-		long int verbosity=0;
-		//  if quatree exist remove it end reconstruct
-		if (quadtree) delete quadtree;
-		quadtree=0;
-		ReMakeTriangleContainingTheVertex();
-		Triangle vide; // a triangle to mark the boundary vertex
-		Triangle   ** tstart= new Triangle* [nbv];
-		Int4 i,j,k;
-		//   attention si Background == Triangle alors on ne peut pas utiliser la rechech rapide 
-		if ( this == & BTh)
-		 for ( i=0;i<nbv;i++)
-		  tstart[i]=vertices[i].t;     
-		else 
-		 for ( i=0;i<nbv;i++)
-		  tstart[i]=0;
-		for ( j=0;j<NbVerticesOnGeomVertex;j++ ) 
-		 tstart[ Number(VerticesOnGeomVertex[j].mv)]=&vide;
-		for ( k=0;k<NbVerticesOnGeomEdge;k++ ) 
-		 tstart[ Number(VerticesOnGeomEdge[k].mv)]=&vide;
-		if(verbosity>2) 
-		 cout << "  -- SmoothingVertex: nb Iteration = " << nbiter << " Omega = " << omega << endl;
-		for (k=0;k<nbiter;k++)
-		  {
-			Int4 i,NbSwap =0;
-			Real8 delta =0;
-			for ( i=0;i<nbv;i++)
-			 if (tstart[i] != &vide) // not a boundary vertex 
-			  delta=Max(delta,vertices[i].Smoothing(*this,BTh,tstart[i],omega));
-			if (!NbOfQuad)
-			 for ( i=0;i<nbv;i++)
-			  if (tstart[i] != &vide) // not a boundary vertex 
-				NbSwap += vertices[i].Optim(1);
-			if (verbosity>3)
-			 cout << "    Move max = " <<  sqrt(delta) << " iteration = " 
-				<< k << " Nb of Swap = " << NbSwap << endl;
-		  }
-
-		delete [] tstart;
-		if (quadtree) quadtree= new QuadTree(this);
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::MakeQuadTree{{{1*/
-	void Triangles::MakeQuadTree() {  
-		long int verbosity=0;
-		if(verbosity>8)
-		 cout << "      MakeQuadTree" << endl;
-		if (  !quadtree )  quadtree = new QuadTree(this);
-
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::ShowRegulaty{{{1*/
-	void  Triangles::ShowRegulaty() const {
-		const  Real8  sqrt32=sqrt(3.)*0.5; 
-		const Real8  aireKh=sqrt32*0.5;
-		D2  Beq(1,0),Heq(0.5,sqrt32);
-		D2xD2 Br(D2xD2(Beq,Heq).t());
-		D2xD2 B1r(Br.inv());
-		/*   D2xD2 BB = Br.t()*Br;
-			  cout << " BB = " << BB << " " << Br*B1r <<  endl; 
-			  MetricAnIso MMM(BB.x.x,BB.x.y,BB.y.y);
-			  MatVVP2x2 VMM(MMM);
-			  cout << " " << VMM.lambda1 << " " << VMM.lambda2 <<  endl; 
-			  */
-		double gammamn=1e100,hmin=1e100;
-		double gammamx=0,hmax=0;
-		double beta=1e100;
-		double beta0=0;
-		double  alpha2=0;
-		double area=0,Marea=0;
-		// Real8 cf= Real8(coefIcoor);
-		// Real8 cf2= 6.*cf*cf;
-		int nt=0;
-		for (int it=0;it<nbt;it++)
-		 if ( triangles[it].link) 
-			{
-			 nt++;
-			 Triangle &K=triangles[it];
-			 Real8  area3= Area2((R2) K[0],(R2) K[1],(R2) K[2])/6.;
-			 area+= area3;
-			 D2xD2 B_Kt(K[0],K[1],K[2]);
-			 D2xD2 B_K(B_Kt.t());
-			 D2xD2 B1K = Br*B_K.inv();
-			 D2xD2 BK =  B_K*B1r;
-			 D2xD2 B1B1 = B1K.t()*B1K;
-			 MetricAnIso MK(B1B1.x.x,B1B1.x.y,B1B1.y.y);
-			 MatVVP2x2 VMK(MK);
-			 alpha2 = Max(alpha2,Max(VMK.lambda1/VMK.lambda2,VMK.lambda2/VMK.lambda1));
-			 // cout << B_K << " * " << B1r << " == " << BK << " " << B_K*B_K.inv() << endl;
-			 Real8 betaK=0;
-
-			 for (int j=0;j<3;j++)
-				{
-				 Real8 he= Norme2(R2(K[j],K[(j+1)%3]));
-				 hmin=Min(hmin,he);
-				 hmax=Max(hmax,he);
-				 Vertex & v=K[j];
-				 D2xD2 M((MetricAnIso)v);
-				 betaK += sqrt(M.det());
-
-				 D2xD2 BMB = BK.t()*M*BK;
-				 MetricAnIso M1(BMB.x.x,BMB.x.y,BMB.y.y);
-				 MatVVP2x2 VM1(M1);
-				 //cout << B_K <<" " <<  M << " " <<  he << " " << BMB << " " << VM1.lambda1 << " " << VM1.lambda2<<   endl; 
-				 gammamn=Min3(gammamn,VM1.lambda1,VM1.lambda2);
-				 gammamx=Max3(gammamx,VM1.lambda1,VM1.lambda2);		
-				}
-			 betaK *= area3;//  1/2 (somme sqrt(det))* area(K)
-			 Marea+= betaK;
-			 // cout << betaK << " " << area3 << " " << beta << " " << beta0 << " " << area3*3*3*3 <<endl;
-			 beta=min(beta,betaK);
-			 beta0=max(beta0,betaK);
-			}   
-		area*=3; 
-		gammamn=sqrt(gammamn);
-		gammamx=sqrt(gammamx);    
-		cout << "  -- adaptmesh Regulary:  Nb triangles " << nt <<  " , h  min " << hmin  << " , h max " << hmax << endl;  
-		cout << "     area =  " << area << " , M area = " << Marea << " , M area/( |Khat| nt) " << Marea/(aireKh*nt) << endl; 
-		cout << "     infiny-regulaty:  min " << gammamn << "  max " << gammamx << endl;  
-		cout << "     anisomax  "<< sqrt(alpha2) << ", beta max = " << 1./sqrt(beta/aireKh) 
-		  << " min  "<<  1./sqrt(beta0/aireKh)  << endl;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::ShowHistogram{{{1*/
-	void  Triangles::ShowHistogram() const {
-
-		const Int4 kmax=10;
-		const Real8 llmin = 0.5,llmax=2;
-		const Real8 lmin=log(llmin),lmax=log(llmax),delta= kmax/(lmax-lmin);
-		Int4 histo[kmax+1];
-		Int4 i,it,k, nbedges =0;
-		for (i=0;i<=kmax;i++) histo[i]=0;
-		for (it=0;it<nbt;it++)
-		 if ( triangles[it].link) 
-			{
-
-			 for (int j=0;j<3;j++)
-				{
-				 Triangle *ta = triangles[it].TriangleAdj(j);
-				 if ( !ta || !ta->link || Number(ta) >= it) 
-					{ 
-					 Vertex & vP = triangles[it][VerticesOfTriangularEdge[j][0]];
-					 Vertex & vQ = triangles[it][VerticesOfTriangularEdge[j][1]];
-					 if ( !& vP || !&vQ) continue;
-					 R2 PQ = vQ.r - vP.r;
-					 Real8 l = log(LengthInterpole(vP,vQ,PQ));
-					 nbedges++;
-					 k = (int) ((l - lmin)*delta);
-					 k = Min(Max(k,0L),kmax);
-					 histo[k]++;
-					}
-				}
-			}  
-		cout << "  -- Histogram of the unit mesh,  nb of edges" << nbedges << endl <<endl;
-
-		cout << "        length of edge in   | % of edge  | Nb of edges " << endl;
-		cout << "        ------------------- | ---------- | ----------- " << endl;
-		for   (i=0;i<=kmax;i++)
-		  { 
-			cout << "    " ;
-			cout.width(10);
-			if (i==0) cout  << " 0 " ;
-			else cout  << exp(lmin+i/delta) ;
-			cout.width(); cout << "," ;
-			cout.width(10);
-			if (i==kmax) cout << " +infty " ;
-			else cout  << exp(lmin+(i+1)/delta) ;
-			cout.width();cout << "   |   " ;
-
-			cout.precision(4);
-			cout.width(6);
-			cout <<  ((long)  ((10000.0 * histo[i])/ nbedges))/100.0 ;
-			cout.width();
-			cout.precision();
-			cout <<  "   |   " << histo[i] <<endl;
-		  }
-		cout << "        ------------------- | ---------- | ----------- " << endl <<endl;
-
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::Crack{{{1*/
-	int  Triangles::Crack() { 
-		assert(NbCrackedEdges ==0 || NbCrackedVertices >0); 
-		for (int i=0;i<NbCrackedEdges;i++)
-		 CrackedEdges[i].Crack();
-		return NbCrackedEdges;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::UnCrack{{{1*/
-	int Triangles::UnCrack() { 
-		assert(NbCrackedEdges ==0 || NbCrackedVertices >0); 
-		for (int i=0;i<NbCrackedEdges;i++)
-		 CrackedEdges[i].UnCrack();
-		return NbCrackedEdges;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::CrackMesh{{{1*/
-	int Triangles::CrackMesh() {
-		long int verbosity=0;
-		Triangles *CurrentThOld = CurrentTh;
-		//  computed the number of cracked edge
-		int i,k;
-		for (k=i=0;i<nbe;i++)
-		 if(edges[i].on->Cracked()) k++;
-		if( k==0) return 0;
-		CurrentTh = this;
-		cout << " Nb of Cracked Edges = " << k << endl;
-		NbCrackedEdges =k;
-		CrackedEdges = new  CrackedEdge[k];
-		//  new edge
-		Edge * e = new Edge[ nbe + k];
-
-		// copy
-		for (i=0;i<nbe;i++) 
-		 e[i] = edges[i];
-		delete edges;
-		edges = e;
-
-		const int  nbe0  = nbe;
-		for (k=i=0;i<nbe0;i++) // on double les arete cracked 
-		 if(edges[i].on->Cracked())
-			{
-			 e[nbe] = e[i];
-			 //  return the edge 
-			 e[nbe].v[0] =  e[i].v[1];
-			 e[nbe].v[1] =  e[i].v[0];
-			 e[nbe].on = e[i].on->link ; // fqux 
-			 CrackedEdges[k++]=CrackedEdge(edges,i,nbe);
-			 nbe++;
-			}
-		ReMakeTriangleContainingTheVertex() ; 
-		//  
-		int nbcrakev  =0;
-		Vertex *vlast = vertices + nbv;
-		Vertex *vend = vertices + nbvx; // end of array
-		for (int iv=0;iv<nbv;iv++) // vertex 
-		  {
-			Vertex & v= vertices[iv];
-			Vertex * vv = & v;  
-			int kk=0; // nb cracked
-			int kc=0; 
-			int kkk =0; // nb triangle  with same number 
-			Triangle * tbegin = v.t;
-			int i  = v.vint;       
-			assert(tbegin && (i >= 0 ) && (i <3));
-			// turn around the vertex v
-			TriangleAdjacent ta(tbegin,EdgesVertexTriangle[i][0]);// previous edge
-			int k=0;
-			do {
-				int kv = VerticesOfTriangularEdge[ta][1];
-				k++; 
-				Triangle * tt (ta);
-				if ( ta.Cracked() ) 
-				  {   
-					TriangleAdjacent tta=(ta.Adj());
-					assert(tta.Cracked());
-					if ( kk == 0) tbegin=ta,kkk=0;  //  begin by a cracked edge  => restart                
-					if (  kkk ) { kc =1;vv = vlast++;  kkk = 0; } // new vertex if use 
-					kk++;// number of cracked edge view                 
-				  }
-				if ( tt->link ) { // if good triangles store the value 
-					int it = Number(tt);
-					assert(it < nt);
-					(*tt)(kv)= vv; //   Change the vertex of triangle 
-					if(vv<vend) {*vv= v;vv->ReferenceNumber=iv;} // copy the vertex value + store the old vertex number in ref 
-					//	  tt->SetTriangleContainingTheVertex();
-					kkk++;
-				} else if (kk) { // crack + boundary 
-					if (  kkk ) { kc =1;vv = vlast++;  kkk = 0; } // new vertex if use 
-				}
-
-				ta = Next(ta).Adj(); 
-			} while ( (tbegin != ta)); 
-			assert(k);
-			if (kc)  nbcrakev++;
-		  }
-
-		if ( nbcrakev ) 
-		 for (int iec =0;iec < NbCrackedEdges; iec ++)
-		  CrackedEdges[iec].Set();
-
-		//  set the ref 
-		cout << " set the ref " <<  endl ;
-		NbCrackedVertices =   nbcrakev;
-		// int nbvo = nbv;
-		nbv = vlast - vertices;
-		int nbnewv =  nbv - nbv; // nb of new vrtices 
-		if (nbcrakev && verbosity > 1 )
-		 cout << " Nb of craked vertices = " << nbcrakev << " Nb of created vertices " <<   nbnewv<< endl;
-		// all the new vertices are on geometry 
-		//  BOFBO--  A VOIR
-		if (nbnewv)
-		  { // 
-			Int4 n = nbnewv+NbVerticesOnGeomVertex;
-			Int4 i,j,k;
-			VertexOnGeom * vog = new VertexOnGeom[n];
-			for ( i =0; i<NbVerticesOnGeomVertex;i++) 
-			 vog[i]=VerticesOnGeomVertex[i];
-			delete [] VerticesOnGeomVertex;
-			VerticesOnGeomVertex = vog;
-			// loop on cracked edge 
-			Vertex * LastOld = vertices + nbv - nbnewv;
-			for (int iec =0;iec < NbCrackedEdges; iec ++)
-			 for (k=0;k<2;k++)
-				{
-				 Edge & e = *( k ? CrackedEdges[iec].a.edge : CrackedEdges[iec].b.edge);
-				 for (j=0;j<2;j++) 
-					{
-					 Vertex * v = e(j);
-					 if ( v >=  LastOld)
-						{ // a new vertex 
-						 Int4 old = v->ReferenceNumber ; // the old same vertex 
-						 Int4 i  = ( v - LastOld);
-						 //  if the old is on vertex => warning
-						 // else the old is on edge => ok 
-						 vog[i] = vog[old];
-						 //  		    vog[i].mv = v;
-						 //g[i].ge = ;
-						 //og[i].abcisse = ;
-						}
-
-					}
-				}
-
-			NbVerticesOnGeomVertex = n;
-		  }
-		SetVertexFieldOn();
-
-
-		if (vlast >= vend)
-		  {  
-			cerr << " Not enougth vertices to crack the mesh we need " << nbv << " vertices " << endl;
-			MeshError(555,this);
-		  }
-		cout << "  NbCrackedVertices " <<  NbCrackedVertices << endl;
-		CurrentTh = CurrentThOld;
-		return  NbCrackedVertices;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::FindTriangleContening{{{1*/
-	Triangle * Triangles::FindTriangleContening(const I2 & B,Icoor2 dete[3], Triangle *tstart) const {
-		Triangle * t=0;	
-		int j,jp,jn,jj;
-		if (tstart) 
-		 t=tstart;
-		else 
-		  {
-			assert(quadtree);
-			Vertex *a = quadtree->NearestVertex(B.x,B.y) ;
-
-			if (! a || !a->t ) {
-				if (a) 
-				  {cerr << " Attention PB TriangleConteningTheVertex  vertex number=" << Number(a) << endl;
-					cerr  << "We forget a call to ReMakeTriangleContainingTheVertex" << endl;}
-					cerr << " Pb with " << B << toR2(B) << endl;
-					MeshError(7777);
-			}
-			assert(a>= vertices && a < vertices+nbv);
-			//  int k=0;
-			t = a->t;
-			assert(t>= triangles && t < triangles+nbt);
-
-		  }
-		Icoor2  detop ;
-		int kkkk =0; // number of test triangle 
-
-		while ( t->det < 0) 
-		  { // the initial triangles is outside  
-			int k0=(*t)(0) ?  ((  (*t)(1) ? ( (*t)(2) ? -1 : 2) : 1  )) : 0;
-			assert(k0>=0); // k0 the NULL  vertex 
-			int k1=NextVertex[k0],k2=PreviousVertex[k0];
-			dete[k0]=det(B,(*t)[k1],(*t)[k2]);
-			dete[k1]=dete[k2]=-1;     
-			if (dete[k0] > 0) // outside B 
-			 return t; 
-			t = t->TriangleAdj(OppositeEdge[k0]);
-			assert(kkkk++ < 2);
-		  }
-
-		jj=0;
-		detop = det(*(*t)(VerticesOfTriangularEdge[jj][0]),*(*t)(VerticesOfTriangularEdge[jj][1]),B);
-
-		while(t->det  > 0 ) 
-		  { 
-			assert( kkkk++ < 2000 ); 
-			j= OppositeVertex[jj];
-			dete[j] = detop;  //det(*b,*s1,*s2);
-			jn = NextVertex[j];
-			jp = PreviousVertex[j];
-			dete[jp]= det(*(*t)(j),*(*t)(jn),B);
-			dete[jn] = t->det-dete[j] -dete[jp];
-
-			// count the number k of  dete <0
-			int k=0,ii[3];
-			if (dete[0] < 0 ) ii[k++]=0; 
-			if (dete[1] < 0 ) ii[k++]=1;
-			if (dete[2] < 0 ) ii[k++]=2;
-			// 0 => ok
-			// 1 => go in way 1
-			// 2 => two way go in way 1 or 2 randomly
-
-			if (k==0) 
-			 break;
-			if (k == 2 && BinaryRand())
-			 Exchange(ii[0],ii[1]);
-			assert ( k  < 3);
-			TriangleAdjacent t1 = t->Adj(jj=ii[0]);
-			if ((t1.det() < 0 ) && (k == 2))
-			 t1 = t->Adj(jj=ii[1]);
-			t=t1;
-			j=t1;// for optimisation we now the -det[OppositeVertex[j]];
-			detop = -dete[OppositeVertex[jj]];
-			jj = j;
-		  }
-
-		if (t->det<0) // outside triangle 
-		 dete[0]=dete[1]=dete[2]=-1,dete[OppositeVertex[jj]]=detop;
-		//  NbOfTriangleSearchFind += kkkk;  
-		return t;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::IntersectGeomMetric{{{1*/
-	void Triangles::IntersectGeomMetric(const Real8 err=1,const int iso=0){
-		long int verbosity=0;
-
-		if(verbosity>1)
-		 cout << "  -- IntersectGeomMetric geometric err=" << err << (iso ? " iso " : " aniso "  ) << endl;
-		Real8 ss[2]={0.00001,0.99999};
-		Real8 errC = 2*sqrt(2*err);
-		Real8 hmax = Gh.MaximalHmax();
-		Real8 hmin = Gh.MinimalHmin();
-		Real8 maxaniso = 1e6;
-		assert(hmax>0);
-		SetVertexFieldOn();
-		if (errC > 1) errC = 1;
-		for (Int4  i=0;i<nbe;i++)
-		 for (int j=0;j<2;j++)
-			{
-
-			 Vertex V;
-			 VertexOnGeom GV;
-			 // cerr << Number(edges[i]) << " " << ss[j] << endl;
-			 Gh.ProjectOnCurve(edges[i],ss[j],V,GV);
-				{
-				 GeometricalEdge * eg = GV;
-				 Real8 s = GV;
-				 R2 tg;
-				 //	   cerr << i << " " << j << " " << Number(V) << " on = " 
-				 //	<< Gh.Number(eg) << " at s = " << s << " " << endl;
-				 Real8  R1= eg->R1tg(s,tg);
-				 // cerr << " R = " << 1/Max(R1,1e-20) << tg << " on x " 
-				 //    << V.r << errC/ Max(R1,1e-20) <<  " hold=" <<V.m(tg) << " "  << endl;
-				 Real8 ht = hmax;
-				 if (R1>1.0e-20) 
-					{  // err relative to the length of the edge
-					 ht = Min(Max(errC/R1,hmin),hmax);
-					}
-				 Real8 hn = iso? ht : Min(hmax,ht*maxaniso);
-				 //cerr << ht << " " << hn << "m=" << edges[i][j].m <<  endl;
-				 assert(ht>0 && hn>0);
-				 MatVVP2x2 Vp(1/(ht*ht),1/(hn*hn),tg);
-				 //cerr << " : " ;
-				 Metric MVp(Vp);
-				 // cerr << " : "  << MVp  << endl;
-				 edges[i][j].m.IntersectWith(MVp);
-				 //cerr << " . " << endl;
-				}
-
-			}
-		// the problem is for the vertex on vertex 
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::BoundAnisotropy{{{1*/
-	void  Triangles::BoundAnisotropy(Real8 anisomax,Real8 hminaniso) {
-		long int verbosity=0;
-
-		double lminaniso = 1/ (Max(hminaniso*hminaniso,1e-100));
-		if (verbosity > 1) 
-		 cout << "  -- BoundAnisotropy by  " << anisomax << endl; 
-		Real8 h1=1.e30,h2=1e-30,rx=0;
-		Real8 coef = 1./(anisomax*anisomax);
-		Real8 hn1=1.e30,hn2=1e-30,rnx =1.e-30;  
-		for (Int4 i=0;i<nbv;i++)
-		  {
-
-			MatVVP2x2 Vp(vertices[i]);
-			double lmax=Vp.lmax();
-			h1=Min(h1,Vp.lmin());
-			h2=Max(h2,Vp.lmax());
-			rx = Max(rx,Vp.Aniso2());
-
-			Vp *= Min(lminaniso,lmax)/lmax;
-
-			Vp.BoundAniso2(coef);
-
-			hn1=Min(hn1,Vp.lmin());
-			hn2=Max(hn2,Vp.lmax());
-			rnx = Max(rnx,Vp.Aniso2());
-
-
-			vertices[i].m = Vp;
-
-		  }
-
-		if (verbosity>2)
-		  {
-			cout << "     input :  Hmin = " << sqrt(1/h2)  << " Hmax = " << sqrt(1/h1) 
-			  << " factor of anisotropy max  = " << sqrt(rx) << endl;
-			cout << "     output:  Hmin = " << sqrt(1/hn2) << " Hmax = " << sqrt(1/hn1) 
-			  << " factor of anisotropy max  = " << sqrt(rnx) << endl;
-		  }
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::IntersectConsMetric{{{1*/
-	void Triangles::IntersectConsMetric(const double * s,const Int4 nbsol,const int * typsols,
-				const  Real8 hmin1,const Real8 hmax1,const Real8 coef,
-				const Real8 anisomax ,const Real8 CutOff,const int NbJacobi,
-				const int DoNormalisation,const double power,const int choice)
-	  { //  the array of solution s is store    
-		// sol0,sol1,...,soln    on vertex 0
-		//  sol0,sol1,...,soln   on vertex 1
-		//  etc.
-		//  choise = 0 =>  H is computed with green formule
-		//   otherwise  => H is computed from P2 on 4T 
-		const int dim = 2;
-
-		long int verbosity=0;
-
-		int sizeoftype[] = { 1, dim ,dim * (dim+1) / 2, dim * dim } ; 
-
-		// computation of the nb of field 
-		Int4 ntmp = 0;
-		if (typsols)
-		  {
-			for (Int4 i=0;i<nbsol;i++)
-			 ntmp += sizeoftype[typsols[i]];
-		  }
-		else
-		 ntmp = nbsol;
-
-		// n is the total number of fields
-
-		const Int4 n = ntmp;
-
-		Int4 i,k,iA,iB,iC,iv;
-		R2 O(0,0);
-		int RelativeMetric = CutOff>1e-30;
-		Real8 hmin = Max(hmin1,MinimalHmin());
-		Real8 hmax = Min(hmax1,MaximalHmax());
-		Real8 coef2 = 1/(coef*coef);
-
-		if(verbosity>1) 
-		  {
-			cout << "  -- Construction of Metric: Nb of field. " << n << " nbt = " 
-			  << nbt << " nbv= " << nbv 
-			  << " coef = " << coef << endl
-			  << "     hmin = " << hmin << " hmax=" << hmax 
-			  << " anisomax = " << anisomax <<  " Nb Jacobi " << NbJacobi << " Power = " << power ;
-			if (RelativeMetric)
-			 cout << " RelativeErr with CutOff= "  <<  CutOff << endl;
-			else
-			 cout << " Absolute Err" <<endl;
-		  }
-		double *ss=(double*)s;//, *ssiii = ss;
-
-		double sA,sB,sC;
-
-		Real8 *detT = new Real8[nbt];
-		Real8 *Mmass= new Real8[nbv];
-		Real8 *Mmassxx= new Real8[nbv];
-		Real8 *dxdx= new Real8[nbv];
-		Real8 *dxdy= new Real8[nbv];
-		Real8 *dydy= new Real8[nbv];
-		Real8 *workT= new Real8[nbt];
-		Real8 *workV= new Real8[nbv];
-		int *OnBoundary = new int[nbv];
-		for (iv=0;iv<nbv;iv++)
-		  {
-			Mmass[iv]=0;
-			OnBoundary[iv]=0;
-			Mmassxx[iv]=0;
-		  }
-
-		for (i=0;i<nbt;i++) 
-		 if(triangles[i].link) // the real triangles 
-			{
-			 const Triangle &t=triangles[i];
-			 // coor of 3 vertices 
-			 R2 A=t[0];
-			 R2 B=t[1];
-			 R2 C=t[2];
-
-
-			 // number of the 3 vertices
-			 iA = Number(t[0]);
-			 iB = Number(t[1]);
-			 iC = Number(t[2]);
-
-			 Real8 dett = bamg::Area2(A,B,C);
-			 detT[i]=dett;
-			 dett /= 6;
-
-			 // construction of on boundary 
-			 int nbb =0;
-			 for(int j=0;j<3;j++)
-				{
-				 Triangle *ta=t.Adj(j);
-				 if ( ! ta || !ta->link) // no adj triangle => edge on boundary
-				  OnBoundary[Number(t[VerticesOfTriangularEdge[j][0]])]=1,
-					 OnBoundary[Number(t[VerticesOfTriangularEdge[j][1]])]=1,
-					 nbb++;
-				}
-
-			 workT[i] = nbb;
-			 Mmass[iA] += dett;
-			 Mmass[iB] += dett;
-			 Mmass[iC] += dett;
-
-			 if((nbb==0)|| !choice)
-				{
-				 Mmassxx[iA] += dett;
-				 Mmassxx[iB] += dett;
-				 Mmassxx[iC] += dett;
-				}
-			}
-		 else
-		  workT[i]=-1;
-
-		for (Int4 nusol=0;nusol<nbsol;nusol++)
-		  { //for all Solution  
-
-			Real8 smin=ss[0],smax=ss[0];
-
-			Real8 h1=1.e30,h2=1e-30,rx=0;
-			Real8 coef = 1./(anisomax*anisomax);
-			Real8 hn1=1.e30,hn2=1e-30,rnx =1.e-30;  
-			int nbfield = typsols? sizeoftype[typsols[nusol]] : 1; 
-			if (nbfield == 1) 
-			 for ( iv=0,k=0; iv<nbv; iv++,k+=n )
-				{
-				 dxdx[iv]=dxdy[iv]=dydy[iv]=0;
-				 smin=Min(smin,ss[k]);
-				 smax=Max(smax,ss[k]);
-				}
-			else
-			  {
-				//  cas vectoriel 
-				for ( iv=0,k=0; iv<nbv; iv++,k+=n )
-				  {	
-					double v=0;		     
-					for (int i=0;i<nbfield;i++) 
-					 v += ss[k+i]*ss[k+i];
-					v = sqrt(v);
-					smin=Min(smin,v);
-					smax=Max(smax,v);
-				  }
-			  }
-			Real8 sdelta = smax-smin;
-			Real8 absmax=Max(Abs(smin),Abs(smax));
-			Real8 cnorm = DoNormalisation ? coef2/sdelta : coef2;
-
-			if(verbosity>2) 
-			 cout << "    Solution " << nusol <<  " Min = " << smin << " Max = " 
-				<< smax << " Delta =" << sdelta << " cnorm = " << cnorm <<  " Nb of fields =" << nbfield << endl;
-
-
-			if ( sdelta < 1.0e-10*Max(absmax,1e-20) && (nbfield ==1)) 
-			  {
-				if (verbosity>2)
-				 cout << "      Solution " << nusol << " is constant. We skip. " 
-					<< " Min = " << smin << " Max = " << smax << endl;
-				continue;
-			  }
-
-			double *sf  = ss; 
-			for (Int4 nufield=0;nufield<nbfield;nufield++,ss++) 
-			  {
-				for ( iv=0,k=0; iv<nbv; iv++,k+=n )
-				 dxdx[iv]=dxdy[iv]=dydy[iv]=0;
-				for (i=0;i<nbt;i++) 
-				 if(triangles[i].link)
-					{// for real all triangles 
-					 // coor of 3 vertices 
-					 R2 A=triangles[i][0];
-					 R2 B=triangles[i][1];
-					 R2 C=triangles[i][2];
-
-
-					 // warning the normal is internal and the 
-					 //   size is the length of the edge
-					 R2 nAB = Orthogonal(B-A);
-					 R2 nBC = Orthogonal(C-B);
-					 R2 nCA = Orthogonal(A-C);
-					 // remark :  nAB + nBC + nCA == 0 
-
-					 // number of the 3 vertices
-					 iA = Number(triangles[i][0]);
-					 iB = Number(triangles[i][1]);
-					 iC = Number(triangles[i][2]);
-
-					 // for the test of  boundary edge
-					 // the 3 adj triangles 
-					 Triangle *tBC = triangles[i].TriangleAdj(OppositeEdge[0]);
-					 Triangle *tCA = triangles[i].TriangleAdj(OppositeEdge[1]);
-					 Triangle *tAB = triangles[i].TriangleAdj(OppositeEdge[2]);
-
-					 // value of the P1 fonction on 3 vertices 
-					 sA = ss[iA*n];
-					 sB = ss[iB*n];
-					 sC = ss[iC*n];
-
-					 R2 Grads = (nAB * sC + nBC * sA + nCA * sB ) /detT[i] ;
-					 if(choice) 
-						{
-						 int nbb = 0;
-						 Real8 dd = detT[i];
-						 Real8 lla,llb,llc,llf;
-						 Real8  taa[3][3],bb[3];
-						 // construction of the trans of lin system
-						 for (int j=0;j<3;j++)
-							{
-							 int ie = OppositeEdge[j];
-							 TriangleAdjacent ta = triangles[i].Adj(ie);
-							 Triangle *tt = ta;
-							 if (tt && tt->link)
-								{
-								 Vertex &v = *ta.OppositeVertex();
-								 R2 V = v;
-								 Int4 iV = Number(v);
-								 Real8 lA  = bamg::Area2(V,B,C)/dd;
-								 Real8 lB  = bamg::Area2(A,V,C)/dd;
-								 Real8 lC  = bamg::Area2(A,B,V)/dd;
-								 taa[0][j] =  lB*lC;
-								 taa[1][j] =  lC*lA;
-								 taa[2][j] =  lA*lB;
-								 //Real8 xx = V.x-V.y;
-								 //Real8 yy = V.x + V.y;
-								 //cout << " iv " << ss[iV*n] << " == " << (8*xx*xx+yy*yy)
-								 //     << " l = " << lA << " " << lB << " " << lC 
-								 //     << " = " << lA+lB+lC << " " <<  V << " == " << A*lA+B*lB+C*lC << endl;
-
-								 lla = lA,llb=lB,llc=lC,llf=ss[iV*n] ;
-
-								 bb[j]     =  ss[iV*n] - ( sA*lA + sB*lB + sC*lC ) ;
-								}
-							 else
-								{
-								 nbb++;
-								 taa[0][j]=0;
-								 taa[1][j]=0;
-								 taa[2][j]=0;
-								 taa[j][j]=1;
-								 bb[j]=0;
-								}
-							}
-
-						 // resolution of 3x3 lineaire system transpose
-						 Real8 det33 =  det3x3(taa[0],taa[1],taa[2]);		
-						 Real8 cBC   =  det3x3(bb,taa[1],taa[2]);
-						 Real8 cCA   =  det3x3(taa[0],bb,taa[2]);
-						 Real8 cAB   =  det3x3(taa[0],taa[1],bb);
-
-						 assert(det33);
-						 //	det33=1;
-						 // verif
-						 //	cout << " " << (taa[0][0]*cBC +  taa[1][0]*cCA + taa[2][0] * cAB)/det33 << " == " << bb[0] ;
-						 //	cout << " " << (taa[0][1]*cBC +  taa[1][1]*cCA + taa[2][1] * cAB)/det33 << " == " << bb[1];
-						 //	cout << " " << (taa[0][2]*cBC +  taa[1][2]*cCA + taa[2][2] * cAB)/det33 << " == " << bb[2] 
-						 //	     << "  -- " ;
-						 //cout << lla*sA + llb*sB+llc*sC+ (lla*llb* cAB +  llb*llc* cBC + llc*lla*cCA)/det33 
-						 //   << " == " << llf <<  endl;
-						 // computation of the gradient in the element 
-
-						 // H( li*lj) = grad li grad lj + grad lj grad lj
-						 // grad li = njk  / detT ; with i j k =(A,B,C)
-						 Real8 Hxx = cAB * ( nBC.x*nCA.x) +  cBC * ( nCA.x*nAB.x) + cCA * (nAB.x*nBC.x);
-						 Real8 Hyy = cAB * ( nBC.y*nCA.y) +  cBC * ( nCA.y*nAB.y) + cCA * (nAB.y*nBC.y);
-						 Real8 Hxy = cAB * ( nBC.y*nCA.x) +  cBC * ( nCA.y*nAB.x) + cCA * (nAB.y*nBC.x) 
-							+ cAB * ( nBC.x*nCA.y) +  cBC * ( nCA.x*nAB.y) + cCA * (nAB.x*nBC.y);
-						 Real8 coef = 1.0/(3*dd*det33);
-						 Real8 coef2 = 2*coef;
-						 //	cout << " H = " << Hxx << " " << Hyy << " " <<  Hxy/2 << " coef2 = " << coef2 << endl;
-						 Hxx *= coef2;
-						 Hyy *= coef2;
-						 Hxy *= coef2;
-						 //cout << i  << " H = " << 3*Hxx/dd << " " << 3*Hyy/dd << " " <<  3*Hxy/(dd*2) << " nbb = " << nbb << endl;
-						 if(nbb==0)
-							{
-							 dxdx[iA] += Hxx;
-							 dydy[iA] += Hyy;
-							 dxdy[iA] += Hxy;
-
-							 dxdx[iB] += Hxx;
-							 dydy[iB] += Hyy;
-							 dxdy[iB] += Hxy;
-
-							 dxdx[iC] += Hxx;
-							 dydy[iC] += Hyy;
-							 dxdy[iC] += Hxy;
-							}
-
-						}
-					 else
-						{
-
-						 // if edge on boundary no contribution  => normal = 0
-						 if ( ! tBC || ! tBC->link ) nBC = O;
-						 if ( ! tCA || ! tCA->link ) nCA = O;
-						 if ( ! tAB || ! tAB->link ) nAB = O;
-
-						 // remark we forgot a 1/2 because
-						 //       $\\int_{edge} w_i = 1/2 $ if $i$ is in edge 
-						 //                          0  if not
-						 // if we don't take the  boundary 
-						 // dxdx[iA] += ( nCA.x + nAB.x ) *Grads.x;
-
-						 dxdx[iA] += ( nCA.x + nAB.x ) *Grads.x;
-						 dxdx[iB] += ( nAB.x + nBC.x ) *Grads.x;
-						 dxdx[iC] += ( nBC.x + nCA.x ) *Grads.x;
-
-						 // warning optimization (1) the divide by 2 is done on the metrix construction
-						 dxdy[iA] += (( nCA.y + nAB.y ) *Grads.x + ( nCA.x + nAB.x ) *Grads.y) ;
-						 dxdy[iB] += (( nAB.y + nBC.y ) *Grads.x + ( nAB.x + nBC.x ) *Grads.y) ;
-						 dxdy[iC] += (( nBC.y + nCA.y ) *Grads.x + ( nBC.x + nCA.x ) *Grads.y) ; 
-
-						 dydy[iA] += ( nCA.y + nAB.y ) *Grads.y;
-						 dydy[iB] += ( nAB.y + nBC.y ) *Grads.y;
-						 dydy[iC] += ( nBC.y + nCA.y ) *Grads.y;
-						}
-
-					} // for real all triangles 
-				Int4 kk=0;
-				for ( iv=0,k=0 ; iv<nbv; iv++,k+=n )
-				 if(Mmassxx[iv]>0) 
-					{
-					 dxdx[iv] /= 2*Mmassxx[iv];
-					 // warning optimization (1) on term dxdy[iv]*ci/2 
-					 dxdy[iv] /= 4*Mmassxx[iv];
-					 dydy[iv] /= 2*Mmassxx[iv];
-					 // Compute the matrix with abs(eigen value)
-					 Metric M(dxdx[iv], dxdy[iv], dydy[iv]);
-					 MatVVP2x2 Vp(M);
-					 //cout <<iv <<  "  M  = " <<  M <<  " aniso= " << Vp.Aniso() ;
-					 Vp.Abs();
-					 M = Vp;
-					 dxdx[iv] = M.a11;
-					 dxdy[iv] = M.a21;
-					 dydy[iv] = M.a22;
-					 //  cout << " (abs)  iv M  = " <<  M <<  " aniso= " << Vp.Aniso() <<endl;
-					}
-				 else kk++;
-
-
-				// correction of second derivate
-				// by a laplacien
-
-				Real8 *d2[3] = { dxdx, dxdy, dydy};
-				Real8 *dd;
-				for (int xy = 0;xy<3;xy++)
-				  {
-					dd = d2[xy];
-					// do leat 2 iteration for boundary problem
-					for (int ijacobi=0;ijacobi<Max(NbJacobi,2);ijacobi++)
-					  {
-						for (i=0;i<nbt;i++) 
-						 if(triangles[i].link) // the real triangles 
-							{
-							 // number of the 3 vertices
-							 iA = Number(triangles[i][0]);
-							 iB = Number(triangles[i][1]);
-							 iC = Number(triangles[i][2]);
-							 Real8 cc=3;
-							 if(ijacobi==0)
-							  cc = Max((Real8) ((Mmassxx[iA]>0)+(Mmassxx[iB]>0)+(Mmassxx[iC]>0)),1.);
-							 workT[i] = (dd[iA]+dd[iB]+dd[iC])/cc;
-							}
-						for (iv=0;iv<nbv;iv++)
-						 workV[iv]=0;
-
-						for (i=0;i<nbt;i++) 
-						 if(triangles[i].link) // the real triangles 
-							{
-							 // number of the 3 vertices
-							 iA = Number(triangles[i][0]);
-							 iB = Number(triangles[i][1]);
-							 iC = Number(triangles[i][2]);
-							 Real8 cc =  workT[i]*detT[i];
-							 workV[iA] += cc;
-							 workV[iB] += cc;
-							 workV[iC] += cc;
-							}
-
-						for (iv=0;iv<nbv;iv++)
-						 if( ijacobi<NbJacobi || OnBoundary[iv])
-						  dd[iv] = workV[iv]/(Mmass[iv]*6);
-
-
-					  }
-
-
-				  }
-
-				// constuction  of the metrix from the Hessian dxdx. dxdy,dydy
-
-				Real8 rCutOff=CutOff*absmax;// relative cut off 
-
-				for ( iv=0,k=0 ; iv<nbv; iv++,k+=n )
-				  { // for all vertices 
-					//{
-					//Metric M(dxdx[iv], dxdy[iv], dydy[iv]);
-					// MatVVP2x2 Vp(M);	  
-					//cout << " iv M="<<  M << "  Vp = " << Vp << " aniso  " << Vp.Aniso() << endl;
-					//}
-					MetricIso Miso;
-					// new code to compute ci ---	  
-					Real8 ci ;
-					if (RelativeMetric)
-					  { //   compute the norm of the solution
-						double xx =0,*sfk=sf+k; 
-						for (int ifield=0;ifield<nbfield;ifield++,sfk++)
-						 xx += *sfk* *sfk;	       
-						xx=sqrt(xx);
-						ci = coef2/Max(xx,rCutOff);
-					  }
-					else ci = cnorm;
-
-					// old 
-					//	  Real8 ci = RelativeMetric ? coef2/(Max(Abs(ss[k]),rCutOff)) : cnorm ;
-					//   modif F Hecht 101099
-					Metric Miv(dxdx[iv]*ci, dxdy[iv]*ci,  dydy[iv]*ci);
-					MatVVP2x2 Vp(Miv);
-
-					Vp.Abs();
-					if(power!=1.0) 
-					 Vp.pow(power);
-
-
-
-					h1=Min(h1,Vp.lmin());
-					h2=Max(h2,Vp.lmax());
-
-					Vp.Maxh(hmin);
-					Vp.Minh(hmax);
-
-					rx = Max(rx,Vp.Aniso2());
-
-					Vp.BoundAniso2(coef);
-
-					hn1=Min(hn1,Vp.lmin());
-					hn2=Max(hn2,Vp.lmax());
-					rnx = Max(rnx,Vp.Aniso2());
-
-					Metric MVp(Vp);
-					vertices[iv].m.IntersectWith(MVp);
-				  }// for all vertices 
-				if (verbosity>2)
-				  { 
-					cout << "              Field " << nufield << " of solution " << nusol  << endl;
-					cout << "              before bounding :  Hmin = " << sqrt(1/h2) << " Hmax = " 
-					  << sqrt(1/h1)  << " factor of anisotropy max  = " << sqrt(rx) << endl;
-					cout << "              after  bounding :  Hmin = " << sqrt(1/hn2) << " Hmax = " 
-					  << sqrt(1/hn1)  << " factor of anisotropy max  = " << sqrt(rnx) << endl;
-				  }
-			  } //  end of for all field
-		  }// end for all solution 
-
-		delete [] detT;
-		delete [] Mmass;
-		delete [] dxdx;
-		delete [] dxdy;
-		delete [] dydy;
-		delete []  workT;
-		delete [] workV;
-		delete [] Mmassxx;
-		delete []  OnBoundary;
-
-	  }
-	/*}}}1*/
-	/*FUNCTION Triangles::MaxSubDivision{{{1*/
-	void  Triangles::MaxSubDivision(Real8 maxsubdiv) {
-		long int verbosity=0;
-
-		const  Real8 maxsubdiv2 = maxsubdiv*maxsubdiv;
-		if(verbosity>1)
-		 cout << "  -- Limit the subdivision of a edges in the new mesh by " << maxsubdiv <<   endl  ;
-		// for all the edges 
-		// if the len of the edge is to long 
-		Int4 it,nbchange=0;    
-		Real8 lmax=0;
-		for (it=0;it<nbt;it++)
-		  {
-			Triangle &t=triangles[it];
-			for (int j=0;j<3;j++)
-			  {
-				Triangle &tt = *t.TriangleAdj(j);
-				if ( ! &tt ||  it < Number(tt) && ( tt.link || t.link)) 
-				  {
-					Vertex &v0 = t[VerticesOfTriangularEdge[j][0]];
-					Vertex &v1 = t[VerticesOfTriangularEdge[j][1]];
-					R2 AB= (R2) v1-(R2) v0;
-					Metric M = v0;
-					Real8 l = M(AB,AB);
-					lmax = Max(lmax,l);
-					if(l> maxsubdiv2)
-					  { R2 AC = M.Orthogonal(AB);// the ortogonal vector of AB in M
-						Real8 lc = M(AC,AC);
-						D2xD2 Rt(AB,AC);// Rt.x = AB , Rt.y = AC;
-						D2xD2 Rt1(Rt.inv());
-						D2xD2 D(maxsubdiv2,0,0,lc);
-						D2xD2 MM = Rt1*D*Rt1.t();
-						v0.m =  M = MetricAnIso(MM.x.x,MM.y.x,MM.y.y);
-						nbchange++;
-					  }
-					M = v1;
-					l = M(AB,AB);
-					lmax = Max(lmax,l);
-					if(l> maxsubdiv2)
-					  { R2 AC = M.Orthogonal(AB);// the ortogonal vector of AB in M
-						Real8 lc = M(AC,AC);
-						D2xD2 Rt(AB,AC);// Rt.x = AB , Rt.y = AC;
-						D2xD2 Rt1(Rt.inv());
-						D2xD2 D(maxsubdiv2,0,0,lc);
-						D2xD2  MM = Rt1*D*Rt1.t();
-						v1.m =  M = MetricAnIso(MM.x.x,MM.y.x,MM.y.y);
-						nbchange++;
-					  }
-
-
-				  }
-			  }
-		  }
-		if(verbosity>3)
-		 cout << "    Nb of metric change = " << nbchange 
-			<< " Max  of the subdivision of a edges before change  = " << sqrt(lmax) << endl;
-
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::SmoothMetric{{{1*/
-	void Triangles::SmoothMetric(Real8 raisonmax) { 
-		long int verbosity=0;
-
-		if(raisonmax<1.1) return;
-		if(verbosity > 1)
-		 cout << "  -- Triangles::SmoothMetric raisonmax = " << raisonmax << " " <<nbv <<endl;
-		ReMakeTriangleContainingTheVertex();
-		Int4 i,j,kch,kk,ip;
-		Int4 *first_np_or_next_t0 = new Int4[nbv];
-		Int4 *first_np_or_next_t1 = new Int4[nbv];
-		Int4 Head0 =0,Head1=-1;
-		Real8 logseuil= log(raisonmax);
-
-		for(i=0;i<nbv-1;i++)
-		 first_np_or_next_t0[i]=i+1; 
-		first_np_or_next_t0[nbv-1]=-1;// end;
-		for(i=0;i<nbv;i++)
-		 first_np_or_next_t1[i]=-1;
-		kk=0;
-		while (Head0>=0&& kk++<100) {
-			kch=0;
-			for (i=Head0;i>=0;i=first_np_or_next_t0[ip=i],first_np_or_next_t0[ip]=-1)
-			  {  //  pour tous les triangles autour du sommet s
-				// 	cout << kk << " i = " << i << " " << ip << endl;
-				register Triangle * t= vertices[i].t;
-				assert(t);
-				Vertex & vi = vertices[i];
-				TriangleAdjacent ta(t,EdgesVertexTriangle[vertices[i].vint][0]);
-				Vertex *pvj0 = ta.EdgeVertex(0);
-				while (1) {
-					//	  cout << i << " " <<  Number(ta.EdgeVertex(0)) << " "
-					//      << Number(ta.EdgeVertex(1)) << "  ---> " ;
-					ta=Previous(Adj(ta));
-					// cout <<  Number(ta.EdgeVertex(0)) << " " << Number(ta.EdgeVertex(1)) << endl;
-					assert(vertices+i == ta.EdgeVertex(1));
-					Vertex & vj = *(ta.EdgeVertex(0));
-					if ( &vj ) {
-						j= &vj-vertices;
-						assert(j>=0 && j < nbv);
-						R2 Aij = (R2) vj - (R2) vi;
-						Real8 ll =  Norme2(Aij);
-						if (0) {  
-							Real8 hi = ll/vi.m(Aij);
-							Real8 hj = ll/vj.m(Aij);
-							if(hi < hj)
-							  {
-								Real8 dh=(hj-hi)/ll;
-								//cout << " dh = " << dh << endl;
-								if (dh>logseuil) {
-									vj.m.IntersectWith(vi.m/(1 +logseuil*ll/hi));
-									if(first_np_or_next_t1[j]<0)
-									 kch++,first_np_or_next_t1[j]=Head1,Head1=j;
-								}
-							  }
-						} 
-						else
-						  {
-							Real8 li = vi.m(Aij);
-							//Real8 lj = vj.m(Aij);
-							//		if ( i == 2 || j == 2)
-							//  cout << " inter " << i << " " << j << " " << ((1 +logseuil*li)) <<  endl;
-							if( vj.m.IntersectWith(vi.m/(1 +logseuil*li)) )
-							 //if( vj.m.IntersectWith(vi.m*(lj/li/(1 +logseuil*lj))) )
-							 if(first_np_or_next_t1[j]<0) // if the metrix change 
-							  kch++,first_np_or_next_t1[j]=Head1,Head1=j;
-						  }
-					}
-					if  ( &vj ==  pvj0 ) break;
-				}
-			  }
-			Head0 = Head1;
-			Head1 = -1;
-			Exchange(first_np_or_next_t0,first_np_or_next_t1);
-			if(verbosity>5)
-			 cout << "     Iteration " << kk << " Nb de  vertices with change  " << kch << endl;
-		}
-		if(verbosity>2 && verbosity < 5) 
-		 cout << "    Nb of Loop " << kch << endl;
-		delete [] first_np_or_next_t0;
-		delete [] first_np_or_next_t1;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::NearestVertex{{{1*/
-	Vertex * Triangles::NearestVertex(Icoor1 i,Icoor1 j) {
-		return  quadtree->NearestVertex(i,j); 
-	} 
-	/*}}}1*/
-	/*FUNCTION Triangles::PreInit{{{1*/
-	void Triangles::PreInit(Int4 inbvx,char *fname) {
-		long int verbosity=0;
-
-		srand(19999999);
-		OnDisk =0;
-		NbRef=0;
-		//  allocGeometry=0;
-		identity=0;
-		NbOfTriangleSearchFind =0;
-		NbOfSwapTriangle =0;
-		nbiv=0;
-		nbv=0;
-		nbvx=inbvx;
-		nbt=0;
-		NbOfQuad = 0;
-		nbtx=2*inbvx-2;
-		NbSubDomains=0;
-		NbVertexOnBThVertex=0;
-		NbVertexOnBThEdge=0;
-		VertexOnBThVertex=0;
-		VertexOnBThEdge=0;
-
-		NbCrackedVertices=0;
-		NbCrackedEdges =0;
-		CrackedEdges  =0;  
-		nbe = 0; 
-		name = fname ;
-
-		if (inbvx) {
-			vertices=new Vertex[nbvx];
-			assert(vertices);
-			ordre=new (Vertex* [nbvx]);
-			assert(ordre);
-			triangles=new Triangle[nbtx];
-			assert(triangles);}
-		else {
-			vertices=0;
-			ordre=0;
-			triangles=0;
-			nbtx=0;
-		}
-		if ( name || inbvx)
-		  {
-			time_t timer =time(0);
-			char buf[70];     
-			strftime(buf ,70,", Date: %y/%m/%d %H:%M %Ss",localtime(&timer));
-			counter++; 
-			char countbuf[30];   
-			sprintf(countbuf,"%d",counter);
-			int lg =0 ;
-			if (&BTh != this && BTh.name)
-			 lg = strlen(BTh.name)+4;
-			identity = new char[ lg + strlen(buf) + strlen(countbuf)+ 2  + 10 + ( Gh.name ? strlen(Gh.name) + 4 : 0)];
-			identity[0]=0;
-			if (lg)
-			 strcat(strcat(strcat(identity,"B="),BTh.name),", ");
-
-			if (Gh.name)
-			 strcat(strcat(identity,"G="),Gh.name);
-			strcat(strcat(identity,";"),countbuf);
-			strcat(identity,buf);
-			// cout << "New MAILLAGE "<< identity << endl;
-		  } 
-
-		quadtree=0;
-		//  edgescomponante=0;
-		edges=0;
-		VerticesOnGeomVertex=0;
-		VerticesOnGeomEdge=0;
-		NbVerticesOnGeomVertex=0;
-		NbVerticesOnGeomEdge=0;
-		//  nbMaxIntersectionTriangles=0;
-		//  lIntTria;
-		subdomains=0;
-		NbSubDomains=0;
-		//  Meshbegin = vertices;
-		//  Meshend  = vertices + nbvx;
-		if (verbosity>98) 
-		 cout << "Triangles::PreInit() " << nbvx << " " << nbtx 
-			<< " " << vertices 
-			<< " " << ordre << " " <<  triangles <<endl;
-	}
-	/*}}}1*/
-
-} // end of namespace bamg 
Index: /issm/trunk/src/c/Bamgx/objects/GeometricalEdge.cpp
===================================================================
--- /issm/trunk/src/c/Bamgx/objects/GeometricalEdge.cpp	(revision 2820)
+++ /issm/trunk/src/c/Bamgx/objects/GeometricalEdge.cpp	(revision 2820)
@@ -0,0 +1,124 @@
+#include <cstdio>
+#include <string.h>
+#include <cmath>
+#include <time.h>
+#include <iostream>
+
+#include "../Mesh2.h"
+#include "../QuadTree.h"
+#include "../SetOfE4.h"
+
+using namespace std;
+
+namespace bamg {
+
+	/*Constructor/Destructor*/
+
+	/*Others*/
+	/*FUNCTION GeometricalEdge::R1tg{{{1*/
+	Real8 GeometricalEdge::R1tg(Real8 theta,R2 & t) const // 1/R of radius of cuvature
+	  { R2 A=v[0]->r,B=v[1]->r;
+		Real8 dca,dcb,dcta,dctb;
+		Real8 ddca,ddcb,ddcta,ddctb;
+		// Real8 t1 = 1 -theta;
+		// Real8 t1t1 = t1*t1;
+		Real8 tt = theta*theta;
+		assert( theta >=0);
+		assert( theta <=1);
+		if (TgA()) 
+		 if (TgB()) // interpolation d'hermite
+			{ //cb =  theta*theta*(3-2*theta);
+			 dcb = 6*theta*(1-theta);
+			 ddcb = 6*(1-2*theta);
+			 //ca =  1-cb;     
+			 dca = -dcb;
+			 ddca = -ddcb;
+
+			 // cta = (1-theta)*(1-theta)*theta;
+			 dcta =  (3*theta - 4)*theta + 1;
+			 ddcta=6*theta-4;
+
+			 //ctb = (theta-1)*theta*theta ;
+			 dctb = 3*tt - 2*theta;
+			 ddctb = 6*theta-2;
+			}
+		 else { // 1-t*t, t-t*t, t*t
+			 Real8 t = theta;
+			 // cb = t*t;
+			 dcb = 2*t;
+			 ddcb = 2;
+			 //ca = 1-cb;
+			 dca = -dcb;
+			 ddca = -2;
+			 // cta= t-cb;
+			 dcta = 1-dcb;
+			 ddcta = -ddcb;
+			 // ctb =0;
+			 dctb=0;    
+			 ddctb=0;    
+		 }    
+		else
+		 if (TgB()){
+			 Real8 t = 1-theta;
+			 //ca = t*t;
+			 dca = -2*t;
+			 ddca = 2;
+			 //cb = 1-ca;
+			 dcb = -dca;
+			 ddcb = -2;
+			 //ctb= -t+ca;
+			 dctb = 1+dca;
+			 ddctb= ddca;
+			 //cta=0;    
+			 dcta =0;
+			 ddcta =0;
+		 }
+		 else {t=B-A;return 0;} // lagrange P1
+		R2 d =  A*dca + B*dcb + tg[0]* dcta + tg[1] * dctb;
+
+		R2 dd =  A*ddca + B*ddcb + tg[0]* ddcta + tg[1] * ddctb;
+		Real8 d2=(d,d);
+		Real8 sd2 = sqrt(d2);
+		t=d;
+		if(d2>1.0e-20) {t/=sd2;return Abs(Det(d,dd))/(d2*sd2);}
+		else return 0;
+	  }
+	/*}}}1*/
+	/*FUNCTION GeometricalEdge::F{{{1*/
+	R2 GeometricalEdge::F(Real8 theta) const // parametrization of the curve edge
+	  { R2 A=v[0]->r,B=v[1]->r;
+		Real8 ca,cb,cta,ctb;
+		assert( theta >=-1e-12);
+		assert( theta <=1+1e-12);
+		if (TgA()) 
+		 if (TgB()) // interpolation d'hermite
+			{ cb =  theta*theta*(3-2*theta);
+			 ca =  1-cb;     
+			 cta = (1-theta)*(1-theta)*theta;
+			 ctb = (theta-1)*theta*theta ;
+			 //  if(ref==4 || ref==5)
+			 //  cout << " FFF " << tg[0] << tg[1] << A << B << " => " << A*ca + B*cb + tg[0]* cta + tg[1] * ctb << endl;
+			}
+		 else { // 1-t*t, t-t*t, t*t
+			 Real8 t = theta;
+			 cb = t*t;
+			 ca = 1-cb;
+			 cta= t-cb;
+			 ctb=0;    
+		 }    
+		else
+		 if (TgB()){
+			 Real8 t = 1-theta;
+			 ca = t*t;
+			 cb = 1-ca;
+			 ctb= -t+ca;
+			 cta=0;    
+		 }
+		 else {
+			 ca =(1-theta),cb = theta,cta=ctb=0; // lagrange P1
+		 }
+		return A*ca + B*cb + tg[0]* cta + tg[1] * ctb;
+	  }
+	/*}}}1*/
+
+}
Index: /issm/trunk/src/c/Bamgx/objects/Geometry.cpp
===================================================================
--- /issm/trunk/src/c/Bamgx/objects/Geometry.cpp	(revision 2820)
+++ /issm/trunk/src/c/Bamgx/objects/Geometry.cpp	(revision 2820)
@@ -0,0 +1,1031 @@
+#include <cstdio>
+#include <cstring>
+#include <cmath>
+#include <ctime>
+
+#include "../Mesh2.h"
+#include "../QuadTree.h"
+#include "../SetOfE4.h"
+
+#include "../../shared/shared.h"
+#include "../../include/macros.h"
+#include "../../toolkits/toolkits.h"
+
+namespace bamg {
+
+	static const  Direction NoDirOfSearch=Direction();
+
+	/*Constructors/Destructors*/
+
+	/*IO*/
+	/*FUNCTION Geometry::WriteGeometry{{{1*/
+	void Geometry::WriteGeometry(BamgGeom* bamggeom, BamgOpts* bamgopts){
+
+		int verbose;
+		int nbreq=0;
+		int nbreqv=0;
+		int nbtan=0;
+		int nbcracked=0;
+		int i,count;
+
+		verbose=bamgopts->verbose;
+
+		//Vertices
+		if(verbose>3) printf("      writing Vertices\n");
+		bamggeom->NumVertices=nbv;
+		xfree((void**)&bamggeom->Vertices);
+		if (nbv){
+			bamggeom->Vertices=(double*)xmalloc(3*nbv*sizeof(double));
+			for (i=0;i<nbv;i++){
+				bamggeom->Vertices[i*3+0]=vertices[i].r.x;
+				bamggeom->Vertices[i*3+1]=vertices[i].r.y;
+				bamggeom->Vertices[i*3+2]=vertices[i].ref();
+
+				//update counters
+				if (vertices[i].Required()) nbreqv++;
+			}
+		}
+		else{
+			bamggeom->Vertices=NULL;
+		}
+
+		//Edges
+		if(verbose>3) printf("      writing Edges\n");
+		bamggeom->NumEdges=nbe;
+		xfree((void**)&bamggeom->Edges);
+		if (nbe){
+			bamggeom->Edges=(double*)xmalloc(3*nbe*sizeof(double));
+			for (i=0;i<nbe;i++){
+				bamggeom->Edges[i*3+0]=Number(edges[i][0])+1; //back to Matlab indexing
+				bamggeom->Edges[i*3+1]=Number(edges[i][1])+1; //back to Matlab indexing
+				//bamggeom->Edges[i*3+2]=(double)edges[i].ref(); //TEST does not compile???
+				bamggeom->Edges[i*3+2]=1; //TEST for now
+
+				//update counters
+				if (edges[i].Required()) nbreq++;
+				if (edges[i].Cracked()){
+					if (i<=Number(edges[i].link)) nbcracked++;
+				}
+				if (edges[i].TgA() && edges[i][0].Corner()) nbtan++;
+				if (edges[i].TgB() && edges[i][1].Corner()) nbtan++;
+			}
+		}
+		else{
+			bamggeom->Edges=NULL;
+		}
+
+		//CrackedEdges
+		if(verbose>3) printf("      writing CrackedEdges\n");
+		bamggeom->NumCrackedEdges=nbcracked;
+		xfree((void**)&bamggeom->CrackedEdges);
+		if (nbcracked){
+			bamggeom->CrackedEdges=(double*)xmalloc(2*nbcracked*sizeof(double));
+			count=0;
+			for (i=0;i<nbe;i++){
+				if (edges[i].Cracked()){
+					if (i<=Number(edges[i].link)){
+						bamggeom->CrackedEdges[count*2+0]=i+1;                     //back to Matlab indexing
+						bamggeom->CrackedEdges[count*2+1]=Number(edges[i].link)+1; //back to Matlab indexing
+						count=count+1;
+					}
+				}
+			}
+		}
+		else{
+			bamggeom->CrackedEdges=NULL;
+		}
+
+		//RequiredEdges
+		if(verbose>3) printf("      writing RequiredEdges\n");
+		bamggeom->NumRequiredEdges=nbreq;
+		xfree((void**)&bamggeom->RequiredEdges);
+		if (nbreq){
+			bamggeom->RequiredEdges=(double*)xmalloc(1*nbreq*sizeof(double));
+			count=0;
+			for (i=0;i<nbe;i++){
+				if (edges[i].Required()){
+					bamggeom->RequiredEdges[count]=i+1; //back to Matlab indexing
+					count=count+1;
+				}
+			}
+		}
+		else{
+			bamggeom->RequiredEdges=NULL;
+		}
+
+		//No corners
+
+		//RequiredVertices
+		if(verbose>3) printf("      writing RequiredVertices\n");
+		bamggeom->NumRequiredVertices=nbreqv;
+		xfree((void**)&bamggeom->RequiredVertices);
+		if (nbreqv){
+			bamggeom->RequiredVertices=(double*)xmalloc(1*nbreqv*sizeof(double));
+			count=0;
+			for (i=0;i<nbe;i++){
+				if (vertices[i].Required()){
+					bamggeom->RequiredVertices[count]=i+1; //back to Matlab indexing
+					count=count+1;
+				}
+			}
+		}
+		else{
+			bamggeom->RequiredVertices=NULL;
+		}
+
+		//SubDomains
+		if(verbose>3) printf("      writing SubDomains\n");
+		bamggeom->NumSubDomains=NbSubDomains;
+		xfree((void**)&bamggeom->SubDomains);
+		if (NbSubDomains){
+			bamggeom->SubDomains=(double*)xmalloc(4*NbSubDomains*sizeof(double));
+			for (i=0;i<NbSubDomains;i++){
+				bamggeom->SubDomains[4*i+0]=2;
+				bamggeom->SubDomains[4*i+1]=Number(subdomains[i].edge)+1; //back to Matlab indexing
+				bamggeom->SubDomains[4*i+2]=subdomains[i].sens;
+				bamggeom->SubDomains[4*i+3]=subdomains[i].ref;
+			}
+		}
+		else{
+			bamggeom->SubDomains=NULL;
+		}
+
+		//TangentAtEdges
+		if(verbose>3) printf("      writing TangentAtEdges\n");
+		bamggeom->NumTangentAtEdges=nbtan;
+		xfree((void**)&bamggeom->TangentAtEdges);
+		if (nbtan){
+			bamggeom->TangentAtEdges=(double*)xmalloc(4*nbtan*sizeof(double));
+			count=0;
+			for (i=0;i<nbe;i++){
+				if (edges[i].TgA() && edges[i][0].Corner()){
+					bamggeom->TangentAtEdges[4*i+0]=i+1; //back to Matlab indexing
+					bamggeom->TangentAtEdges[4*i+1]=1;
+					bamggeom->TangentAtEdges[4*i+2]=edges[i].tg[0].x;
+					bamggeom->TangentAtEdges[4*i+3]=edges[i].tg[0].y;
+				}
+				if (edges[i].TgB() && edges[i][1].Corner()){
+					bamggeom->TangentAtEdges[4*i+0]=i+1; //back to Matlab indexing
+					bamggeom->TangentAtEdges[4*i+1]=2;
+					bamggeom->TangentAtEdges[4*i+2]=edges[i].tg[1].x;
+					bamggeom->TangentAtEdges[4*i+3]=edges[i].tg[2].y;
+				}
+				count=count+1;
+			}
+		}
+		else{
+			bamggeom->TangentAtEdges=NULL;
+		}
+	}
+	/*}}}1*/
+	/*FUNCTION Geometry::ReadGeometry{{{1*/
+	void Geometry::ReadGeometry(BamgGeom* bamggeom,BamgOpts* bamgopts){
+
+		int verbose;
+		nbiv=nbv=nbvx=0;
+		nbe=nbt=nbtx=0;
+		NbOfCurves=0;
+
+		Real8 Hmin = HUGE_VAL;// the infinie value 
+		Int4 hvertices=0;
+		int i,j,k,n;
+
+		//initialize some variables
+		int Version=1,dim=2;
+		nbv=bamggeom->NumVertices;
+		nbe=bamggeom->NumEdges;
+		nbvx = nbv;
+		nbiv = nbv;
+		verbose=bamgopts->verbose;
+
+		//some checks
+		if (bamggeom->NumVertices<=0 || bamggeom->Vertices==NULL){
+			throw ErrorException(__FUNCT__,exprintf("the domain provided does not contain any vertex"));
+		}
+		if (bamggeom->NumEdges<=0 || bamggeom->Edges==NULL){
+			throw ErrorException(__FUNCT__,exprintf("the domain provided does not contain any edge"));
+		}
+
+		//Vertices
+		if (bamggeom->Vertices){
+			if(verbose>3) printf("      processing Vertices\n");
+			vertices = new GeometricalVertex[nbvx];
+			for (i=0;i<nbv;i++) {
+				vertices[i].r.x=(double)bamggeom->Vertices[i*3+0];
+				vertices[i].r.y=(double)bamggeom->Vertices[i*3+1];
+				vertices[i].ReferenceNumber=(Int4)bamggeom->Vertices[i*3+2];
+				vertices[i].DirOfSearch=NoDirOfSearch;
+				vertices[i].color =0;
+				vertices[i].Set();
+			}
+			//find domain extrema for pmin,pmax
+			pmin =  vertices[0].r;
+			pmax =  vertices[0].r;
+			for (i=0;i<nbv;i++) {
+				pmin.x = Min(pmin.x,vertices[i].r.x);
+				pmin.y = Min(pmin.y,vertices[i].r.y);
+				pmax.x = Max(pmax.x,vertices[i].r.x);
+				pmax.y = Max(pmax.y,vertices[i].r.y);
+			}
+			R2 DD05 = (pmax-pmin)*0.05;
+			pmin -=  DD05;
+			pmax +=  DD05;
+			coefIcoor= (MaxICoor)/(Max(pmax.x-pmin.x,pmax.y-pmin.y));
+			if(coefIcoor <=0){
+				throw ErrorException(__FUNCT__,exprintf("coefIcoor should be positive"));
+			}
+		}
+		else{
+			throw ErrorException(__FUNCT__,exprintf("No Vertex provided"));
+		}
+
+		//Edges
+		if (bamggeom->Edges){
+			int i1,i2;
+			R2 zero2(0,0);
+			Real4 *len =0;
+
+			if(verbose>3) printf("      processing Edges\n");
+			edges = new GeometricalEdge[nbe];
+
+			if (!hvertices) {
+				len = new Real4[nbv];
+				for(i=0;i<nbv;i++)
+				 len[i]=0;
+			}
+
+			for (i=0;i<nbe;i++){
+				i1=(int)bamggeom->Edges[i*3+0]-1; //-1 for C indexing
+				i2=(int)bamggeom->Edges[i*3+1]-1; //-1 for C indexing
+				edges[i].ref=(Int4)bamggeom->Edges[i*3+2];
+				edges[i].v[0]=  vertices + i1;
+				edges[i].v[1]=  vertices + i2;
+				R2 x12 = vertices[i2].r-vertices[i1].r;
+				Real8 l12=sqrt((x12,x12));
+				edges[i].tg[0]=zero2;
+				edges[i].tg[1]=zero2;
+				edges[i].SensAdj[0] = edges[i].SensAdj[1] = -1;
+				edges[i].Adj[0] = edges[i].Adj[1] = 0;
+				edges[i].flag = 0;
+				if (!hvertices) {
+					vertices[i1].color++;
+					vertices[i2].color++;
+					len[i1] += l12;
+					len[i2] += l12;
+				}
+
+				Hmin = Min(Hmin,l12);
+			}
+
+			// definition  the default of the given mesh size 
+			if (!hvertices){
+				for (i=0;i<nbv;i++) 
+				 if (vertices[i].color > 0) 
+				  vertices[i].m=  Metric(len[i] /(Real4) vertices[i].color);
+				 else 
+				  vertices[i].m=  Metric(Hmin);
+				delete [] len;
+			}
+		}
+		else{
+			throw ErrorException(__FUNCT__,exprintf("No edges provided"));
+		}
+
+		//hVertices
+		if(bamggeom->hVertices){
+			if(verbose>3) printf("      processing hVertices\n");
+			for (i=0;i< nbv;i++){
+				vertices[i].m=Metric((Real4)bamggeom->hVertices[i]);
+			}
+		}
+		else{
+			if(verbose>3) printf("      no hVertices found\n");
+		}
+
+		//MetricVertices
+		if(bamggeom->MetricVertices){
+			if(verbose>3) printf("      processing MetricVertices\n");
+			hvertices=1;
+			for (i=0;i< nbv;i++) {
+				vertices[i].m = Metric((Real4)bamggeom->MetricVertices[i*3+0],(Real4)bamggeom->MetricVertices[i*3+1],(Real4)bamggeom->MetricVertices[i*3+2]);
+			}
+		}
+		else{
+			if(verbose>3) printf("      no MetricVertices found\n");
+		}
+
+		//h1h2VpVertices
+		if(bamggeom->h1h2VpVertices){
+			if(verbose>3) printf("      processing h1h2VpVertices\n");
+			Real4 h1,h2,v1,v2;
+			hvertices =1;
+			for (i=0;i< nbv;i++) {
+				h1=(Real4)bamggeom->MetricVertices[i*4+0];
+				h2=(Real4)bamggeom->MetricVertices[i*4+1];
+				v1=(Real4)bamggeom->MetricVertices[i*4+2];
+				v2=(Real4)bamggeom->MetricVertices[i*4+3];
+				vertices[i].m = Metric(MatVVP2x2(1/(h1*h1),1/(h2*h2),D2(v1,v2)));
+			}
+		}
+		else{
+			if(verbose>3) printf("      no h1h2VpVertices found\n");
+		}
+
+		//MaximalAngleOfCorner
+		if (bamgopts->MaximalAngleOfCorner){
+			if(verbose>3) printf("      processing MaximalAngleOfCorner\n");
+			MaximalAngleOfCorner=bamgopts->MaximalAngleOfCorner*Pi/180;
+		}
+		else{
+			if(verbose>3) printf("      no MaximalAngleOfCorner found\n");
+		}
+
+		//TangentAtEdges
+		if (bamggeom->TangentAtEdges){
+			if(verbose>3) printf("      processing TangentAtEdges");
+			int n,i,j,k;
+			R2 tg;
+
+			n=bamggeom->NumTangentAtEdges;
+			for (k=0;k<n;k++) {
+				i=(int)bamggeom->TangentAtEdges[k*4+0]-1; //for C indexing
+				j=(int)bamggeom->TangentAtEdges[k*4+1]-1; //for C indexing
+				tg.x=bamggeom->TangentAtEdges[k*4+2];
+				tg.y=bamggeom->TangentAtEdges[k*4+3];
+				if (j!=0 && j!=1){
+					throw ErrorException(__FUNCT__,exprintf("TangentAtEdges second index should be 1 or 2 only"));
+				}
+				edges[i].tg[j] = tg;
+			}
+		}
+		else{
+			if(verbose>3) printf("      no TangentAtEdges found\n");
+		}
+
+		//Corners
+		if(bamggeom->Corners){
+			if(verbose>3) printf("      processing Corners");
+			n=bamggeom->NumCorners;
+			for (i=0;i<n;i++) {     
+				j=(int)bamggeom->Corners[i]-1; //for C indexing
+				if (j>nbv-1 || j<0){
+					throw ErrorException(__FUNCT__,exprintf("Bad corner definition: should in [0 %i]",nbv));
+				}
+				vertices[j].SetCorner();
+				vertices[j].SetRequired();  }
+		}
+		else{
+			if(verbose>3) printf("      no Corners found\n");
+		}
+
+		//RequiredVertices
+		if(bamggeom->RequiredVertices){
+			if(verbose>3) printf("      processing RequiredVertices");
+			n=bamggeom->NumRequiredVertices;
+			for (i=0;i<n;i++) {     
+				j=(int)bamggeom->RequiredVertices[i]-1; //for C indexing
+				if (j>nbv-1 || j<0){
+					throw ErrorException(__FUNCT__,exprintf("Bad RequiredVerticess  definition: should in [0 %i]",nbv));
+				}
+				vertices[j].SetRequired();  }
+		}
+		else{
+			if(verbose>3) printf("      no RequiredVertices found\n");
+		}
+
+		//RequiredEdges
+		if(bamggeom->RequiredEdges){
+			if(verbose>3) printf("      processing RequiredEdges");
+			n=bamggeom->NumRequiredEdges;
+			for (i=0;i<n;i++) {     
+				j=(int)bamggeom->RequiredEdges[i]-1; //for C indexing
+				if (j>nbe-1 || j<0){
+					throw ErrorException(__FUNCT__,exprintf("Bad RequiredEdges definition: should in [0 %i]",nbv));
+				}
+				edges[j].SetRequired();  }
+		}
+		else{
+			if(verbose>3) printf("      no RequiredEdges found\n");
+		}
+
+		//SubDomain
+		if(bamggeom->SubDomains){
+			Int4 i0,i1,i2,i3;
+			if(verbose>3) printf("      processing SubDomains\n");
+			NbSubDomains=bamggeom->NumSubDomains;
+			subdomains = new GeometricalSubDomain[NbSubDomains];
+			for (i=0;i<NbSubDomains;i++) {
+				i0=(int)bamggeom->SubDomains[i*4+0];
+				i1=(int)bamggeom->SubDomains[i*4+1];
+				i2=(int)bamggeom->SubDomains[i*4+2];
+				i3=(int)bamggeom->SubDomains[i*4+3];
+				if (i0!=2) throw ErrorException(__FUNCT__,exprintf("Bad Subdomain definition: first number should be 2 (for Edges)"));
+				if (i1>nbe || i1<=0) throw ErrorException(__FUNCT__,exprintf("Bad Subdomain definition: second number should in [1 %i] (edge number)",nbe));
+				subdomains[i].edge=edges + (i1-1);
+				subdomains[i].sens = (int) i2;
+				subdomains[i].ref = i3;
+			}
+		}
+		else{
+			if(verbose>3) printf("      no SubDomains found\n");
+		}
+	}
+	/*}}}1*/
+
+	/*Other*/
+
+void Geometry::EmptyGeometry()  // empty geometry
+  {
+  OnDisk=0;
+  NbRef=0;
+  name =0;
+  quadtree=0;
+  curves=0;
+ // edgescomponante=0;
+  triangles=0;
+  edges=0;
+  vertices=0;
+  NbSubDomains=0;
+  //  nbtf=0;
+//  BeginOfCurve=0;  
+  nbiv=nbv=nbvx=0;
+  nbe=nbt=nbtx=0;
+  NbOfCurves=0;
+//  BeginOfCurve=0;
+  subdomains=0;
+  MaximalAngleOfCorner = 10*Pi/180;
+  }
+
+
+
+Geometry::Geometry(const Geometry & Gh)
+ { Int4 i;
+   *this = Gh;
+   NbRef =0;
+   quadtree=0;
+   name = new char[strlen(Gh.name)+4];
+   strcpy(name,"cp:");
+   strcat(name,Gh.name);
+   vertices = nbv ? new GeometricalVertex[nbv] : NULL;
+   triangles = nbt ? new  Triangle[nbt]:NULL;
+   edges = nbe ? new GeometricalEdge[nbe]:NULL;
+   curves= NbOfCurves ? new Curve[NbOfCurves]:NULL;
+   subdomains = NbSubDomains ? new GeometricalSubDomain[NbSubDomains]:NULL;
+   for (i=0;i<nbv;i++)
+     vertices[i].Set(Gh.vertices[i],Gh,*this);
+   for (i=0;i<nbe;i++)
+     edges[i].Set(Gh.edges[i],Gh,*this);
+   for (i=0;i<NbOfCurves;i++)
+     curves[i].Set(Gh.curves[i],Gh,*this);
+   for (i=0;i<NbSubDomains;i++)
+     subdomains[i].Set(Gh.subdomains[i],Gh,*this);
+     
+   //    for (i=0;i<nbt;i++)
+   //      triangles[i].Set(Gh.triangles[i],Gh,*this);
+   assert(!nbt);   
+ }
+
+
+GeometricalEdge* Geometry::Contening(const R2 P,  GeometricalEdge * start) const
+{
+  GeometricalEdge* on =start,* pon=0;
+  // walk with the cos on geometry
+  //  cout << P ;
+  int k=0;
+   while(pon != on)
+     {  
+       pon = on;
+       assert(k++<100);
+       R2 A= (*on)[0];
+       R2 B= (*on)[1];
+       R2 AB = B-A;
+       R2 AP = P-A;
+       R2 BP = P-B;
+       //   cout << "::  " << on - edges << " "  <<  AB*AP  << " " <<  AB*BP << " " << A << B << endl;
+       if ( (AB,AP) < 0) 
+	 on = on->Adj[0];
+       else if ( (AB,BP)  > 0) 
+	 on = on->Adj[1];
+       else
+	 return on;
+     }
+   return on;
+}
+GeometricalEdge* Geometry::ProjectOnCurve(const Edge & e,Real8 s,Vertex &V,VertexOnGeom &GV ) const 
+ {  
+    Real8 save_s=s;
+    int NbTry=0;
+retry:    
+    s=save_s;
+    GeometricalEdge * on = e.on;
+    assert(on);
+    assert( e[0].on &&  e[1].on);
+    const Vertex &v0=e[0],&v1=e[1];
+    V.m = Metric(1.0-s, v0,s, v1);
+#define MXE__LINE  __LINE__+1
+    const int mxe =100;
+    GeometricalEdge *ge[mxe+1];
+    int    sensge[mxe+1];
+    Real8  lge[mxe+1];
+    int bge=mxe/2,tge=bge;
+    ge[bge] = e.on;
+    sensge[bge]=1;
+
+    R2 V0 = v0,V1=v1,V01=V1-V0;
+    VertexOnGeom  vg0= *v0.on,  vg1=*v1.on;
+    if(NbTry) cout << "bug: s==== " << s << " e=" <<  V0 << " " << V1 << endl;
+
+    //    GeometricalEdge * eg0 = e.on,* eg1 = e.on, *eg=NULL;
+    GeometricalEdge * eg0=on, *eg1=on;
+    R2 Ag=(R2) (*on)[0],Bg=(R2)(*on)[1],AB=Bg-Ag; 
+    if(NbTry) cout <<" G edge= " << Ag << Bg << endl << " v edge" << V01 << " v geom " << AB  <<  (V01,AB) <<endl; 
+    int OppositeSens = (V01,AB) < 0;
+    int sens0=0,sens1=1;
+    if (OppositeSens)
+      s=1-s,Exchange(vg0,vg1),Exchange(V0,V1);
+    if(NbTry) cout << "bug: edge = " << v0.r << " -> " << v1.r << endl 
+		   << "sg 0 = " << vg0 
+		   << " on = " << Number(on) << ":" << Ag << Bg << "; " 
+		   <<  " sg 1= " << vg1 
+		   << "--------------------------------------------" << endl;
+    while (eg0 != (GeometricalEdge*) vg0  &&  (*eg0)(sens0) != (GeometricalVertex*) vg0)
+      { 
+      if (bge<=0) {
+	//          int kkk;
+          // if (NbTry) cout <<"Read (int) to Show Sioux window", cin >> kkk ;
+	       if(NbTry) 
+	          {
+		    cerr << " -- Fatal Error: on the class triangles before call Geometry::ProjectOnCurve" << endl; 
+		    cerr << "   The mesh of the  Geometry is to fine: ";
+		    cerr << "     1)  a mesh edge  contening more than "<< mxe/2 << " geometrical edges." << endl;
+		    cerr << "     2)  code bug : be sure that we call   Triangles::SetVertexFieldOn() before " << endl;
+		    cerr << "   To solve the problem do a coarsening of the geometrical mesh " << endl;
+		    cerr << " or change the constant value of mxe in " << __FILE__ << " line " << MXE__LINE << "( dangerous way )" << endl;	  
+		    MeshError(222);
+		  }
+	    NbTry++;
+	    goto retry;}
+        GeometricalEdge* tmpge = eg0;
+	 if(NbTry)
+		cout << "bug: --Edge @" <<  Number(tmpge)  << " = "<< Number(eg0) << ":" <<Number(eg0->Adj[0]) << "," <<  
+			 Number(eg0->Adj[1]) <<"," ;
+	ge[--bge] =eg0 = eg0->Adj[sens0];
+	assert(bge>=0 && bge <= mxe);
+	sens0 = 1-( sensge[bge] = tmpge->SensAdj[sens0]);
+	if(NbTry)
+		cout << "bug: Edge "  <<  Number(eg0) << " "<< 1-sens0 <<  " S "
+		     << Number((*eg0)[1-sens0]) <<":" << Number(eg0->Adj[0]) << "," 
+		     <<  Number(eg0->Adj[1]) <<"," << endl
+	 	     <<Number(eg0)<< (*eg0)[sens0].r << "v = " << Number((*eg1)(sens0)) << " e = " << eg0 <<  endl;
+     }
+      if(NbTry) cout << Number((GeometricalEdge*) vg1) << " " << Number((GeometricalVertex*) vg1) << endl;
+    while (eg1 != (GeometricalEdge*) vg1  &&  (*eg1)(sens1) != (GeometricalVertex*) vg1)
+      { 
+        if(tge>=mxe ) { 
+	  cerr << " --Fatal Error: on the class triangles before call Geometry::ProjectOnCurve" << endl; 
+	  NbTry++;
+	  if (NbTry<2) goto retry;
+	  cerr << "   The mesh of the  Geometry is to fine:" ;
+	  cerr << "     1)  a mesh edge  contening more than "<< mxe/2 << " geometrical edges." << endl;
+	  cerr << "     2)  code bug : be sure that we call   Triangles::SetVertexFieldOn() before " << endl;
+	  cerr << "   To solve the problem do a coarsening of the geometrical mesh " << endl;
+	  cerr << " or change the constant value of mxe in " << __FILE__ << " line " << MXE__LINE << "( dangerous way )" << endl;	
+	  MeshError(223);
+	}
+
+	GeometricalEdge* tmpge = eg1;
+	if(NbTry)
+		cout << "++Edge @" << tmpge << " = " <<  Number(eg1) <<"%" << Number(eg1->Adj[0]) << "," 
+		 <<  Number(eg1->Adj[1]) <<"," ;
+	ge[++tge] =eg1 = eg1->Adj[sens1];
+	sensge[tge]= sens1 = 1-tmpge->SensAdj[sens1];
+	assert(tge>=0 && tge <= mxe);
+         if(NbTry)
+		cout << "  Edge "  <<  Number(eg1) << " " << sens1 << " S "
+		     <<Number((*eg1)[sens1]) <<"%"<< Number(eg1->Adj[0]) << "," <<  Number(eg1->Adj[1]) <<"," 
+	             <<Number(eg1)<< (*eg1)[sens1].r << "v = " << Number((*eg1)(sens1)) << " e = " << Number(eg1) <<  endl;
+      }
+
+    	if(NbTry)    cout << endl;
+        
+
+    if ( (*eg0)(sens0) == (GeometricalVertex*) vg0 )
+      vg0 = VertexOnGeom( *(Vertex *) vg0,*eg0,sens0);
+    
+    if ( (*eg1)(sens1) == (GeometricalVertex*) vg1)
+       vg1 = VertexOnGeom( *(Vertex *) vg1,*eg1,sens1);
+
+    Real8 sg;
+    //   cout << "           " << Number(on) << " " <<  Number(eg0) << " " <<  Number(eg1) << " "  ; 
+    if (eg0 == eg1) { 
+       register Real8 s0= vg0,s1=vg1;
+       sg =  s0 * (1.0-s) +  s * s1;
+       //    cout <<"                s0=" << s0 << " s1=" << s1 
+       //             << " s = " << s << " sens= " << OppositeSens << "\t\t sg = " << sg << endl ;
+       on=eg0;}
+    else {
+       R2 AA=V0,BB;
+       Real8 s0,s1;
+       
+       //cout << endl << "s= " << s << Number(eg0) << " " << (Real8) vg0 << " " 
+       //	    << Number(eg1) << " " << (Real8) vg1 << V0 << V1 << "  Interpol = " 
+       // << V0*(1-s)+V1*s << ";;; " <<  endl;
+       int i=bge;
+       Real8 ll=0;
+       for(i=bge;i<tge;i++) 
+	 {
+	   assert( i>=0 && i <= mxe);
+	   BB =  (*ge[i])[sensge[i]];
+	   lge[i]=ll += Norme2(AA-BB);
+	   //   cout << " ll " << i << BB << ll << " " <<sensge[i] <<" on = " <<
+	   // Number(ge[i]) << " sens= " << sensge[i] ;
+	   AA=BB ;}
+       lge[tge]=ll+=Norme2(AA-V1); 
+       // cout << " ll " << tge << " " << ll <<  sensge[tge] 
+       //	     <<" on = " << Number(ge[tge]) <<  " sens= " << sensge[tge] << endl;
+    // search the geometrical edge
+      assert(s <= 1.0);
+      Real8 ls= s*ll;
+      on =0;
+      s0 = vg0;
+      s1= sensge[bge];
+      Real8 l0=0,l1;
+      i=bge;
+      while (  (l1=lge[i]) < ls ) {
+	assert(i >= 0 && i <= mxe);
+	i++,s0=1-(s1=sensge[i]),l0=l1;}
+      on=ge[i];
+      if (i==tge) 
+	s1=vg1;
+     
+      s=(ls-l0)/(l1-l0);
+      //  cout << "on =" << Number(on) << sens0 << sens1 <<  "s0  " << s0 << " s1 =" 
+      //	     << s1 << " l0 =" << l0 << " ls= " << ls << " l1= " << l1 << " s= " << s;
+       sg =  s0 * (1.0-s) +  s * s1;    
+       } 
+    assert(on);
+    // assert(sg && sg-1);
+    V.r= on->F(sg);
+    //  if (eg0 != eg1) 
+    //        cout << "----- sg = "<< sg << " Sens =" << OppositeSens << " Edge = " 
+    //     << Number(on) <<"  V=" << V << endl;
+    GV=VertexOnGeom(V,*on,sg);
+    return on;
+ }
+
+void Geometry::AfterRead()
+ {// -----------------
+	 long int verbosity=0;
+
+    if (verbosity>20)
+    cout << "Geometry::AfterRead()" <<  nbv << " " << nbe << endl;
+    Int4 i,k=0;        ;
+    int jj; // jj in [0,1]
+    Int4 * hv = new Int4 [ nbv];
+    Int4 * ev = new Int4 [ 2 * nbe ];
+    float  * eangle = new float[ nbe ];
+    {
+      double eps = 1e-20;
+      QuadTree quadtree; // to find same vertices
+      Vertex * v0 = vertices; 
+      GeometricalVertex  * v0g = (GeometricalVertex  *) (void *) v0;   
+      int k=0;
+      for (i=0;i<nbv;i++) 
+        vertices[i].link = vertices +i;
+      for (i=0;i<nbv;i++) 
+	     {
+	      vertices[i].i = toI2(vertices[i].r); // set integer coordinate
+	      Vertex *v= quadtree.NearestVertex(vertices[i].i.x,vertices[i].i.y); 
+	      if( v && Norme1(v->r - vertices[i]) < eps )
+	       { // link v & vertices[i] 
+	         // vieille ruse pour recuperer j 
+	         GeometricalVertex * vg = (GeometricalVertex  *) (void *) v;
+	         int j = vg-v0g;
+	         assert( v ==  & (Vertex &) vertices[j]);
+	         vertices[i].link = vertices + j;
+            k++;	      
+	       }
+	      else  quadtree.Add(vertices[i]); 
+	     }
+      if (k) {
+	cout << " Number of distinte vertices " << nbv - k << " Over " << nbv << endl;
+	//if (verbosity>10) 
+	{
+	  cout << " The duplicate vertex " << endl;
+	  for (i=0;i<nbv;i++)
+	    if (!vertices[i].IsThe())
+	      cout << " " << i << " and " << Number(vertices[i].The()) << endl;
+	  MeshError(102);
+	  //throw(ErrorExec("exit",1));    
+	}
+      }
+      
+      //  verification of cracked edge
+      int err =0;
+      for (i=0;i<nbe;i++)
+	if (edges[i].Cracked() )
+	  {
+	    //    verification of crack
+	    GeometricalEdge & e1=edges[i];
+	    GeometricalEdge & e2=*e1.link;
+            cerr << i << " " << e1[0].The() << " " << e2[0].The() << " " <<  e1[1].The() << " " << e2[1].The() << endl;
+	    if ( e1[0].The() == e2[0].The() && e1[1].The() == e2[1].The() )
+	      {
+	      }
+	    else 
+	      if ( e1[0].The() == e2[1].The() && e1[1].The() == e2[0].The() )
+		{
+		}
+	      else
+		{
+		  err++;
+		  cerr << " Cracked edges with no same vertex " << &e1-edges << " " << &e2 -edges << endl;
+		}
+	  }
+	else
+	  {
+	    //  if (!edges[i][0].IsThe()) err++;
+	    // if (!edges[i][1].IsThe()) err++;
+	  }
+      if (err)
+	{
+	  cerr << " Some vertex was not distint and not on cracked edge " << err<< endl;
+	  MeshError(222);
+	}
+    }
+    if(verbosity>7) 
+      for (i=0;i<nbv;i++)
+	if (vertices[i].Required())
+	  cout << "     The geo vertices  " << i << " is required" << endl;
+
+    for (i=0;i<nbv;i++) 
+      hv[i]=-1;// empty list
+
+    for (i=0;i<nbe;i++) 
+      {
+        R2 v10  =  edges[i].v[1]->r -  edges[i].v[0]->r;
+        Real8 lv10 = Norme2(v10);
+        if(lv10 == 0) {
+          cerr << "The length  of " <<i<< "th Egde is 0 " << endl ;
+          MeshError(1);}
+        eangle[i] = atan2(v10.y,v10.x)  ; // angle in [ -Pi,Pi ]
+	if(verbosity>9) 
+	  cout << "     angle edge " << i <<" " << eangle[i]*180/Pi<< v10<<endl;
+        for (jj=0;jj<2;jj++)
+          { // generation of list
+            Int4 v =  Number(edges[i].v[jj]);
+            ev[k] = hv[v];
+            hv[v] = k++;
+          }
+      }
+    // bulle sort on the angle of edge  
+    for (i=0;i<nbv;i++) {
+      int exch = 1,ord =0;      
+      while (exch) {
+        exch = 0;
+        Int4  *p =  hv + i, *po = p;
+	Int4 n = *p;
+        register float angleold = -1000 ; // angle = - infini 
+        ord = 0;
+        while (n >=0) 
+        {
+          ord++;
+          register Int4 i1= n /2;
+          register Int4  j1 = n % 2;
+          register Int4 *pn = ev + n;
+          float angle = j1 ? OppositeAngle(eangle[i1]):  eangle[i1];
+          n = *pn;
+          if (angleold > angle) // exch to have : po -> pn -> p 
+            exch=1,*pn = *po,*po=*p,*p=n,po = pn;
+          else //  to have : po -> p -> pn 
+            angleold =  angle, po = p,p  = pn;
+        }
+      } // end while (exch)
+      
+      if (ord >= 1 ) 
+	{ /*
+	  Int4 n = hv[i];
+	  while ( n >=0) 
+	    { Int4 i1 = n/2,j1 = n%2;
+	    //float a = 180*(j1 ? OppositeAngle(eangle[i1]): eangle[i1])/Pi;
+	    n = ev[n];
+	    }
+	  */
+	} 
+      if(ord == 2) { // angulare test to find a corner 
+        Int4 n1 = hv[i];
+        Int4 n2 = ev[n1];
+        Int4 i1 = n1 /2, i2 = n2/2; // edge number
+        Int4  j1 = n1 %2, j2 = n2%2; // vertex in the edge 
+        float angle1= j1 ? OppositeAngle(eangle[i1]) :  eangle[i1];
+        float angle2= !j2 ? OppositeAngle(eangle[i2]) :  eangle[i2];
+	float da12 = Abs(angle2-angle1);
+	if(verbosity>9)
+	  cout <<"     check angle " << i << " " << i1 << " " << i2  << " " << 180*(da12)/Pi 
+	       << " " << 180*MaximalAngleOfCorner/Pi << vertices[i] << endl;
+
+        if (( da12 >= MaximalAngleOfCorner ) 
+            && (da12 <= 2*Pi -MaximalAngleOfCorner)) {
+	  vertices[i].SetCorner() ; 
+	  if(verbosity>7)
+	    cout << "     The vertex " << i << " is a corner (angle) " 
+		 << 180*(da12)/ Pi<< " " << 180*MaximalAngleOfCorner/Pi << endl;}
+	// if the ref a changing then is     SetRequired();
+	
+	if (edges[i1].flag != edges[i2].flag || edges[i1].Required()) 
+	 {
+	  vertices[i].SetRequired();
+	  if(verbosity>7)
+	    cout << "     The vertex " << i << " is Required the flag change (crack or equi, or require)" << endl;}
+	  
+	if (edges[i1].ref != edges[i2].ref) {
+	  vertices[i].SetRequired();
+	  if(verbosity>7)
+	    cout << "     The vertex " << i << " is Required ref" << endl;}
+      } ;
+      
+      if(ord != 2) {
+        vertices[i].SetCorner();
+	if(verbosity>7)
+	  cout << "     the vertex " << i << " is a corner ordre = " << ord << endl;
+      }
+      // close the liste around the vertex 
+      { Int4 no=-1, ne = hv[i];
+        while ( ne >=0) 
+                 ne = ev[no=ne];        
+            if(no>=0) 
+              ev[no] = hv[i];
+          } // now the list around the vertex is circular
+      
+    } // end for (i=0;i<nbv;i++)
+ 
+    k =0;
+    for (i=0;i<nbe;i++)
+      for (jj=0;jj<2;jj++){
+            Int4 n1 = ev[k++]; 
+            Int4 i1 = n1/2 ,j1=n1%2;
+            if( edges[i1].v[j1] != edges[i].v[jj]) 
+              { cerr << " Bug Adj edge " << i << " " << jj << 
+                  " et " << i1 << " " << j1 << " k=" << k;
+                cerr << Number(edges[i].v[jj]) <<" <> " 
+                     << Number(edges[i1].v[j1])  <<endl;
+                cerr << "edge " << Number(edges[i].v[0]) << " " 
+                     << Number(edges[i].v[1]) << endl; 
+            //    cerr << "in file " <<filename <<endl;
+                MeshError(1);
+              }
+            edges[i1].Adj[j1] = edges + i;
+            edges[i1].SensAdj[j1] = jj;
+	    if (verbosity>10)
+	      cout << " edges. Adj " << i1 << " " << j1 << " <--- " << i << " " << jj << endl;
+      }
+    
+    // generation of  all the tangente 
+    for (i=0;i<nbe;i++) {
+        R2 AB = edges[i].v[1]->r -edges[i].v[0]->r;        
+	Real8 lAB = Norme2(AB); // length of current edge AB
+        Real8 ltg2[2];
+        ltg2[0]=0;ltg2[1]=0;
+        for (jj=0;jj<2;jj++) {
+             R2 tg =  edges[i].tg[jj];
+             Real8 ltg = Norme2(tg); // length of tg
+             if(ltg == 0) {// no tg
+	       if( ! edges[i].v[jj]->Corner())   { // not a Corner       
+		 tg =  edges[i].v[1-jj]->r 
+		   - edges[i].Adj[jj]->v[1-edges[i].SensAdj[jj]]->r;
+		 ltg =  Norme2(tg);
+		 tg =  tg *(lAB/ltg),ltg=lAB;
+		/*
+		   if(edges[i].ref >=4) 
+		   cout << " tg " << tg.x << " "<< tg.y  << " " << edges[i].v[1-jj]->r << edges[i].Adj[jj]->v[1-edges[i].SensAdj[jj]]->r << " y-y = "
+		     << edges[i].v[1-jj]->r.y -edges[i].Adj[jj]->v[1-edges[i].SensAdj[jj]]->r.y <<  endl;
+		*/
+	       }
+	       
+	       //else ;// a Corner with no tangent => nothing to do    
+             } // a tg 
+             else 
+               tg = tg *(lAB/ltg),ltg=lAB;
+             ltg2[jj] = ltg;
+             if ( (tg,AB) < 0) 
+               tg = -tg;
+	    //if(edges[i].ref >=4) cout << " tg = " << tg << endl;
+             edges[i].tg[jj] = tg;
+	}     // for (jj=0;jj<2;jj++) 
+	
+	if (ltg2[0]!=0) edges[i].SetTgA();
+	if (ltg2[1]!=0) edges[i].SetTgB();
+    } // for (i=0;i<nbe;i++)
+
+    if(verbosity>7)
+      for (i=0;i<nbv;i++)
+	if (vertices[i].Required())
+	  cout << "     The  geo  vertices " << i << " is required " << endl;
+  
+   for (int step=0;step<2;step++)
+   {
+    for (i=0;i<nbe;i++) 
+      edges[i].SetUnMark();
+    
+    NbOfCurves = 0;
+    Int4  nbgem=0;
+    for (int level=0;level < 2 && nbgem != nbe;level++)
+      for (i=0;i<nbe;i++) {
+	GeometricalEdge & ei = edges[i];   
+	for(jj=0;jj<2;jj++) 
+	  if (!ei.Mark() && (level || ei[jj].Required())) { 
+	    // warning ei.Mark() can be change in loop for(jj=0;jj<2;jj++) 
+	    int k0=jj,k1;
+	    GeometricalEdge *e = & ei;
+	    GeometricalVertex *a=(*e)(k0); // begin 
+	    if(curves) {
+	      curves[NbOfCurves].be=e;
+	      curves[NbOfCurves].kb=k0;
+	    }
+	    int nee=0;
+	    for(;;) { 
+		nee++;
+	      k1 = 1-k0; // next vertex of the edge 
+	      e->SetMark();
+	      nbgem++;
+	      e->CurveNumber=NbOfCurves;
+	      if(curves) {
+	      curves[NbOfCurves].ee=e;
+	      curves[NbOfCurves].ke=k1;
+	      }
+	      
+	      GeometricalVertex *b=(*e)(k1);
+	      if (a == b ||  b->Required() ) break;
+	      k0 = e->SensAdj[k1];//  vertex in next edge
+	      e = e->Adj[k1]; // next edge
+	      
+	    }// for(;;)
+	      if(verbosity>10 && curves==0) cout << NbOfCurves <<" curve :  nb edges=  "<< nee<<  endl; 
+	    NbOfCurves++;
+	    if(level) {
+	      if(verbosity>4)
+		cout << "    Warning: Curve "<< NbOfCurves << " without required vertex " 
+		     << "so the vertex " << Number(a) << " become required " <<endl;
+	      a->SetRequired();
+	    }
+       
+	  }} 
+	  assert(nbgem && nbe);
+
+	  if(step==0) {
+	    curves = new Curve[NbOfCurves];
+	  }
+    	} 
+    for(int i=0;i<NbOfCurves ;i++)
+     {
+       GeometricalEdge * be=curves[i].be, *eqbe=be->link;
+       //GeometricalEdge * ee=curves[i].ee, *eqee=be->link;
+       curves[i].master=true;
+       if(be->Equi() || be->ReverseEqui() ) 
+        {
+          assert(eqbe);
+          int nc = eqbe->CurveNumber;
+          assert(i!=nc);
+          curves[i].next=curves[nc].next;
+          curves[i].master=false;
+          curves[nc].next=curves+i;
+          if(be->ReverseEqui())
+           curves[i].Reverse();           
+        }
+     }
+    	 
+    if(verbosity>3)
+      cout << "    End ReadGeometry: Number of curves in geometry is " << NbOfCurves <<endl; 
+    if(verbosity>4)
+    for(int i=0;i<NbOfCurves ;i++)
+     {
+        cout << " Curve " << i << " begin e=" << Number(curves[i].be) << " k=" << curves[i].kb 
+             << "  end e= " << Number(curves[i].ee) << " k=" << curves[i].ke << endl;
+     }
+    delete []ev;
+    delete []hv;
+    delete []eangle;
+    
+}
+Geometry::~Geometry() 
+{
+	long int verbosity=0;
+
+  assert(NbRef<=0);
+  if(verbosity>9)
+    cout << "DELETE      ~Geometry "<< this  << endl;
+  if(vertices)  delete [] vertices;vertices=0;
+  if(edges)     delete [] edges;edges=0;
+ // if(edgescomponante) delete [] edgescomponante; edgescomponante=0;
+  if(triangles) delete [] triangles;triangles=0;
+  if(quadtree)  delete  quadtree;quadtree=0;
+  if(curves)  delete  []curves;curves=0;NbOfCurves=0;
+  if(name) delete [] name;name=0;
+  if(subdomains) delete [] subdomains;subdomains=0;
+//  if(ordre)     delete [] ordre;
+  EmptyGeometry();
+
+}
+
+
+} 
Index: /issm/trunk/src/c/Bamgx/objects/Triangle.cpp
===================================================================
--- /issm/trunk/src/c/Bamgx/objects/Triangle.cpp	(revision 2820)
+++ /issm/trunk/src/c/Bamgx/objects/Triangle.cpp	(revision 2820)
@@ -0,0 +1,42 @@
+#include <cstdio>
+#include <cstring>
+#include <cmath>
+#include <ctime>
+
+#include "../Mesh2.h"
+#include "../QuadTree.h"
+#include "../SetOfE4.h"
+
+#include "../../shared/shared.h"
+#include "../../include/macros.h"
+#include "../../toolkits/toolkits.h"
+
+namespace bamg {
+
+	/*Others*/
+	/*FUNCTION Triangle::FindBoundaryEdge{{{1*/
+	TriangleAdjacent Triangle::FindBoundaryEdge(int i) const
+	  {
+		// turn around  the vertex ns[i] also call  s
+		Triangle   *t = (Triangle *) this , *ttc;
+		int k=0,j = EdgesVertexTriangle[i][0],jc;
+		int exterieur  = !link  ;
+
+		do 
+		  {
+			int exterieurp = exterieur;
+			k++; 
+			ttc =  t->at[j];
+			exterieur = !ttc->link;
+			if (exterieur+exterieurp == 1) 
+			 return TriangleAdjacent(t,j);
+			jc = NextEdge[t->aa[j]&3];
+			t = ttc;
+			j = NextEdge[jc];
+			assert(k<2000);
+		  } while ( (this!= t)); 
+		return TriangleAdjacent(0,0);
+	  }
+	/*}}}1*/
+
+}
Index: /issm/trunk/src/c/Bamgx/objects/Triangles.cpp
===================================================================
--- /issm/trunk/src/c/Bamgx/objects/Triangles.cpp	(revision 2820)
+++ /issm/trunk/src/c/Bamgx/objects/Triangles.cpp	(revision 2820)
@@ -0,0 +1,5764 @@
+#include <cstdio>
+#include <cstring>
+#include <cmath>
+#include <ctime>
+
+#include "../Mesh2.h"
+#include "../QuadTree.h"
+#include "../SetOfE4.h"
+
+#include "../../shared/shared.h"
+#include "../../include/macros.h"
+#include "../../toolkits/toolkits.h"
+
+namespace bamg {
+
+	static const  Direction NoDirOfSearch=Direction();
+	long NbUnSwap =0;
+
+	/*Constructors/Destructors*/
+	/*FUNCTION Triangles::Triangles(BamgMesh* bamgmesh, BamgOpts* bamgopts){{{1*/
+	Triangles::Triangles(BamgMesh* bamgmesh, BamgOpts* bamgopts):Gh(*(new Geometry())),BTh(*this){ 
+
+		PreInit(0,"none");
+		OnDisk = 1;
+
+		ReadMesh(bamgmesh,bamgopts);
+		SetIntCoor();
+		FillHoleInMesh();
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::Triangles(const Triangles & Tho,const int *flag ,const int *bb){{{1*/
+	Triangles::Triangles(const Triangles & Tho,const int *flag ,const int *bb)
+	  : Gh(*(new Geometry())), BTh(*this) {
+
+		  char cname[] = "trunc";
+
+		  int i,k,itadj;
+		  int kt=0;
+		  int * kk    = new int [Tho.nbv];
+		  Int4 * reft = new Int4[Tho.nbt];
+		  Int4 nbInT =    Tho.ConsRefTriangle(reft);
+		  Int4 * refv = new Int4[Tho.nbv];
+
+		  for (i=0;i<Tho.nbv;i++)
+			kk[i]=-1;
+		  for (i=0;i<Tho.nbv;i++)
+			refv[i]=0;
+		  int nbNewBedge =0;
+		  //  int nbOldBedge =0;  
+		  for (i=0;i<Tho.nbt;i++)
+			if(  reft[i] >=0 && flag[i]) 
+			  {
+				const Triangle & t = Tho.triangles[i];
+				kt++;
+				kk[Tho.Number(t[0])]=1;
+				kk[Tho.Number(t[1])]=1;
+				kk[Tho.Number(t[2])]=1;
+				itadj=Tho.Number(t.TriangleAdj(0));
+				if (  reft[itadj] >=0 && !flag[itadj])
+				  { nbNewBedge++;
+					refv[Tho.Number(t[VerticesOfTriangularEdge[0][0]])]=bb[i];
+					refv[Tho.Number(t[VerticesOfTriangularEdge[0][1]])]=bb[i];
+				  }
+				itadj=Tho.Number(t.TriangleAdj(1));
+				if (  reft[itadj] >=0 && !flag[itadj])
+				  { nbNewBedge++;
+					refv[Tho.Number(t[VerticesOfTriangularEdge[1][0]])]=bb[i];
+					refv[Tho.Number(t[VerticesOfTriangularEdge[1][1]])]=bb[i];}
+					itadj=Tho.Number(t.TriangleAdj(2));
+					if (  reft[itadj] >=0 && !flag[itadj])
+					  { nbNewBedge++;
+						refv[Tho.Number(t[VerticesOfTriangularEdge[2][0]])]=bb[i];
+						refv[Tho.Number(t[VerticesOfTriangularEdge[2][1]])]=bb[i];}
+			  }
+		  k=0;
+		  for (i=0;i<Tho.nbv;i++)
+			if (kk[i]>=0) 
+			 kk[i]=k++;
+		  cout << " number of vertices " << k << " remove = " << Tho.nbv - k << endl;
+		  cout << " number of triangles " << kt << " remove = " << nbInT-kt << endl;
+		  cout << " number of New boundary edge " << nbNewBedge << endl;
+		  Int4 inbvx =k;
+		  PreInit(inbvx,cname);
+		  for (i=0;i<Tho.nbv;i++)
+			if (kk[i]>=0) 
+			  {
+				vertices[nbv] = Tho.vertices[i];
+				if (!vertices[nbv].ref())
+				 vertices[nbv].ReferenceNumber = refv[i];
+				nbv++;
+			  }
+		  assert(inbvx == nbv);
+		  for (i=0;i<Tho.nbt;i++)
+			if(  reft[i] >=0 && flag[i]) 
+			  {
+				const Triangle & t = Tho.triangles[i];
+				int i0 = Tho.Number(t[0]);
+				int i1 = Tho.Number(t[1]);
+				int i2 = Tho.Number(t[2]);
+				assert(i0>=0 && i1 >= 0 && i2  >= 0);
+				assert(i0<Tho.nbv && i1 <Tho.nbv && i2  <Tho.nbv);
+				// cout <<i<< " F" <<  flag[i] << " T " << nbt << "   = " <<  kk[i0] << " " << kk[i1] << " " << kk[i2] ;
+				// cout << " OT  " <<  i0 << " "  << i1 << " " << i2  << " " << reft[i] << endl;
+				triangles[nbt] = Triangle(this,kk[i0],kk[i1],kk[i2]);
+				triangles[nbt].color = Tho.subdomains[reft[i]].ref; 
+				nbt++;           
+			  }
+		  assert(kt==nbt);
+		  if (nbt ==0 && nbv ==0) {
+			  cout << "Error all triangles was remove " << endl;
+			  MeshError(999,this);
+		  }
+		  delete [] kk;
+		  delete [] reft;
+		  delete [] refv;
+		  double cutoffradian = 10.0/180.0*Pi;
+		  ConsGeometry(cutoffradian);
+		  Gh.AfterRead(); 
+		  SetIntCoor();
+		  FillHoleInMesh();
+
+		  assert(NbSubDomains);
+		  assert(subdomains[0].head && subdomains[0].head->link);
+
+	  }
+	/*}}}1*/
+	/*FUNCTION Triangles::~Triangles(){{{1*/
+	Triangles::~Triangles() {
+		long int verbosity=2;
+		//assert(NbRef<=0);
+		if (CurrentTh == this) CurrentTh=0;
+		//if(vertices)  delete [] vertices; //TEST  crash if not commented
+		if(edges)     delete [] edges;
+		if(triangles) delete [] triangles;
+		if(quadtree)  delete  quadtree;
+		//if(ordre)     delete [] ordre; //TEST  crash if not commented
+		if( subdomains) delete []  subdomains;
+		if (VerticesOnGeomEdge) delete [] VerticesOnGeomEdge;
+		if (VerticesOnGeomVertex) delete [] VerticesOnGeomVertex;
+		//if (name) delete [] name; //TEST crash if not commented
+		if (identity) delete [] identity;
+		if (VertexOnBThVertex) delete [] VertexOnBThVertex;
+		if (VertexOnBThEdge) delete [] VertexOnBThEdge;
+
+		if (&Gh) {
+			if (Gh.NbRef>0) Gh.NbRef--;
+			else if (Gh.NbRef==0) delete &Gh;
+		}
+		if (&BTh && (&BTh != this)) {
+			if (BTh.NbRef>0) BTh.NbRef--;
+			else if (BTh.NbRef==0) delete &BTh;
+		}
+		PreInit(0); // set all to zero 
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::Triangles(Triangles & Th,Geometry * pGh,Triangles * pBth,Int4 nbvxx) COPY{{{1*/
+	Triangles::Triangles(Triangles & Th,Geometry * pGh,Triangles * pBth,Int4 nbvxx)
+	  : Gh(*(pGh?pGh:&Th.Gh)), BTh(*(pBth?pBth:this)) {
+		  Gh.NbRef++;
+		  nbvxx = Max(nbvxx,Th.nbv); 
+		  Int4 i;
+		  // do all the allocation to be sure all the pointer existe
+
+		  char * cname = 0;
+		  if (Th.name) 
+			 {
+			  cname = new char[strlen(Th.name)+1];
+			  strcpy(cname,Th.name);
+			 }
+		  PreInit(nbvxx,cname);// to make the allocation 
+		  // copy of triangles
+		  nt=Th.nt;
+		  nbv = Th.nbv;
+		  nbt = Th.nbt;
+		  nbiv = Th.nbiv;
+		  nbe = Th.nbe;
+		  NbSubDomains = Th.NbSubDomains;
+		  NbOutT = Th.NbOutT;
+		  NbOfQuad =  Th.NbOfQuad ;
+		  NbOfSwapTriangle =0;
+		  NbVerticesOnGeomVertex = Th.NbVerticesOnGeomVertex;
+		  if(NbVerticesOnGeomVertex)
+			VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];
+		  NbVerticesOnGeomEdge = Th.NbVerticesOnGeomEdge;
+		  if (NbVerticesOnGeomEdge)
+			VerticesOnGeomEdge = new VertexOnGeom[NbVerticesOnGeomEdge] ;
+		  if (& BTh == & Th.BTh) // same back ground 
+			 {
+			  BTh.NbRef++;
+			  NbVertexOnBThVertex = Th.NbVertexOnBThVertex;
+			  if(NbVertexOnBThVertex)
+				VertexOnBThVertex = new VertexOnVertex[NbVertexOnBThVertex];
+			  NbVertexOnBThEdge = Th.NbVertexOnBThEdge;
+			  if(NbVertexOnBThEdge)
+				VertexOnBThEdge = new VertexOnEdge[NbVertexOnBThEdge];
+			 }
+		  else 
+			 { // no add on back ground mesh 
+			  BTh.NbRef++;
+			  NbVertexOnBThVertex=0;
+			  VertexOnBThVertex=0;
+			  NbVertexOnBThEdge=0;
+			  VertexOnBThEdge=0;
+			  //       assert (& BTh == this); // --- a voir 
+
+			 }
+
+
+		  if(nbe)
+			edges = new Edge[nbe];
+		  if(NbSubDomains)
+			subdomains = new SubDomain[NbSubDomains];
+		  pmin = Th.pmin;
+		  pmax = Th.pmax;
+		  coefIcoor = Th.coefIcoor;
+		  for(i=0;i<nbt;i++)
+			triangles[i].Set(Th.triangles[i],Th,*this);
+		  for(i=0;i<nbe;i++)
+			edges[i].Set(Th,i,*this);
+		  for(i=0;i<nbv;i++)
+			vertices[i].Set(Th.vertices[i],Th,*this);
+		  for(i=0;i<NbSubDomains;i++)  
+			subdomains[i].Set(Th,i,*this);
+		  for (i=0;i<NbVerticesOnGeomVertex;i++)
+			VerticesOnGeomVertex[i].Set(Th.VerticesOnGeomVertex[i],Th,*this);
+		  for (i=0;i<NbVerticesOnGeomEdge;i++)
+			VerticesOnGeomEdge[i].Set(Th.VerticesOnGeomEdge[i],Th,*this);
+		  quadtree=0;
+
+
+		  //  assert(!OutSidesTriangles);
+	  }
+	/*}}}1*/
+
+	/*IO*/
+	/*FUNCTION Triangles::ReadMesh{{{1*/
+	void Triangles::ReadMesh(BamgMesh* bamgmesh, BamgOpts* bamgopts){
+
+		int verbose;
+		Real8 Hmin = HUGE_VAL;// the infinie value 
+		Int4 i1,i2,i3,iref;
+		Int4 i,j;
+		Int4 hvertices =0;
+		Int4 ifgeom=0;
+		Metric M1(1);
+		int Version=1,dim=2;
+
+		verbose=bamgopts->verbose;
+
+		nbv=bamgmesh->NumVertices;
+		nbvx=nbv;
+		nbt=bamgmesh->NumTriangles;
+		nbiv=nbvx;
+
+		//Vertices
+		if(bamgmesh->Vertices){
+			if(verbose>3) printf("      processing Vertices\n");
+
+			vertices=(Vertex*)xmalloc(nbv*sizeof(Vertex));
+			ordre=(Vertex**)xmalloc(nbv*sizeof(Vertex*));
+
+			for (i=0;i<nbv;i++){
+				vertices[i].r.x=bamgmesh->Vertices[i*3+0];
+				vertices[i].r.y=bamgmesh->Vertices[i*3+1];
+				vertices[i].ReferenceNumber=1;
+				vertices[i].DirOfSearch =NoDirOfSearch;
+				vertices[i].m=M1;
+				vertices[i].color=(Int4)bamgmesh->Vertices[i*3+2];
+			}
+			nbtx=2*nbvx-2; // for filling The Holes and quadrilaterals 
+		}
+		else{
+			if(verbose>3) throw ErrorException(__FUNCT__,exprintf("no Vertices found in the initial mesh"));
+		}
+
+		//Triangles
+		if(bamgmesh->Triangles){
+			if(verbose>3) printf("      processing Triangles\n");
+			triangles =new Triangle[nbtx]; //we cannot allocate only nbt triangles since 
+			//other triangles will be added for each edge
+			for (i=0;i<nbt;i++){
+				Triangle & t = triangles[i];
+				i1=(Int4)bamgmesh->Triangles[i*4+0]-1; //for C indexing
+				i2=(Int4)bamgmesh->Triangles[i*4+1]-1; //for C indexing
+				i3=(Int4)bamgmesh->Triangles[i*4+2]-1; //for C indexing
+				t=Triangle(this,i1,i2,i3);
+				t.color=(Int4)bamgmesh->Triangles[i*4+3];
+			}
+		}
+		else{
+			if(verbose>3) throw ErrorException(__FUNCT__,exprintf("no Triangles found in the initial mesh"));
+		}
+
+		//Quadrilaterals
+		if(bamgmesh->Quadrilaterals){
+			if(verbose>3) printf("      processing Quadrilaterals\n");
+			Int4 i1,i2,i3,i4,iref;
+			triangles =new Triangle[nbt];
+			for (i=0;i<bamgmesh->NumQuadrilaterals;i++){
+				Triangle & t1 = triangles[2*i];
+				Triangle & t2 = triangles[2*i+1];
+				i1=(Int4)bamgmesh->Quadrilaterals[i*4+0]-1; //for C indexing
+				i2=(Int4)bamgmesh->Quadrilaterals[i*4+1]-1; //for C indexing
+				i3=(Int4)bamgmesh->Quadrilaterals[i*4+2]-1; //for C indexing
+				i4=(Int4)bamgmesh->Quadrilaterals[i*4+3]-1; //for C indexing
+				t1=Triangle(this,i1,i2,i3);
+				t2=Triangle(this,i3,i4,i1);
+				t1.color=1; //reference = 1 for all triangles since it has not been specified
+				t2.color=1; //reference = 1 for all triangles since it has not been specified
+				t1.SetHidden(OppositeEdge[1]); // two times  because the adj was not created 
+				t2.SetHidden(OppositeEdge[1]); 
+			}
+		}
+		else{
+			if(verbose>3) printf("      no Quadrilaterals found\n");
+		}
+
+		//hVertices
+		if(bamgmesh->hVertices){
+			if(verbose>3) printf("      processing hVertices\n");
+			hvertices=1;
+			for (i=0;i< nbv;i++){
+				vertices[i].m=Metric((Real4)bamgmesh->hVertices[i]);
+			}
+		}
+		else{
+			if(verbose>3) printf("      no hVertices found\n");
+		}
+
+		//VerVerticesOnGeometricEdge
+		if(bamgmesh->VerticesOnGeometricEdge){
+			if(verbose>3) printf("      processing VerticesOnGeometricEdge\n");
+			NbVerticesOnGeomEdge=bamgmesh->NumVerticesOnGeometricEdge;
+			VerticesOnGeomEdge= new  VertexOnGeom[NbVerticesOnGeomEdge] ;
+			for (i=0;i<NbVerticesOnGeomEdge;i++){
+				Int4  i1,i2;
+				Real8 s;
+				i1=(Int4)bamgmesh->VerticesOnGeometricEdge[i*3+0]-1; //for C indexing
+				i2=(Int4)bamgmesh->VerticesOnGeometricEdge[i*3+1]-1; //for C indexing
+				s =(Int4)bamgmesh->VerticesOnGeometricEdge[i*3+2];
+				VerticesOnGeomEdge[i]=VertexOnGeom(vertices[i1],Gh.edges[i2],s);
+			}
+		}
+		else{
+			if(verbose>3) printf("      no VertexOnGeometricEdge found\n");
+		}
+
+		//Edges
+		if (bamgmesh->Edges){
+			int i1,i2;
+			R2 zero2(0,0);
+			Real4 *len =0;
+
+			if(verbose>3) printf("      processing Edges\n");
+			nbe=bamgmesh->NumEdges;
+			edges = new Edge[nbe];
+
+			if (!hvertices) {
+				len = new Real4[nbv];
+				for(i=0;i<nbv;i++)
+				 len[i]=0;
+			}
+
+			for (i=0;i<nbe;i++){
+				i1=(int)bamgmesh->Edges[i*3+0]-1; //-1 for C indexing
+				i2=(int)bamgmesh->Edges[i*3+1]-1; //-1 for C indexing
+				edges[i].v[0]= vertices +i1;
+				edges[i].v[1]= vertices +i2;
+				edges[i].adj[0]=0;
+				edges[i].adj[1]=0;
+				R2 x12 = vertices[i2].r-vertices[i1].r;
+				Real8 l12=sqrt( (x12,x12));        
+
+				if (!hvertices) {
+					vertices[i1].color++;
+					vertices[i2].color++;
+					len[i1]+= l12;
+					len[i2] += l12;
+				}
+				Hmin = Min(Hmin,l12);
+			}
+
+			// definition  the default of the given mesh size 
+			if (!hvertices){
+				for (i=0;i<nbv;i++) 
+				 if (vertices[i].color > 0) 
+				  vertices[i].m=  Metric(len[i] /(Real4) vertices[i].color);
+				 else 
+				  vertices[i].m=  Metric(Hmin);
+				delete [] len;
+			}
+
+			// construction of edges[].adj 
+			for (i=0;i<nbv;i++){ 
+				vertices[i].color = (vertices[i].color ==2) ? -1 : -2;
+			}
+			for (i=0;i<nbe;i++){
+				for (j=0;j<2;j++) { 
+					Vertex *v=edges[i].v[j];
+					Int4 i0=v->color,j0;
+					if(i0==-1){
+						v->color=i*2+j;
+					}
+					else if (i0>=0) {// i and i0 edge are adjacent by the vertex v
+						j0 =  i0%2;
+						i0 =  i0/2;
+						assert( v ==  edges[i0 ].v[j0]);
+						edges[i ].adj[ j ] =edges +i0;
+						edges[i0].adj[ j0] =edges +i ;
+						assert(edges[i0].v[j0] == v);
+						v->color = -3;
+					}
+				}
+			}
+		}
+		else{
+			if(verbose>3) printf("      no Edges found\n");
+		}
+
+		//EdgeOnGeometricEdge
+		if(bamgmesh->EdgesOnGeometricEdge){
+			if(verbose>3) printf("      processing EdgesOnGeometricEdge\n");
+			int i1,i2,i,j;
+			i2=bamgmesh->NumEdgesOnGeometricEdge;
+			for (i1=0;i1<i2;i1++) {
+				i=(int)bamgmesh->EdgesOnGeometricEdge[i*2+0];
+				j=(int)bamgmesh->EdgesOnGeometricEdge[i*2+1];
+				if(!(i>0 && j >0 && i <= nbe && j <= Gh.nbe)) {
+					throw ErrorException(__FUNCT__,exprintf("EdgesOnGeometricEdge error: We must have : (i>0 && j >0 && i <= nbe && j <= Gh.nbe)"));
+				}
+				edges[i-1].on = Gh.edges + j-1;
+			}
+		}
+		else{
+			if(verbose>3) printf("      no EdgesOnGeometricEdge found\n");
+		}
+
+		//SubDomain
+		if(bamgmesh->SubDomains){
+			Int4 i3,head,sens;
+			if(verbose>3) printf("      processing SubDomains\n");
+			NbSubDomains=bamgmesh->NumSubDomains;
+			subdomains = new SubDomain [ NbSubDomains ];
+			for (i=0;i<NbSubDomains;i++) {
+				i3  =(int)bamgmesh->SubDomains[i*3+0];
+				head=(int)bamgmesh->SubDomains[i*3+1]-1;//C indexing
+				sens=(int)bamgmesh->SubDomains[i*3+2];
+				if (i3!=23) throw ErrorException(__FUNCT__,exprintf("Bad Subdomain definition: first number should be 3"));
+				if (head<0 || head>=nbt) throw ErrorException(__FUNCT__,exprintf("Bad Subdomain definition: head should in [1 %i] (triangle number)",nbt));
+				subdomains[i].head = triangles+head;
+			}
+		}
+		else{
+			if(verbose>3) printf("      no SubDomains found\n");
+		}
+
+		/*Recreate geometry if needed*/
+		if(1!=0) {
+			printf("Warning: mesh present but no geometry found. Reconstructing...\n");
+			/*Recreate geometry: */
+			ConsGeometry(bamgopts->MaximalAngleOfCorner*Pi/180);
+			Gh.AfterRead();
+		}
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::WriteMesh {{{1*/
+	void Triangles::WriteMesh(BamgMesh* bamgmesh,BamgOpts* bamgopts){
+
+		int i,j;
+		int verbose;
+
+		verbose=bamgopts->verbose;
+		Int4 *reft = new Int4[nbt];
+		Int4 nbInT = ConsRefTriangle(reft);
+
+		//Vertices
+		if(verbose>3) printf("      writing Vertices\n");
+		bamgmesh->NumVertices=nbv;
+		xfree((void**)&bamgmesh->Vertices);
+		if (nbv){
+			bamgmesh->Vertices=(double*)xmalloc(3*nbv*sizeof(double));
+			for (i=0;i<nbv;i++){
+				bamgmesh->Vertices[i*3+0]=vertices[i].r.x;
+				bamgmesh->Vertices[i*3+1]=vertices[i].r.y;
+				bamgmesh->Vertices[i*3+2]=vertices[i].ref();
+			}
+		}
+		else{
+			bamgmesh->Vertices=NULL;
+		}
+
+		//Edges
+		if(verbose>3) printf("      writing Edges\n");
+		bamgmesh->NumEdges=nbe;
+		xfree((void**)&bamgmesh->Edges);
+		if (nbe){
+			bamgmesh->Edges=(double*)xmalloc(3*nbe*sizeof(double));
+			for (i=0;i<nbe;i++){
+				bamgmesh->Edges[i*3+0]=Number(edges[i][0])+1; //back to M indexing
+				bamgmesh->Edges[i*3+1]=Number(edges[i][1])+1; //back to M indexing
+				bamgmesh->Edges[i*3+2]=edges[i].ref;
+			}
+		}
+		else{
+			bamgmesh->Edges=NULL;
+		}
+
+		//CrackedEdges
+		if(verbose>3) printf("      writing CrackedEdges\n");
+		bamgmesh->NumCrackedEdges=NbCrackedEdges;
+		xfree((void**)&bamgmesh->CrackedEdges);
+		if (NbCrackedEdges){
+			bamgmesh->CrackedEdges=(double*)xmalloc(2*NbCrackedEdges*sizeof(double));
+			for (i=0;i<NbCrackedEdges;i++){
+				bamgmesh->CrackedEdges[i*2+0]=Number(CrackedEdges[i].a.edge)+1; //back to M indexing
+				bamgmesh->CrackedEdges[i*2+1]=Number(CrackedEdges[i].b.edge)+1; //back to M indexing
+			}
+		}
+		else{
+			bamgmesh->CrackedEdges=NULL;
+		}
+
+		//Triangles
+		if(verbose>3) printf("      writing Triangles\n");
+		Int4 k=nbInT-NbOfQuad*2;
+		Int4 num=0;
+		bamgmesh->NumTriangles=k;
+		xfree((void**)&bamgmesh->Triangles);
+		if (k){
+			bamgmesh->Triangles=(double*)xmalloc(4*k*sizeof(double));
+			for (i=0;i<nbt;i++){
+				Triangle &t=triangles[i];
+				if (reft[i]>=0 && !( t.Hidden(0) || t.Hidden(1) || t.Hidden(2) )){
+					bamgmesh->Triangles[num*4+0]=Number(t[0])+1; //back to M indexing
+					bamgmesh->Triangles[num*4+1]=Number(t[1])+1; //back to M indexing
+					bamgmesh->Triangles[num*4+2]=Number(t[2])+1; //back to M indexing
+					bamgmesh->Triangles[num*4+3]=subdomains[reft[i]].ref;
+					num=num+1;
+				}
+			}
+		}
+		else{
+			bamgmesh->Triangles=NULL;
+		}
+
+		//Quadrilaterals
+		if(verbose>3) printf("      writing Quadrilaterals\n");
+		bamgmesh->NumQuadrilaterals=NbOfQuad;
+		xfree((void**)&bamgmesh->Quadrilaterals);
+		if (NbOfQuad){
+			bamgmesh->Quadrilaterals=(double*)xmalloc(5*NbOfQuad*sizeof(double));
+			for (i=0;i<nbt;i++){
+				Triangle &t =triangles[i];
+				Triangle* ta;
+				Vertex *v0,*v1,*v2,*v3;
+				if (reft[i]<0) continue;
+				if ((ta=t.Quadrangle(v0,v1,v2,v3)) !=0 && &t<ta) { 
+					bamgmesh->Quadrilaterals[i*5+0]=Number(v0)+1; //back to M indexing
+					bamgmesh->Quadrilaterals[i*5+1]=Number(v1)+1; //back to M indexing
+					bamgmesh->Quadrilaterals[i*5+2]=Number(v2)+1; //back to M indexing
+					bamgmesh->Quadrilaterals[i*5+3]=Number(v3)+1; //back to M indexing
+					bamgmesh->Quadrilaterals[i*5+4]=subdomains[reft[i]].ref;
+				}
+			}
+		}
+		else{
+			bamgmesh->Quadrilaterals=NULL;
+		}
+
+		//SubDomains
+		if(verbose>3) printf("      writing SubDomains\n");
+		bamgmesh->NumSubDomains=NbSubDomains;
+		xfree((void**)&bamgmesh->SubDomains);
+		if (NbSubDomains){
+			bamgmesh->SubDomains=(double*)xmalloc(4*NbSubDomains*sizeof(double));
+			for (i=0;i<NbSubDomains;i++){
+				bamgmesh->SubDomains[i*4+0]=3;
+				bamgmesh->SubDomains[i*4+1]=reft[Number(subdomains[i].head)];
+				bamgmesh->SubDomains[i*4+2]=1;
+				bamgmesh->SubDomains[i*4+3]=subdomains[i].ref;
+			}
+		}
+		else{
+			bamgmesh->SubDomains=NULL;
+		}
+
+		//SubDomainsFromGeom
+		if(verbose>3) printf("      writing SubDomainsFromGeom\n");
+		bamgmesh->NumSubDomainsFromGeom=Gh.NbSubDomains;
+		xfree((void**)&bamgmesh->SubDomainsFromGeom);
+		if (Gh.NbSubDomains){
+			bamgmesh->SubDomainsFromGeom=(double*)xmalloc(4*Gh.NbSubDomains*sizeof(double));
+			for (i=0;i<Gh.NbSubDomains;i++){
+				bamgmesh->SubDomainsFromGeom[i*4+0]=2;
+				bamgmesh->SubDomainsFromGeom[i*4+1]=Number(subdomains[i].edge)+1; //back to Matlab indexing
+				bamgmesh->SubDomainsFromGeom[i*4+2]=subdomains[i].sens;
+				bamgmesh->SubDomainsFromGeom[i*4+3]=Gh.subdomains[i].ref;
+			}
+		}
+		else{
+			bamgmesh->SubDomainsFromGeom=NULL;
+		}
+
+		//VerticesOnGeomVertex
+		if(verbose>3) printf("      writing VerticesOnGeometricVertex\n");
+		bamgmesh->NumVerticesOnGeometricVertex=NbVerticesOnGeomVertex;
+		xfree((void**)&bamgmesh->VerticesOnGeometricVertex);
+		if (NbVerticesOnGeomVertex){
+			bamgmesh->VerticesOnGeometricVertex=(double*)xmalloc(2*NbVerticesOnGeomVertex*sizeof(double));
+			for (i=0;i<NbVerticesOnGeomVertex;i++){
+				VertexOnGeom &v=VerticesOnGeomVertex[i];
+				if (!v.OnGeomVertex()){
+					throw ErrorException(__FUNCT__,exprintf("A vertices supposed to be OnGeometricVertex is actually not"));
+				}
+				bamgmesh->VerticesOnGeometricVertex[i*2+0]=Number((Vertex*)v)+1; //back to Matlab indexing
+				bamgmesh->VerticesOnGeometricVertex[i*2+1]=Gh.Number(( GeometricalVertex*)v)+1; //back to Matlab indexing
+			}
+		}
+		else{
+			bamgmesh->VerticesOnGeometricVertex=NULL;
+		}
+
+		//VertexOnGeometricEdge
+		if(verbose>3) printf("      writing VerticesOnGeometricEdge\n");
+		bamgmesh->NumVerticesOnGeometricEdge=NbVerticesOnGeomEdge;
+		xfree((void**)&bamgmesh->VerticesOnGeometricEdge);
+		if (NbVerticesOnGeomEdge){
+			bamgmesh->VerticesOnGeometricEdge=(double*)xmalloc(3*NbVerticesOnGeomEdge*sizeof(double));
+			for (i=0;i<NbVerticesOnGeomEdge;i++){
+				const VertexOnGeom &v=VerticesOnGeomEdge[i];
+				if (!v.OnGeomEdge()){
+					throw ErrorException(__FUNCT__,exprintf("A vertices supposed to be OnGeometricEdge is actually not"));
+				}
+				bamgmesh->VerticesOnGeometricEdge[i*3+0]=Number((Vertex*)v)+1; //back to Matlab indexing
+				bamgmesh->VerticesOnGeometricEdge[i*3+1]=Gh.Number((const GeometricalEdge*)v)+1; //back to Matlab indexing
+				bamgmesh->VerticesOnGeometricEdge[i*3+2]=(double)v;
+			}
+		}
+		else{
+			bamgmesh->VerticesOnGeometricEdge=NULL;
+		}
+
+		//EdgesOnGeometricEdge
+		if(verbose>3) printf("      writing EdgesOnGeometricEdge\n");
+		k=0;
+		for (i=0;i<nbe;i++){
+			if (edges[i].on) k=k+1;
+		}
+		bamgmesh->NumEdgesOnGeometricEdge=k;
+		xfree((void**)&bamgmesh->EdgesOnGeometricEdge);
+		if (k){
+			bamgmesh->EdgesOnGeometricEdge=(double*)xmalloc(2*(int)k*sizeof(double));
+			int count=0;
+			for (i=0;i<nbe;i++){
+				if (edges[i].on){
+					bamgmesh->EdgesOnGeometricEdge[count*2+0]=(double)i+1; //back to Matlab indexing
+					bamgmesh->EdgesOnGeometricEdge[count*2+1]=(double)Gh.Number(edges[i].on)+1; //back to Matlab indexing
+					count=count+1;
+				}
+			}
+		}
+		else{
+			bamgmesh->EdgesOnGeometricEdge=NULL;
+		}
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::ReadMetric{{{1*/
+	void Triangles::ReadMetric(BamgOpts* bamgopts,const Real8 hmin1=1.0e-30,const Real8 hmax1=1.0e30,const Real8 coef=1) {
+		int  i,j;
+
+		if(bamgopts->verbose>3) printf("      processing metric\n");
+
+		Real8 hmin = Max(hmin1,MinimalHmin());
+		Real8 hmax = Min(hmax1,MaximalHmax());
+
+		//for now we only use j==3
+		j=3;
+
+		for (i=0;i<nbv;i++){
+			Real8 h;
+			if (j == 1){
+				h=bamgopts->metric[i];
+				vertices[i].m=Metric(Max(hmin,Min(hmax, h*coef)));
+			}
+			else if (j==3){
+				Real8 a,b,c;	     
+				a=bamgopts->metric[i*3+0];
+				b=bamgopts->metric[i*3+1];
+				c=bamgopts->metric[i*3+2];
+				MetricAnIso M(a,b,c);
+				MatVVP2x2 Vp(M/coef);
+
+				Vp.Maxh(hmin);
+				Vp.Minh(hmax);
+				vertices[i].m = Vp;
+			}
+		}
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::WriteMetric{{{1*/
+	void Triangles::WriteMetric(BamgOpts* bamgopts) {
+		int i;
+		xfree((void**)&bamgopts->metric);
+		if (bamgopts->iso){
+			bamgopts->metric=(double*)xmalloc(1*nbv*sizeof(double));
+			for (i=0;i<nbv;i++){
+				MatVVP2x2 V=vertices[i].m;
+				bamgopts->metric[i]=V.hmin();
+			}
+		}
+		else {
+			bamgopts->metric=(double*)xmalloc(3*nbv*sizeof(double));
+			for (i=0;i<nbv;i++){
+				bamgopts->metric[i*3+0]=vertices[i].m.a11;
+				bamgopts->metric[i*3+1]=vertices[i].m.a21;
+				bamgopts->metric[i*3+2]=vertices[i].m.a22;
+			}
+		}
+	}
+	/*}}}1*/
+
+	/*Others*/
+	/*FUNCTION Triangles::ConsGeometry{{{1*/
+	void Triangles::ConsGeometry(Real8 cutoffradian,int *equiedges) // construct a geometry if no geo 
+	  {
+		//  if equiedges existe taille nbe 
+		//   equiedges[i]/2 == i  original
+		//   equiedges[i]/2 = j  =>   equivalence entre i et j => meme maillage
+		//   equiedges[i]%2   : 0 meme sens , 1 pas meme sens 
+		//       
+		// --------------------------
+		long int verbosity=0;
+		if (verbosity>1) 
+		 cout << "  -- construction of the geometry from the 2d mesh " << endl;
+		if (nbt<=0 || nbv <=0 ) { MeshError(101);}
+
+		// construction of the edges 
+		//  Triangles * OldCurrentTh =CurrentTh;
+		CurrentTh=this;
+		//  Int4 NbTold = nbt;
+		// generation of the integer coor
+		// generation of the adjacence of the triangles
+		if (cutoffradian>=0)
+		 Gh.MaximalAngleOfCorner = cutoffradian;
+		SetOfEdges4 * edge4= new SetOfEdges4(nbt*3,nbv);
+		Int4 * st = new Int4[nbt*3];
+		Int4 i,k;
+		int j; 
+		if (Gh.name) delete Gh.name;
+		Gh.name = new char [ name ? strlen(name) + 15 : 50 ];
+		Gh.name[0]=0;
+		strcat(Gh.name,"cons from: ");
+		if (name) strcat(Gh.name,name);
+		else strcat(Gh.name," a mesh with no name");
+		for (i=0;i<nbt*3;i++)
+		 st[i]=-1;
+		Int4 kk =0;
+
+		Int4 nbeold = nbe;
+		for (i=0;i<nbe;i++)
+		  {
+			//      cout << i << " " << Number(edges[i][0]) << " " << Number(edges[i][1]) << endl;
+			edge4->addtrie(Number(edges[i][0]),Number(edges[i][1]));
+		  }
+		if (nbe !=  edge4->nb())
+		  { 
+			cerr << " Some Double edge in the mesh, the number is " << nbe 
+			  << " nbe4=" << edge4->nb()  << endl;
+			MeshError(1002);
+		  }
+		for (i=0;i<nbt;i++)
+		 for  (j=0;j<3;j++)
+			{
+			 // Int4 i0,i1;
+			 Int4 k =edge4->addtrie(Number(triangles[i][VerticesOfTriangularEdge[j][0]]),
+						 Number(triangles[i][VerticesOfTriangularEdge[j][1]]));
+			 Int4 invisible = triangles[i].Hidden(j);
+			 if(st[k]==-1)
+			  st[k]=3*i+j;
+			 else if(st[k]>=0) {
+				 assert( ! triangles[i].TriangleAdj(j) && !triangles[st[k] / 3].TriangleAdj((int) (st[k]%3)));
+
+				 triangles[i].SetAdj2(j,triangles + st[k] / 3,(int) (st[k]%3));
+				 if (invisible)  triangles[i].SetHidden(j);
+				 if (k<nbe) {
+					 triangles[i].SetLocked(j);
+				 }
+				 st[k]=-2-st[k]; }
+			 else {
+				 cerr << " The edge (" 
+					<< Number(triangles[i][VerticesOfTriangularEdge[j][0]])
+					<< " , " 
+					<< Number(triangles[i][VerticesOfTriangularEdge[j][1]])
+					<< " ) is in more than 2 triangles " <<k <<endl;
+				 cerr << " Edge " << j << " Of Triangle " << i << endl;
+				 cerr << " Edge " << (-st[k]+2)%3 << " Of Triangle " << (-st[k]+2)/3  << endl;
+				 cerr << " Edge " << triangles[(-st[k]+2)/3].NuEdgeTriangleAdj((int)((-st[k]+2)%3))
+					<< " Of Triangle " <<  Number(triangles[(-st[k]+2)/3].TriangleAdj((int)((-st[k]+2)%3))) 
+					<< endl;
+				 MeshError(9999);}	
+
+
+			}
+		Int4 nbedges = edge4->nb(); // the total number of edges 
+		delete edge4;
+		edge4 =0;
+
+		if(verbosity>5) {
+			if (name)
+			 cout << "    On Mesh " << name << endl;
+			cout << "    - The number of Vertices  = " << nbv << endl;
+			cout << "    - The number of Triangles = " << nbt << endl;
+			cout << "    - The number of given edge = " << nbe << endl;
+			cout << "    - The number of all edges = " << nbedges << endl;
+			cout << "    - The Euler number = 1-Nb Of Hole = " << nbt-nbedges+nbv << endl; }
+
+
+			// check the consistant of edge[].adj and the geometrical required  vertex
+			k=0;
+			kk=0;
+			Int4 it;
+
+			for (i=0;i<nbedges;i++)
+			 if (st[i] <-1) // edge internal
+				{ 
+				 it =  (-2-st[i])/3;
+				 j  =  (int) ((-2-st[i])%3);
+				 Triangle & tt = * triangles[it].TriangleAdj(j);
+				 //cout << it << " c="  << triangles[it].color <<  " " << Number(tt) << " c="  << tt.color << endl;
+				 if (triangles[it].color != tt.color|| i < nbeold) // Modif FH 06122055 // between 2 sub domai
+				  k++;
+				}
+			 else if (st[i] >=0) // edge alone 
+			  // if (i >= nbeold) 
+			  kk++;
+
+			if(verbosity>4 && (k+kk) )
+			 cout << "    Nb of  ref edge " << kk+k << " (internal " << k << ")"
+				<< " in file " << nbe  << endl;
+			k += kk;
+			kk=0;
+			if (k)
+			  {
+
+				//      if (nbe) {
+				//	cerr << k << " boundary edges  are not defined as edges " << endl;
+				//	MeshError(9998);
+				// }
+				// construction of the edges 
+				nbe = k;
+				Edge * edgessave = edges;
+				edges = new Edge[nbe];
+				k =0;
+				// construction of the edges 
+				if(verbosity>4)
+				 cout << "    Construction of the edges  " << nbe << endl;
+
+				for (i=0;i<nbedges;i++)
+				  { 
+					Int4  add= -1;
+
+					if (st[i] <-1) // edge internal
+					  { 
+						it =  (-2-st[i])/3;
+						j  =  (int) ((-2-st[i])%3);
+						Triangle & tt = * triangles[it].TriangleAdj(j);
+						if (triangles[it].color !=  tt.color || i < nbeold) // Modif FH 06122055
+						 add=k++;
+					  }
+					else if (st[i] >=0) // edge alone 
+					  {
+						it = st[i]/3;
+						j  = (int) (st[i]%3);
+						add=k++;
+					  }
+
+					if (add>=0 && add < nbe)
+					  {
+
+						edges[add].v[0] = &triangles[it][VerticesOfTriangularEdge[j][0]];
+						edges[add].v[1] = &triangles[it][VerticesOfTriangularEdge[j][1]];
+						edges[add].on=0; 
+						if (i<nbeold) // in file edge // Modif FH 06122055 
+						  {
+							edges[add].ref = edgessave[i].ref; 		      
+							edges[add].on = edgessave[i].on; //  HACK pour recuperer les aretes requise midf FH avril 2006 ???? 
+						  }
+						else
+						 edges[add].ref = Min(edges[add].v[0]->ref(),edges[add].v[1]->ref()); // no a good choice
+					  }
+				  }
+				assert(k==nbe);
+				if (edgessave) delete [] edgessave;
+			  }
+
+			// construction of edges[].adj 
+			for (i=0;i<nbv;i++) 
+			 vertices[i].color =0;
+			for (i=0;i<nbe;i++)
+			 for (j=0;j<2;j++) 
+			  edges[i].v[j]->color++;
+
+			for (i=0;i<nbv;i++) 
+			 vertices[i].color = (vertices[i].color ==2) ? -1 : -2;
+			for (i=0;i<nbe;i++)
+			 for (j=0;j<2;j++) 
+				{ 
+				 Vertex *v=edges[i].v[j];
+				 Int4 i0=v->color,j0;
+				 if(i0<0)
+				  edges[i ].adj[ j ]=0;  // Add FH Jan 2008   
+				 if(i0==-1)
+				  v->color=i*2+j;
+				 else if (i0>=0) {// i and i0 edge are adjacent by the vertex v
+					 j0 =  i0%2;
+					 i0 =  i0/2;
+					 assert( v ==  edges[i0 ].v[j0]);
+					 edges[i ].adj[ j ] =edges +i0;
+					 edges[i0].adj[ j0] =edges +i ;
+					 assert(edges[i0].v[j0] == v);
+					 //	    if(verbosity>8)
+					 //  cout << " edges adj " << i0 << " "<< j0 << " <-->  "  << i << " " << j << endl;
+					 v->color = -3;}
+				}
+			// now reconstruct the sub domain info 
+			assert(!NbSubDomains);
+			NbSubDomains=0;
+
+			  { 
+				Int4 it;
+				// find all the sub domain
+				Int4 *colorT = new Int4[nbt];
+				Triangle *tt,*t;
+				Int4 k;
+				for ( it=0;it<nbt;it++)
+				 colorT[it]=-1;
+				for (it=0;it<nbt;it++)
+				  {
+					if (colorT[it]<0) 
+					  {
+						colorT[it]=NbSubDomains;
+						Int4 level =1,j,jt,kolor=triangles[it].color;
+						st[0]=it; // stack 
+						st[1]=0;
+						k=1;
+						while (level>0)
+						 if( ( j=st[level]++) <3)
+							{ 
+							 t = &triangles[st[level-1]];
+							 tt=t->TriangleAdj((int)j);
+
+							 if ( ! t->Locked(j) && tt && (colorT[jt = Number(tt)] == -1) && ( tt->color==kolor))
+								{
+								 colorT[jt]=NbSubDomains;
+								 st[++level]=jt;
+								 st[++level]=0;
+								 k++;
+								}
+							}
+						 else 
+						  level-=2;
+						if (verbosity>5) 
+						 cout << "   Nb of triangles " << k << " of Subdomain "  
+							<<  NbSubDomains << " " << kolor << endl;
+						NbSubDomains++;
+					  }
+				  }
+				if (verbosity> 3)
+				 cout << "   The Number of sub domain = " << NbSubDomains << endl;
+
+				Int4 isd;
+				subdomains = new SubDomain[NbSubDomains];
+				for (isd=0;isd<NbSubDomains;isd++)
+				  {
+					subdomains[isd].head =0;
+				  }
+				k=0;
+				for (it=0;it<nbt;it++)
+				 for (int j=0;j<3;j++)
+					{
+					 tt=triangles[it].TriangleAdj(j);
+					 if ((!tt || tt->color != triangles[it].color) && !subdomains[isd=colorT[it]].head)
+						{
+						 subdomains[isd].head = triangles+it;
+						 subdomains[isd].ref =  triangles[it].color;
+						 subdomains[isd].sens = j; // hack
+						 subdomains[isd].edge = 0;
+						 k++;
+						}
+					}  
+				assert(k== NbSubDomains);
+
+				delete [] colorT;
+
+
+			  }      
+			delete [] st;
+			// now make the geometry
+			// 1 compress the vertices 
+			Int4 * colorV = new Int4[nbv];
+			for (i=0;i<nbv;i++) 
+			 colorV[i]=-1;
+			for (i=0;i<nbe;i++)
+			 for ( j=0;j<2;j++)
+			  colorV[Number(edges[i][j])]=0;
+			k=0;
+			for (i=0;i<nbv;i++) 
+			 if(!colorV[i])
+			  colorV[i]=k++;
+
+			Gh.nbv=k;
+			Gh.nbe = nbe;
+			Gh.vertices = new GeometricalVertex[k];
+			Gh.edges = new GeometricalEdge[nbe];
+			Gh.NbSubDomains = NbSubDomains;
+			Gh.subdomains = new GeometricalSubDomain[NbSubDomains];
+			if (verbosity>3)
+			 cout << "    Nb of  vertices  = " << Gh.nbv << " Nb of edges = " << Gh.nbe << endl;
+			NbVerticesOnGeomVertex = Gh.nbv;
+			VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];
+			NbVerticesOnGeomEdge =0;
+			VerticesOnGeomEdge =0;
+			  {
+				Int4 j;
+				for (i=0;i<nbv;i++) 
+				 if((j=colorV[i])>=0)
+					{
+
+					 Vertex & v = Gh.vertices[j];
+					 v = vertices[i];
+					 v.color =0;
+					 VerticesOnGeomVertex[j] = VertexOnGeom(vertices[i], Gh.vertices[j]);
+					}
+
+			  }
+			edge4= new SetOfEdges4(nbe,nbv);  
+
+			Real4 * len = new Real4[Gh.nbv];
+			for(i=0;i<Gh.nbv;i++)
+			 len[i]=0;
+
+			Gh.pmin =  Gh.vertices[0].r;
+			Gh.pmax =  Gh.vertices[0].r;
+			// recherche des extrema des vertices pmin,pmax
+			for (i=0;i<Gh.nbv;i++) {
+				Gh.pmin.x = Min(Gh.pmin.x,Gh.vertices[i].r.x);
+				Gh.pmin.y = Min(Gh.pmin.y,Gh.vertices[i].r.y);
+				Gh.pmax.x = Max(Gh.pmax.x,Gh.vertices[i].r.x);
+				Gh.pmax.y = Max(Gh.pmax.y,Gh.vertices[i].r.y);
+			}
+
+			R2 DD05 = (Gh.pmax-Gh.pmin)*0.05;
+			Gh.pmin -=  DD05;
+			Gh.pmax +=  DD05;
+
+			Gh.coefIcoor= (MaxICoor)/(Max(Gh.pmax.x-Gh.pmin.x,Gh.pmax.y-Gh.pmin.y));
+			assert(Gh.coefIcoor >0);
+
+			Real8 hmin = HUGE_VAL;
+			int kreq=0;
+			for (i=0;i<nbe;i++)
+			  {
+				Int4 i0 = Number(edges[i][0]);
+				Int4 i1 = Number(edges[i][1]);
+				Int4 j0 =	 colorV[i0];
+				Int4 j1 =  colorV[i1];
+
+				Gh.edges[i].v[0] = Gh.vertices +  j0;
+				Gh.edges[i].v[1] = Gh.vertices +  j1;
+				Gh.edges[i].flag = 0;
+				Gh.edges[i].tg[0]=R2();
+				Gh.edges[i].tg[1]=R2();
+				bool requis= edges[i].on; 
+				if(requis) kreq++;
+				edges[i].on =  Gh.edges + i;
+				if(equiedges && i < nbeold ) {
+					int j=equiedges[i]/2;
+					int sens=equiedges[i]%2;
+					if(i!=j && equiedges[i]>=0) {
+						if(verbosity>9)  
+						 cout << " Edges Equi " << i << " <=> " << j << " sens = " << sens  << endl;
+						if( sens==0)
+						 Gh.edges[i].SetEqui();
+						else 
+						 Gh.edges[i].SetReverseEqui();
+						Gh.edges[i].link= & Gh.edges[j];
+						//assert(sens==0);//  meme sens pour l'instant
+					}
+
+				}
+				if(requis)  {  // correction fevr 2009 JYU ...
+					Gh.edges[i].v[0]->SetRequired();
+					Gh.edges[i].v[1]->SetRequired();
+					Gh.edges[i].SetRequired(); // fin modif ... 
+				}
+				R2 x12 = Gh.vertices[j0].r-Gh.vertices[j1].r;
+				Real8 l12=Norme2(x12);        
+				hmin = Min(hmin,l12);
+
+				Gh.vertices[j1].color++;
+				Gh.vertices[j0].color++;
+
+				len[j0]+= l12;
+				len[j1] += l12;
+				hmin = Min(hmin,l12);
+
+				Gh.edges[i].ref  = edges[i].ref;
+
+				k = edge4->addtrie(i0,i1);
+
+				assert(k == i);
+
+			  }
+
+
+			for (i=0;i<Gh.nbv;i++) 
+			 if (Gh.vertices[i].color > 0) 
+			  Gh.vertices[i].m=  Metric(len[i] /(Real4) Gh.vertices[i].color);
+			 else 
+			  Gh.vertices[i].m=  Metric(hmin);
+			delete [] len;
+			for (i=0;i<NbSubDomains;i++)
+			  {
+				Int4 it = Number(subdomains[i].head);
+				int j = subdomains[i].sens;
+				Int4 i0 = Number(triangles[it][VerticesOfTriangularEdge[j][0]]);
+				Int4 i1 = Number(triangles[it][VerticesOfTriangularEdge[j][1]]);
+				k = edge4->findtrie(i0,i1);
+				if(k>=0)
+				  {
+					subdomains[i].sens = (vertices + i0 == edges[k].v[0]) ? 1 : -1;
+					subdomains[i].edge = edges+k;
+					Gh.subdomains[i].edge = Gh.edges + k;
+					Gh.subdomains[i].sens  =  subdomains[i].sens;
+					Gh.subdomains[i].ref =  subdomains[i].ref;
+				  }
+				else
+				 MeshError(103);
+			  }
+
+			delete edge4;
+			delete [] colorV;
+			//  -- unset adj
+			for (i=0;i<nbt;i++)
+			 for ( j=0;j<3;j++)
+			  triangles[i].SetAdj2(j,0,triangles[i].GetAllflag(j));
+
+	  }
+	/*}}}1*/
+	/*FUNCTION Triangles::ProjectOnCurve{{{1*/
+	GeometricalEdge*   Triangles::ProjectOnCurve( Edge & BhAB, Vertex &  vA, Vertex & vB,
+				Real8 theta,Vertex & R,VertexOnEdge &  BR,VertexOnGeom & GR) {
+		void *pA=0,*pB=0;
+		Real8 tA=0,tB=0;
+		R2 A=vA,B=vB;
+		Vertex * pvA=&vA, * pvB=&vB;
+		if (vA.vint == IsVertexOnVertex)
+		  {
+			//  cout << " Debut vertex = " << BTh.Number(vA.onbv) ;
+			pA=vA.onbv;
+		  }
+		else if (vA.vint == IsVertexOnEdge)
+		  {
+			pA=vA.onbe->be;
+			tA=vA.onbe->abcisse;
+			// cout << " Debut edge = " << BTh.Number(vA.onbv) << " " << tA ;
+
+		  }
+		else
+		  {cerr << "ProjectOnCurve On Vertex " << BTh.Number(vA) << " " << endl;
+			cerr << " forget call to SetVertexFieldOnBTh" << endl;
+			MeshError(-1);
+		  } 
+
+		if (vB.vint == IsVertexOnVertex)
+		  {
+			// cout << " Fin vertex = " << BTh.Number(vB.onbv) << endl;
+			pB=vB.onbv;
+		  }
+		else if(vB.vint == IsVertexOnEdge)
+		  {
+			pB=vB.onbe->be;
+			tB=vB.onbe->abcisse;
+			// cout << " Fin edge = " << BTh.Number(vB.onbe->be) << " " <<  tB ;
+
+		  }
+		else
+		  {cerr << "ProjectOnCurve On Vertex " << BTh.Number(vB) << " " << endl;
+			cerr << " forget call to SetVertexFieldOnBTh" << endl;
+			MeshError(-1);
+		  } 
+		Edge * e = &BhAB;
+		assert( pA && pB && e);
+		// be carefull the back ground edge e is on same geom edge 
+		// of the initiale edge def by the 2 vertex A B;
+		assert(e>=BTh.edges && e<BTh.edges+BTh.nbe);// Is a background Mesh;   
+		// walk on BTh edge 
+		//assert(0 /* not finish ProjectOnCurve with BackGround Mesh*/);
+		// 1 first find a back ground edge contening the vertex A
+		// 2 walk n back gound boundary to find the final vertex B
+
+		if( vA.vint == IsVertexOnEdge) 
+		  { // find the start edge 
+			e = vA.onbe->be;	 
+
+		  } 
+		else if (vB.vint == IsVertexOnEdge) 
+		  {
+			theta = 1-theta;
+			Exchange(tA,tB);
+			Exchange(pA,pB);
+			Exchange(pvA,pvB);
+			Exchange(A,B);
+			e =  vB.onbe->be;
+
+			// cout << " EXCHANGE  A et B) " << endl;
+		  } 
+		else
+		  { // do the search by walking 
+			assert(0 /* A FAIRE */);
+		  }
+
+		// find the direction of walking with sens of edge and pA,PB;
+		R2 AB=B-A;
+
+		Real8 cosE01AB = (( (R2) (*e)[1] - (R2) (*e)[0] ) , AB);
+		int kkk=0;
+		int sens = (cosE01AB>0) ? 1 : 0;
+
+		//   Real8 l=0; // length of the edge AB
+		Real8 abscisse = -1;
+
+		for (int cas=0;cas<2;cas++)
+		  {// 2 times algo:
+			//    1 for computing the length l
+			//    2 for find the vertex 
+			int  iii;
+			Vertex  *v0=pvA,*v1; 
+			Edge *neee,*eee;
+			Real8 lg =0; // length of the curve 
+			Real8 te0;
+			// we suppose take the curve's abcisse 
+			// cout << kkk << " e = " << BTh.Number(e) << "  v0=  " 
+			//    << BTh.Number(v0) << " v1 = " << BTh.Number((*e)[sens]) << endl;
+			for ( eee=e,iii=sens,te0=tA;
+						eee && ((( void*) eee) != pB) && (( void*) (v1=&((*eee)[iii]))) != pB ;
+						neee = eee->adj[iii],iii = 1-neee->Intersection(*eee),eee = neee,v0=v1,te0=1-iii )   
+			  { 
+				//	cout << kkk << " eee = " << BTh.Number(eee) << "  v0=  " 
+				//     << BTh.Number(v0) << " v1 = " << BTh.Number(v1) << endl;
+
+				assert(kkk++<100);
+				assert(eee);
+				Real8 lg0 = lg;
+				Real8 dp = LengthInterpole(v0->m,v1->m,(R2) *v1 - (R2) *v0);
+				lg += dp;
+				if (cas && abscisse <= lg)
+				  { // ok we find the geom edge 
+					Real8 sss  =   (abscisse-lg0)/dp;
+					Real8 thetab = te0*(1-sss)+ sss*iii;
+					assert(thetab>=0 && thetab<=1);
+					BR = VertexOnEdge(&R,eee,thetab);
+
+					// cout << Number(R) << " = " <<  thetab << " on  " <<  BTh.Number(eee)
+					//	 << " = " << R << endl;
+
+					return  Gh.ProjectOnCurve(*eee,thetab,R,GR);
+
+				  }
+			  }
+			// we find the end 
+			if (v1 != pvB) 
+			  {
+				if (( void*) v1 == pB)
+				 tB = iii;
+
+				Real8 lg0 = lg;
+				assert(eee);
+				v1 = pvB;
+				Real8 dp = LengthInterpole(v0->m,v1->m,(R2) *v1 - (R2) *v0);
+				lg += dp;	
+				abscisse = lg*theta;
+				if (abscisse <= lg && abscisse >= lg0 ) // small optimisation we know the lenght because end
+				  { // ok we find the geom edge 
+					Real8 sss  =   (abscisse-lg0)/dp;
+					Real8 thetab = te0*(1-sss)+ sss*tB;
+					assert(thetab>=0 && thetab<=1);
+					BR = VertexOnEdge(&R,eee,thetab);
+
+					//	cout << kkk << " eee = " << BTh.Number(eee) << "  v0=  " 
+					//     << BTh.Number(v0) << " " << te0
+					//      << " v1 = " << BTh.Number(v1) <<  " " << tB  << endl;
+
+					//out << Number(R) << " Opt  = " <<  thetab << " on  " <<  BTh.Number(eee) 
+					//	    << " = " << R << endl;
+
+					return  Gh.ProjectOnCurve(*eee,thetab,R,GR);
+				  }
+			  }
+			abscisse = lg*theta;
+
+		  }
+		cerr << " Big Bug" << endl;
+		MeshError(678);
+		return 0; // just for the compiler 
+
+	}                  
+	/*}}}1*/
+	/*FUNCTION Triangles::MakeQuadrangles{{{1*/
+	void Triangles::MakeQuadrangles(double costheta){
+		long int verbosity=0;
+
+		if (verbosity>2) 
+		 cout << "  -- MakeQuadrangles costheta = " << costheta << endl;
+		if (verbosity>5)  
+		 cout << "    (in)  Nb of Quadrilaterals = " << NbOfQuad 
+			<< " Nb Of Triangles = " << nbt-NbOutT- NbOfQuad*2 
+			<< " Nb of outside triangles = " << NbOutT << endl;
+
+		if (costheta >1) {
+			if (verbosity>5)
+			 cout << "     do nothing costheta >1 "<< endl;
+			return;}
+
+
+			Int4 nbqq = (nbt*3)/2;
+			DoubleAndInt4  *qq = new DoubleAndInt4[nbqq];
+
+			Int4 i,ij;
+			int j;
+			Int4 k=0;
+			for (i=0;i<nbt;i++)
+			 for (j=0;j<3;j++)
+			  if ((qq[k].q=triangles[i].QualityQuad(j))>=costheta)
+				qq[k++].i3j=i*3+j;
+			//  sort  qq
+			HeapSort(qq,k);
+
+			Int4 kk=0;
+			for (ij=0;ij<k;ij++)
+			  { 
+				//      cout << qq[ij].q << " " << endl;
+				i=qq[ij].i3j/3;
+				j=(int) (qq[ij].i3j%3);
+				// optisamition no float computation  
+				if (triangles[i].QualityQuad(j,0) >=costheta) 
+				 triangles[i].SetHidden(j),kk++;
+			  }
+			NbOfQuad = kk;
+			if (verbosity>2) 
+			  {
+				cout << "    (out)  Nb of Quadrilaterals = " << NbOfQuad 
+				  << " Nb Of Triangles = " << nbt-NbOutT- NbOfQuad*2 
+				  << " Nb of outside triangles = " << NbOutT << endl;
+			  }
+			delete [] qq;
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::SplitElement{{{1*/
+	int  Triangles::SplitElement(int choice){
+		long int verbosity=0;
+
+		Direction NoDirOfSearch;
+		const  int withBackground = &BTh != this && &BTh;
+		if (verbosity>2) 
+		 cout << "  -- SplitElement " << (choice? " Q->4Q and T->4T " : " Q->4Q or T->3Q " ) << endl;;
+		if (verbosity>5)
+		 cout << endl << "    (in)  Nb of Quadrilaterals = " << NbOfQuad 
+			<< " Nb Of Triangles = " << nbt-NbOutT- NbOfQuad*2 
+			<< " Nb of outside triangles = " << NbOutT << endl;
+
+		ReNumberingTheTriangleBySubDomain();
+		//int nswap =0;
+		const Int4 nfortria( choice ? 4 : 6);
+		if(withBackground) 
+		  {
+			BTh.SetVertexFieldOn();
+			SetVertexFieldOnBTh();
+		  }
+		else
+		 BTh.SetVertexFieldOn();
+
+		Int4 newnbt=0,newnbv=0;
+		Int4 * kedge = 0;
+		Int4 newNbOfQuad=NbOfQuad;
+		Int4 * ksplit= 0, * ksplitarray=0;
+		Int4 kkk=0;
+		int ret =0;
+		if (nbvx<nbv+nbe) return 1;//   
+		Triangles *  OCurrentTh= CurrentTh;
+		CurrentTh = this;
+		// 1) create  the new points by spliting the internal edges 
+		// set the 
+		Int4 nbvold = nbv;
+		Int4 nbtold = nbt;
+		Int4 NbOutTold  = NbOutT;
+		Int4  NbEdgeOnGeom=0;
+		Int4 i;
+
+		nbt = nbt - NbOutT; // remove all the  the ouside triangles 
+		Int4 nbtsave = nbt;
+		Triangle * lastT = triangles + nbt;
+		for (i=0;i<nbe;i++)
+		 if(edges[i].on) NbEdgeOnGeom++;
+		Int4 newnbe=nbe+nbe;
+		//  Int4 newNbVerticesOnGeomVertex=NbVerticesOnGeomVertex;
+		Int4 newNbVerticesOnGeomEdge=NbVerticesOnGeomEdge+NbEdgeOnGeom;
+		// Int4 newNbVertexOnBThVertex=NbVertexOnBThVertex;
+		Int4 newNbVertexOnBThEdge=withBackground ? NbVertexOnBThEdge+NbEdgeOnGeom:0;
+
+		// do allocation for pointeur to the geometry and background
+		VertexOnGeom * newVerticesOnGeomEdge = new VertexOnGeom[newNbVerticesOnGeomEdge];
+		VertexOnEdge *newVertexOnBThEdge = newNbVertexOnBThEdge ?  new VertexOnEdge[newNbVertexOnBThEdge]:0;
+		if (NbVerticesOnGeomEdge)
+		 memcpy(newVerticesOnGeomEdge,VerticesOnGeomEdge,sizeof(VertexOnGeom)*NbVerticesOnGeomEdge);
+		if (NbVertexOnBThEdge)
+		 memcpy(newVertexOnBThEdge,VertexOnBThEdge,sizeof(VertexOnEdge)*NbVertexOnBThEdge);
+		Edge *newedges = new Edge [newnbe];
+		//  memcpy(newedges,edges,sizeof(Edge)*nbe);
+		SetOfEdges4 * edge4= new SetOfEdges4(nbe,nbv);
+		Int4 k=nbv;
+		Int4 kk=0;
+		Int4 kvb = NbVertexOnBThEdge;
+		Int4 kvg = NbVerticesOnGeomEdge;
+		Int4 ie =0;
+		Edge ** edgesGtoB=0;
+		if (withBackground)
+		 edgesGtoB= BTh.MakeGeometricalEdgeToEdge();
+		Int4 ferr=0;
+		for (i=0;i<nbe;i++)
+		 newedges[ie].on=0;
+
+		for (i=0;i<nbe;i++)
+		  {
+			GeometricalEdge *ong =  edges[i].on;
+
+			newedges[ie]=edges[i];
+			newedges[ie].adj[0]=newedges+(edges[i].adj[0]-edges) ;
+			newedges[ie].adj[1]=newedges + ie +1;
+			R2 A = edges[i][0],B = edges[i][1];
+			// cout << " ie = " << ie <<"  v0 = " <<  Number(newedges[ie][0]) << endl;
+
+
+			kk += (i == edge4->addtrie(Number(edges[i][0]),Number(edges[i][1])));
+			if (ong) // a geometrical edges 
+			  { 
+				if (withBackground)
+				  {
+					// walk on back ground mesh 
+					//  newVertexOnBThEdge[ibe++] = VertexOnEdge(vertices[k],bedge,absicsseonBedge); 
+					// a faire -- difficile 
+					// the first PB is to now a background edge between the 2 vertices
+					assert(edgesGtoB); 
+					// cout << " ie = " << ie <<"  v0 = " <<  Number(newedges[ie][0]) << endl;
+					ong= ProjectOnCurve(*edgesGtoB[Gh.Number(edges[i].on)],
+								edges[i][0],edges[i][1],0.5,vertices[k],
+								newVertexOnBThEdge[kvb],
+								newVerticesOnGeomEdge[kvg++]);
+					vertices[k].ReferenceNumber= edges[i].ref;
+					vertices[k].DirOfSearch =   NoDirOfSearch;        
+					;
+					// get the Info on background mesh 
+					Real8 s =        newVertexOnBThEdge[kvb];
+					Vertex &  bv0  = newVertexOnBThEdge[kvb][0];
+					Vertex &  bv1  = newVertexOnBThEdge[kvb][1];
+					// compute the metrix of the new points 
+					vertices[k].m =  Metric(1-s,bv0,s,bv1); 
+					kvb++;
+					// cout << " ie = " << ie <<"  v0 = " <<  Number(newedges[ie][0]) << endl;
+				  }
+				else 
+				  {
+					ong=Gh.ProjectOnCurve(edges[i],
+								0.5,vertices[k],newVerticesOnGeomEdge[kvg++]);
+					// vertices[k].i = toI2( vertices[k].r);
+					vertices[k].ReferenceNumber = edges[i].ref;
+					vertices[k].DirOfSearch = NoDirOfSearch;
+					vertices[k].m =  Metric(0.5,edges[i][0],0.5,edges[i][1]);	      
+				  }  
+			  }
+			else // straigth line edge ---
+			  { 
+				vertices[k].r = ((R2) edges[i][0] + (R2)  edges[i][1] )*0.5;
+				vertices[k].m =  Metric(0.5,edges[i][0],0.5,edges[i][1]);
+				vertices[k].on = 0;
+			  }
+			//vertices[k].i = toI2( vertices[k].r);
+			R2 AB =  vertices[k].r;
+			R2 AA = (A+AB)*0.5;
+			R2 BB = (AB+B)*0.5;
+			vertices[k].ReferenceNumber = edges[i].ref;
+			vertices[k].DirOfSearch = NoDirOfSearch;
+
+			newedges[ie].on = Gh.Contening(AA,ong);
+			newedges[ie++].v[1]=vertices+k;
+
+			newedges[ie]=edges[i];
+			newedges[ie].adj[0]=newedges + ie -1;
+			newedges[ie].adj[1]=newedges+(edges[i].adj[1]-edges) ;
+			newedges[ie].on =  Gh.Contening(BB,ong);
+			newedges[ie++].v[0]=vertices+k;
+			// cout << " ie = " << ie-2 << " vm " << k << " v0 = " <<  Number(newedges[ie-2][0])
+			//	   << " v1 = " << Number(newedges[ie-1][1])  
+			//	   << " ong =" << ong-Gh.edges 
+			//	   << " on 0 =" <<  newedges[ie-2].on -Gh.edges << AA
+			//	   << " on 1 =" <<  newedges[ie-1].on -Gh.edges << BB 
+			//	   << endl;
+			k++;
+		  }
+		if (edgesGtoB) delete [] edgesGtoB;
+		edgesGtoB=0;
+
+		newnbv=k;
+		newNbVerticesOnGeomEdge=kvg;
+		if (newnbv> nbvx) goto Error;// bug 
+
+		nbv = k;
+
+
+		kedge = new Int4[3*nbt+1];
+		ksplitarray = new Int4[nbt+1];
+		ksplit = ksplitarray +1; // because ksplit[-1] == ksplitarray[0]
+
+		for (i=0;i<3*nbt;i++)
+		 kedge[i]=-1;
+
+		//  
+
+		for (i=0;i<nbt;i++)
+		  {  
+
+			Triangle & t = triangles[i];
+			assert(t.link);
+			for(int j=0;j<3;j++)
+			  {
+				const TriangleAdjacent ta = t.Adj(j);
+				const Triangle & tt = ta;
+				if (&tt >= lastT)
+				 t.SetAdj2(j,0,0);// unset adj
+				const Vertex & v0 = t[VerticesOfTriangularEdge[j][0]];
+				const Vertex & v1 = t[VerticesOfTriangularEdge[j][1]];
+				Int4  ke =edge4->findtrie(Number(v0),Number(v1));
+				if (ke>0) 
+				  {
+					Int4 ii = Number(tt);
+					int  jj = ta;
+					Int4 ks = ke + nbvold;
+					kedge[3*i+j] = ks;
+					if (ii<nbt) // good triangle
+					 kedge[3*ii+jj] = ks;
+					Vertex &A=vertices[ks];
+					Real8 aa,bb,cc,dd;
+					if ((dd=Area2(v0.r,v1.r,A.r)) >=0)
+					  { // warning PB roundoff error 
+						if (t.link && ( (aa=Area2( A.r    , t[1].r , t[2].r )) < 0.0 
+										||   (bb=Area2( t[0].r , A.r    , t[2].r )) < 0.0  
+										||   (cc=Area2( t[0].r , t[1].r , A.r    )) < 0.0))
+						 ferr++, cerr << " Error : " <<  ke + nbvold << " not in triangle " 
+							<< i << " In=" << !!t.link
+							<< " " <<  aa  << " " << bb << " " << cc << " " << dd << endl;
+
+					  }
+
+					else
+					  {
+						if (tt.link && ( (aa=Area2( A.r     , tt[1].r , tt[2].r )) < 0 
+										||   (bb=Area2( tt[0].r , A.r     , tt[2].r )) < 0 
+										||   (cc=Area2( tt[0].r , tt[1].r , A.r     )) < 0)) 
+						 ferr++, cerr << " Warning : " <<  ke + nbvold << " not in triangle " << ii 
+							<< " In=" << !!tt.link 
+							<< " " <<  aa  << " " << bb << " " << cc << " " << dd << endl;
+
+					  } 
+
+				  }
+			  }
+		  }
+		if(ferr)
+		  {
+			cerr << " Number of triangles with P2 interpolation Probleme " << ferr << endl;;
+			MeshError(9);
+		  }
+
+		for (i=0;i<nbt;i++)
+		  {
+			ksplit[i]=1; // no split by default
+			const Triangle & t = triangles[ i];
+			// cout << " Triangle " << i << " " << t  << !!t.link << ":: " ;
+			int nbsplitedge =0;
+			int nbinvisible =0;
+			int invisibleedge=0;
+			int kkk[3];      
+			for (int j=0;j<3;j++)
+			  {
+				if (t.Hidden(j)) invisibleedge=j,nbinvisible++;
+
+				const TriangleAdjacent ta = t.Adj(j);
+				const Triangle & tt = ta;
+
+
+				const Vertex & v0 = t[VerticesOfTriangularEdge[j][0]];
+				const Vertex & v1 = t[VerticesOfTriangularEdge[j][1]];
+				//  cout << " ke = " << kedge[3*i+j]  << " " << Number(v0) << " " << Number(v1) << "/ ";
+				if ( kedge[3*i+j] < 0) 
+				  {
+					Int4  ke =edge4->findtrie(Number(v0),Number(v1));
+					//  cout << ":" << ke << "," << !!t.link << " " <<  &tt ;
+					if (ke<0) // new 
+					  {
+						if (&tt) // internal triangles all the boundary 
+						  { // new internal edges 
+							Int4 ii = Number(tt);
+							int  jj = ta;
+
+							kedge[3*i+j]=k;// save the vertex number 
+							kedge[3*ii+jj]=k;
+							if (k<nbvx) 
+							  {
+								vertices[k].r = ((R2) v0+(R2) v1 )/2;
+								//vertices[k].i = toI2( vertices[k].r);
+								vertices[k].ReferenceNumber=0;
+								vertices[k].DirOfSearch =NoDirOfSearch;
+								vertices[k].m =  Metric(0.5,v0,0.5,v1);
+							  }
+							k++;
+							kkk[nbsplitedge++]=j;		      
+						  } // tt 
+						else
+						 cerr <<endl <<  " Bug " <<i<< " " << j << " t=" << t << endl;
+
+					  } // ke<0	       
+					else
+					  { // ke >=0
+						kedge[3*i+j]=nbvold+ke;
+						kkk[nbsplitedge++]=j;// previously splited
+					  }
+				  }
+				else 
+				 kkk[nbsplitedge++]=j;// previously splited
+
+			  } 
+			assert (nbinvisible<2);
+			// cout << " " <<  nbinvisible << " " <<  nbsplitedge << endl;
+			switch (nbsplitedge) {
+				case 0: ksplit[i]=10; newnbt++; break;   // nosplit
+				case 1: ksplit[i]=20+kkk[0];newnbt += 2; break; // split in 2 
+				case 2: ksplit[i]=30+3-kkk[0]-kkk[1];newnbt += 3; break; // split in 3 
+				case 3:
+						  if (nbinvisible) ksplit[i]=40+invisibleedge,newnbt += 4;
+						  else   ksplit[i]=10*nfortria,newnbt+=nfortria;
+						  break;
+			} 
+			assert(ksplit[i]>=40);
+		  }
+		//  now do the element split
+		newNbOfQuad = 4*NbOfQuad;
+		nbv = k;
+		//  cout << " Nbv = " << nbv << endl;
+		kkk = nbt;
+		ksplit[-1] = nbt;
+		// look on  old true  triangles 
+
+		for (i=0;i<nbtsave;i++)
+		  {
+			//     cout << "Triangle " << i << " " << ksplit[i] << ":" << triangles[i]
+			//	   << "  ----------------------------------------------- " <<endl;
+			// Triangle * tc=0;
+			int  nbmkadj=0;
+			Int4 mkadj [100];
+			mkadj[0]=i;
+			Int4 kk=ksplit[i]/10;
+			int  ke=(int) (ksplit[i]%10);
+			assert(kk<7 && kk >0);
+
+			// def the numbering   k (edge) i vertex 
+			int k0 = ke;
+			int k1 = NextEdge[k0];
+			int k2 = PreviousEdge[k0];
+			int i0 = OppositeVertex[k0];
+			int i1 = OppositeVertex[k1];
+			int i2 = OppositeVertex[k2];
+
+			Triangle &t0=triangles[i];
+			Vertex * v0=t0(i0);           
+			Vertex * v1=t0(i1);           
+			Vertex * v2=t0(i2);
+
+			// cout << "nbmkadj " << nbmkadj << " it=" << i <<endl;
+			assert(nbmkadj< 10);
+			// --------------------------
+			TriangleAdjacent ta0(t0.Adj(i0)),ta1(t0.Adj(i1)),ta2(t0.Adj(i2));
+			// save the flag Hidden
+			int hid[]={t0.Hidden(0),t0.Hidden(1),t0.Hidden(2)};
+			// un set all adj -- save Hidden flag --
+			t0.SetAdj2(0,0,hid[0]);
+			t0.SetAdj2(1,0,hid[1]);
+			t0.SetAdj2(2,0,hid[2]);
+			// --  remake 
+			switch  (kk) {
+				case 1: break;// nothing 
+				case 2: // 
+						  {
+							Triangle &t1=triangles[kkk++];
+							t1=t0;
+							assert (kedge[3*i+i0]>=0);
+							Vertex * v3 = vertices + kedge[3*i+k0];
+
+							t0(i2) = v3;
+							t1(i1) = v3;
+							t0.SetAllFlag(k2,0);
+							t1.SetAllFlag(k1,0);
+						  } 
+						break; 
+				case 3: //
+						  {
+							Triangle &t1=triangles[kkk++];
+							Triangle &t2=triangles[kkk++];
+							t2=t1=t0;
+							assert (kedge[3*i+k1]>=0);
+							assert (kedge[3*i+k2]>=0);
+
+							Vertex * v01 = vertices + kedge[3*i+k2];
+							Vertex * v02 = vertices + kedge[3*i+k1]; 
+							t0(i1) = v01; 
+							t0(i2) = v02; 
+							t1(i2) = v02;
+							t1(i0) = v01; 
+							t2(i0) = v02; 
+							t0.SetAllFlag(k0,0);
+							t1.SetAllFlag(k1,0);
+							t1.SetAllFlag(k0,0);
+							t2.SetAllFlag(k2,0);
+						  } 
+						break;
+				case 4: // 
+				case 6: // split in 4 
+						  {
+							Triangle &t1=triangles[kkk++];
+							Triangle &t2=triangles[kkk++];
+							Triangle &t3=triangles[kkk++];
+							t3=t2=t1=t0;
+							assert(kedge[3*i+k0] >=0 && kedge[3*i+k1] >=0 && kedge[3*i+k2] >=0);
+							Vertex * v12 = vertices + kedge[3*i+k0];
+							Vertex * v02 = vertices + kedge[3*i+k1]; 
+							Vertex * v01 = vertices + kedge[3*i+k2];
+							// cout << Number(t0(i0))  << " " << Number(t0(i1)) 
+							//     << " " <<  Number(t0(i2)) 
+							//     << " " <<  kedge[3*i+k0] 
+							//     << " " <<  kedge[3*i+k1] 
+							//     << " " <<  kedge[3*i+k2] << endl;
+							t0(i1) = v01;
+							t0(i2) = v02;
+							t0.SetAllFlag(k0,hid[k0]);
+
+							t1(i0) = v01;
+							t1(i2) = v12;
+							t0.SetAllFlag(k1,hid[k1]);
+
+							t2(i0) = v02;
+							t2(i1) = v12;
+							t2.SetAllFlag(k2,hid[k2]);
+
+							t3(i0) = v12;
+							t3(i1) = v02;
+							t3(i2) = v01;
+
+							t3.SetAllFlag(0,hid[0]);	   
+							t3.SetAllFlag(1,hid[1]);	   
+							t3.SetAllFlag(2,hid[2]);
+
+							if ( kk == 6)
+							  {
+
+								Triangle &t4=triangles[kkk++];
+								Triangle &t5=triangles[kkk++];
+
+								t4 = t3;
+								t5 = t3;
+
+								t0.SetHidden(k0);
+								t1.SetHidden(k1);
+								t2.SetHidden(k2);
+								t3.SetHidden(0);
+								t4.SetHidden(1);
+								t5.SetHidden(2);
+
+								if (nbv < nbvx ) 
+								  {
+									vertices[nbv].r = ((R2) *v01 + (R2) *v12  + (R2) *v02 ) / 3.0;
+									vertices[nbv].ReferenceNumber =0;
+									vertices[nbv].DirOfSearch =NoDirOfSearch;
+									//vertices[nbv].i = toI2(vertices[nbv].r);
+									Real8 a3[]={1./3.,1./3.,1./3.};
+									vertices[nbv].m = Metric(a3,v0->m,v1->m,v2->m);
+									Vertex * vc =  vertices +nbv++;
+									t3(i0) = vc;
+									t4(i1) = vc;
+									t5(i2) = vc;
+
+								  }
+								else
+								 goto Error; 
+							  }
+
+						  } 
+						break;         
+			}
+
+			// cout << "  -- " << i << " " << nbmkadj << " " << kkk << " " << tc << endl;
+			//  t0.SetDetf();
+			// save all the new triangles
+			mkadj[nbmkadj++]=i;
+			Int4 jj;
+			if (t0.link) 
+			 for (jj=nbt;jj<kkk;jj++)
+				{
+				 triangles[jj].link=t0.link;
+				 t0.link= triangles+jj;
+				 mkadj[nbmkadj++]=jj;
+				 // triangles[jj].SetDet();
+				}
+			// cout << "  -- " << i << " " << nbmkadj << endl;
+			assert(nbmkadj<=13);// 13 = 6 + 4 + 3
+
+			if (kk==6)  newNbOfQuad+=3;
+			//	 triangles[i].Draw();       
+
+			for (jj=ksplit[i-1];jj<kkk;jj++)
+			 // triangles[jj].SetDet();
+			 //	   triangles[jj].Draw();
+
+
+
+			 nbt = kkk;
+			ksplit[i]= nbt; // save last adresse of the new triangles
+			kkk = nbt;
+
+		  }
+
+		//  cout << " nv = " << nbv << " nbt = " << nbt << endl;
+		for (i=0;i<nbv;i++)
+		 vertices[i].m = vertices[i].m*2.;
+		//
+		if(withBackground)
+		 for (i=0;i<BTh.nbv;i++)
+		  BTh.vertices[i].m =  BTh.vertices[i].m*2.;
+
+
+		ret = 2;
+		if (nbt>= nbtx) goto Error; // bug 
+		if (nbv>= nbvx) goto Error; // bug 
+		// generation of the new triangles 
+
+		SetIntCoor("In SplitElement"); 
+
+		ReMakeTriangleContainingTheVertex();
+		if(withBackground)
+		 BTh.ReMakeTriangleContainingTheVertex();
+
+		delete [] edges;
+		edges = newedges;
+		nbe = newnbe;
+		NbOfQuad = newNbOfQuad;
+
+		for (i=0;i<NbSubDomains;i++)
+		  { 
+			Int4 k = subdomains[i].edge- edges;
+			subdomains[i].edge =  edges+2*k; // spilt all edge in 2 
+		  }
+
+		if (ksplitarray) delete [] ksplitarray;
+		if (kedge) delete [] kedge;
+		if (edge4) delete edge4;
+		if (VerticesOnGeomEdge) delete [] VerticesOnGeomEdge;
+		VerticesOnGeomEdge= newVerticesOnGeomEdge;
+		if(VertexOnBThEdge) delete []  VertexOnBThEdge;
+		VertexOnBThEdge = newVertexOnBThEdge;
+		NbVerticesOnGeomEdge = newNbVerticesOnGeomEdge;
+		NbVertexOnBThEdge=newNbVertexOnBThEdge;
+		//  ReMakeTriangleContainingTheVertex();
+
+		FillHoleInMesh();
+
+		if (verbosity>2)
+		 cout << "    (out) Nb of Quadrilaterals = " << NbOfQuad 
+			<< " Nb Of Triangles = " << nbt-NbOutT- NbOfQuad*2 
+			<< " Nb of outside triangles = " << NbOutT << endl;
+
+		CurrentTh=OCurrentTh;
+		return 0; //ok
+
+Error:
+		nbv = nbvold;
+		nbt = nbtold;
+		NbOutT = NbOutTold;
+		// cleaning memory ---
+		delete newedges;
+		if (ksplitarray) delete [] ksplitarray;
+		if (kedge) delete [] kedge;
+		if (newVerticesOnGeomEdge) delete [] newVerticesOnGeomEdge;
+		if (edge4) delete edge4;
+		if(newVertexOnBThEdge) delete []  newVertexOnBThEdge;
+
+
+		CurrentTh= OCurrentTh;
+		return ret; // ok 
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::swap{{{1*/
+	int Triangle::swap(Int2 a,int koption){
+		if(a/4 !=0) return 0;// arete lock or MarkUnSwap
+
+		register Triangle *t1=this,*t2=at[a];// les 2 triangles adjacent
+		register Int1 a1=a,a2=aa[a];// les 2 numero de l arete dans les 2 triangles
+		if(a2/4 !=0) return 0; // arete lock or MarkUnSwap
+
+		register Vertex  *sa=t1->ns[VerticesOfTriangularEdge[a1][0]];
+		register Vertex  *sb=t1->ns[VerticesOfTriangularEdge[a1][1]];
+		register Vertex  *s1=t1->ns[OppositeVertex[a1]];
+		register Vertex  *s2=t2->ns[OppositeVertex[a2]];
+
+		Icoor2 det1=t1->det , det2=t2->det ;
+		Icoor2 detT = det1+det2;
+		Icoor2 detA = Abs(det1) + Abs(det2);
+		Icoor2 detMin = Min(det1,det2);
+
+		int OnSwap = 0;       
+		// si 2 triangle infini (bord) => detT = -2;
+		if (sa == 0) {// les deux triangles sont frontieres
+			det2=bamg::det(s2->i,sb->i,s1->i);
+			OnSwap = det2 >0;}
+		else if (sb == 0) { // les deux triangles sont frontieres
+			det1=bamg::det(s1->i,sa->i,s2->i);
+			OnSwap = det1 >0;}
+		else if(( s1 != 0) && (s2 != 0) ) {
+			det1 = bamg::det(s1->i,sa->i,s2->i);
+			det2 = detT - det1;
+			OnSwap = (Abs(det1) + Abs(det2)) < detA;
+
+			Icoor2 detMinNew=Min(det1,det2);
+			//     if (detMin<0 && (Abs(det1) + Abs(det2) == detA)) OnSwap=BinaryRand();// just for test   
+			if (! OnSwap &&(detMinNew>0)) {
+				OnSwap = detMin ==0;
+				if (! OnSwap) {
+					int  kopt = koption;
+					while (1)
+					 if(kopt) {
+						 // critere de Delaunay pure isotrope
+						 register Icoor2 xb1 = sb->i.x - s1->i.x,
+									 x21 = s2->i.x - s1->i.x,
+									 yb1 = sb->i.y - s1->i.y,
+									 y21 = s2->i.y - s1->i.y,
+									 xba = sb->i.x - sa->i.x, 
+									 x2a = s2->i.x - sa->i.x,
+									 yba = sb->i.y - sa->i.y,
+									 y2a = s2->i.y - sa->i.y;
+						 register double
+							cosb12 =  double(xb1*x21 + yb1*y21),
+									 cosba2 =  double(xba*x2a + yba*y2a) ,
+									 sinb12 = double(det2),
+									 sinba2 = double(t2->det);
+
+
+						 // angle b12 > angle ba2 => cotg(angle b12) < cotg(angle ba2)
+						 OnSwap =  ((double) cosb12 * (double)  sinba2) <  ((double) cosba2 * (double) sinb12);
+						 //  	 if(CurrentTh) 
+						 //  	   cout << "swap " << CurrentTh->Number(sa) << " " << CurrentTh->Number(sb) << " " ;
+						 //  	 cout <<  cosb12 << " " <<  sinba2 << " "  <<  cosba2 << " " << sinb12 
+						 //  	      << " Onswap = " <<  OnSwap << endl;
+						 break;
+					 }
+					 else 
+						{	
+						 // critere de Delaunay anisotrope 
+						 Real8 som;
+						 I2 AB=(I2) *sb - (I2) *sa;
+						 I2 MAB2=((I2) *sb + (I2) *sa);
+						 R2 MAB(MAB2.x*0.5,MAB2.y*0.5);
+						 I2 A1=(I2) *s1 - (I2) *sa;
+						 I2 D = (I2) * s1 - (I2) * sb ;
+						 R2 S2(s2->i.x,s2->i.y);
+						 R2 S1(s1->i.x,s1->i.y);
+							{
+							 Metric M=s1->m;
+							 R2 ABo = M.Orthogonal(AB);
+							 R2 A1o = M.Orthogonal(A1);
+							 // (A+B)+ x ABo = (S1+B)/2+ y A1 
+							 // ABo x - A1o y =  (S1+B)/2-(A+B)/2 = (S1-B)/2 = D/2
+							 double dd = Abs(ABo.x*A1o.y)+Abs(ABo.y*A1o.x);
+							 double d = (ABo.x*A1o.y - ABo.y*A1o.x)*2; // because D/2
+							 if (Abs(d) > dd*1.e-3) {
+								 R2 C(MAB+ABo*((D.x*A1o.y - D.y*A1o.x)/d));
+								 som  = M(C - S2)/M(C - S1);
+							 } else 
+								{kopt=1;continue;}
+
+							}
+							{
+							 Metric M=s2->m;
+							 R2 ABo = M.Orthogonal(AB);
+							 R2 A1o = M.Orthogonal(A1);
+							 // (A+B)+ x ABo = (S1+B)/2+ y A1 
+							 // ABo x - A1o y =  (S1+B)/2-(A+B)/2 = (S1-B)/2 = D/2 
+							 double dd = Abs(ABo.x*A1o.y)+Abs(ABo.y*A1o.x);
+							 double d = (ABo.x*A1o.y - ABo.y*A1o.x)*2; // because D/2
+							 if(Abs(d) > dd*1.e-3) {
+								 R2 C(MAB+ABo*((D.x*A1o.y - D.y*A1o.x)/d));
+								 som  += M(C - S2)/M(C -  S1);
+							 } else 
+								{kopt=1;continue;}
+							}
+						 OnSwap = som < 2;
+						 break;
+						}
+
+				} // OnSwap 
+			} // (! OnSwap &&(det1 > 0) && (det2 > 0) )
+		}
+		if( OnSwap ) 
+		 bamg::swap(t1,a1,t2,a2,s1,s2,det1,det2);
+		else {
+			NbUnSwap ++;
+			t1->SetMarkUnSwap(a1);     
+		}
+		return OnSwap;
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::MetricAt{{{1*/
+	Metric Triangles::MetricAt(const R2 & A) const { 
+		I2 a = toI2(A);
+		Icoor2 deta[3];
+		Triangle * t =FindTriangleContening(a,deta);
+		if (t->det <0) { // outside
+			double ba,bb;
+			TriangleAdjacent edge= CloseBoundaryEdge(a,t,ba,bb) ;
+			return Metric(ba,*edge.EdgeVertex(0),bb,*edge.EdgeVertex(1));}
+		else { // inside
+			Real8   aa[3];
+			Real8 s = deta[0]+deta[1]+deta[2];
+			aa[0]=deta[0]/s;
+			aa[1]=deta[1]/s;
+			aa[2]=deta[2]/s;
+			return Metric(aa,(*t)[0],(*t)[1],(*t)[2]);
+		}
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::Add{{{1*/
+	void Triangles::Add( Vertex & s,Triangle * t, Icoor2 * det3) {
+		// -------------------------------------------
+		//             s2
+		//                                            !
+		//             /|\                            !
+		//            / | \                           !
+		//           /  |  \                          !
+		//    tt1   /   |   \ tt0                     !
+		//         /    |s   \                        !
+		//        /     .     \                       !
+		//       /  .      `   \                      !
+		//      / .           ` \                     !
+		//      ----------------                      !
+		//   s0       tt2       s1
+		//-------------------------------------------- 
+
+		Triangle * tt[3]; // the 3 new Triangles
+		Vertex &s0 = (* t)[0], &s1=(* t)[1], &s2=(* t)[2];
+		Icoor2  det3local[3];
+		int infv = &s0 ?  ((  &s1 ? ( &s2  ? -1 : 2) : 1  )) : 0;
+		// infv = ordre of the infini vertex (null)
+		register int nbd0 =0; // number of zero det3
+		register int izerodet=-1,iedge; // izerodet = egde contening the vertex s
+		Icoor2 detOld = t->det;
+
+		if ( ( infv <0 ) && (detOld <0) ||  ( infv >=0  ) && (detOld >0) ) 
+		  {
+			cerr << "  infv " << infv << " det = " << detOld << endl;
+			cerr << Number(s) << " "<< Number(s0) << " "  
+			  << Number(s1) << " "  << Number(s2) << endl;
+			MeshError(3);
+		  }
+
+		// if det3 do not exist then constuct det3
+		if (!det3) { 
+			det3 = det3local; // alloc 
+			if ( infv<0 ) {
+				det3[0]=bamg::det(s ,s1,s2);
+				det3[1]=bamg::det(s0,s ,s2);
+				det3[2]=bamg::det(s0,s1,s );}
+			else { 
+				// one of &s1  &s2  &s0 is NULL so (&si || &sj) <=> !&sk
+				det3[0]=  &s0 ? -1  : bamg::det(s ,s1,s2) ;
+				det3[1]=  &s1 ? -1 : bamg::det(s0,s ,s2) ;
+				det3[2]=  &s2 ? -1 : bamg::det(s0,s1,s ) ;}}
+
+
+				if (!det3[0]) izerodet=0,nbd0++;
+				if (!det3[1]) izerodet=1,nbd0++;
+				if (!det3[2]) izerodet=2,nbd0++;
+
+				if  (nbd0 >0 ) // point s on a egde or on a vertex 
+				 if (nbd0 == 1) {
+					 iedge = OppositeEdge[izerodet];
+					 TriangleAdjacent ta = t->Adj(iedge);
+
+					 // the point is on the edge 
+					 // if the point is one the boundary 
+					 // add the point in outside part 
+					 if ( t->det >=0) { // inside triangle
+						 if ((( Triangle *) ta)->det < 0 ) {
+							 // add in outside triangle 
+							 Add(s,( Triangle *) ta);
+							 return;}
+					 }}
+				 else {
+					 cerr << " bug  " << nbd0 <<endl;
+					 cerr << " Bug double points in " << endl ;
+					 cerr << " s = " << Number(s) << " " <<  s << endl;
+					 cerr << " s0 = "<< Number(s0) << " "  << s0 << endl;
+					 cerr << " s1 = "<< Number(s1) << " "  << s1 << endl;
+					 cerr << " s2 = "<< Number(s2) << " "  << s2 << endl;
+					 MeshError(5,this);}
+
+					 // remove de MarkUnSwap edge
+					 t->SetUnMarkUnSwap(0);     
+					 t->SetUnMarkUnSwap(1);     
+					 t->SetUnMarkUnSwap(2);
+
+					 tt[0]= t;
+					 tt[1]= &triangles[nbt++];
+					 tt[2]= &triangles[nbt++];
+
+					 if (nbt>nbtx) {
+						 cerr << " No enougth triangles " << endl;
+						 MeshError(999,this);
+					 }
+
+					 *tt[1]=   *tt[2]= *t;
+					 // gestion of the link
+					 tt[0]->link=tt[1];
+					 tt[1]->link=tt[2]; 
+
+					 (* tt[0])(OppositeVertex[0])=&s;
+					 (* tt[1])(OppositeVertex[1])=&s;
+					 (* tt[2])(OppositeVertex[2])=&s;
+
+					 tt[0]->det=det3[0];
+					 tt[1]->det=det3[1];
+					 tt[2]->det=det3[2];         
+
+					 //  update adj des triangles externe 
+					 tt[0]->SetAdjAdj(0);
+					 tt[1]->SetAdjAdj(1);
+					 tt[2]->SetAdjAdj(2);
+					 //  update des adj des 3 triangle interne
+					 const int i0 = 0;
+					 const int i1= NextEdge[i0];
+					 const int i2 = PreviousEdge[i0];
+
+					 tt[i0]->SetAdj2(i2,tt[i2],i0);
+					 tt[i1]->SetAdj2(i0,tt[i0],i1);
+					 tt[i2]->SetAdj2(i1,tt[i1],i2);
+
+					 tt[0]->SetTriangleContainingTheVertex();
+					 tt[1]->SetTriangleContainingTheVertex();
+					 tt[2]->SetTriangleContainingTheVertex();
+
+
+					 // swap if the point s is on a edge
+					 if(izerodet>=0) {
+						 //  cout << " the point s is on a edge =>swap " << iedge << " "  << *tt[izerodet] << endl;
+						 int rswap =tt[izerodet]->swap(iedge);
+
+						 if (!rswap) 
+							{
+							 cout << " Pb swap the point s is on a edge =>swap " << iedge << " "  << *tt[izerodet] << endl;
+							}
+						 assert(rswap);
+					 }
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::SplitInternalEdgeWithBorderVertices{{{1*/
+	Int4  Triangles::SplitInternalEdgeWithBorderVertices(){
+		Int4 NbSplitEdge=0;
+		SetVertexFieldOn();  
+		Int4 it;
+		Int4 nbvold=nbv;
+		long int verbosity=2;
+		for (it=0;it<nbt;it++)
+		  {
+			Triangle &t=triangles[it];
+			if (t.link)
+			 for (int j=0;j<3;j++)
+			  if(!t.Locked(j) && !t.Hidden(j)){
+				  Triangle &tt = *t.TriangleAdj(j);
+				  if ( &tt && tt.link && it < Number(tt)) 
+					 { // an internal edge 
+					  Vertex &v0 = t[VerticesOfTriangularEdge[j][0]];
+					  Vertex &v1 = t[VerticesOfTriangularEdge[j][1]];
+					  if (v0.on && v1.on)
+						 {
+						  R2 P= ((R2) v0 + (R2) v1)*0.5;
+						  if ( nbv<nbvx) {
+							  vertices[nbv].r = P;
+							  vertices[nbv++].m = Metric(0.5,v0.m,0.5,v1.m);
+							  vertices[nbv].ReferenceNumber=0;
+							  vertices[nbv].DirOfSearch = NoDirOfSearch ;
+						  }
+						  NbSplitEdge++;
+						  if (verbosity>7)
+							cout <<" Internal edge with two vertices on boundary" 
+							  << Number(v0) << " " << Number(v1) << " by " <<  endl;
+						 }
+					 }
+			  }
+		  }
+		ReMakeTriangleContainingTheVertex();    
+		if (nbvold!=nbv) 
+		  {
+			Int4  iv = nbvold;
+			Int4 NbSwap = 0;
+			Icoor2 dete[3];  
+			for (Int4 i=nbvold;i<nbv;i++) 
+			  {// for all the new point
+				Vertex & vi = vertices[i];
+				vi.i = toI2(vi.r);
+				vi.r = toR2(vi.i);
+				//      if (!quadtree->ToClose(vi,seuil,hi,hj)) {
+				// a good new point 
+				vi.ReferenceNumber=0; 
+				vi.DirOfSearch =NoDirOfSearch;
+				//	cout << " Add " << Number(vi) << " " << vi 
+				// << "   " <<  Number(vi) << " <--> " << Number(vi) <<endl;
+				Triangle *tcvi = FindTriangleContening(vi.i,dete);
+				if (tcvi && !tcvi->link) {
+					cout << i <<  " PB insert point " << Number(vi) << vi << Number(vi) 
+					  << " tcvi = " << tcvi << " " << tcvi->link << endl;
+					cout << (*tcvi)[1] <<  (*tcvi)[2] << endl;
+					tcvi = FindTriangleContening(vi.i,dete);
+					cout << (*tcvi)[1] <<  (*tcvi)[2] << endl;
+					MeshError(1001,this);
+				}
+
+
+				quadtree->Add(vi);
+				assert (tcvi && tcvi->det >= 0) ;// internal 
+				Add(vi,tcvi,dete);
+				NbSwap += vi.Optim(1);          
+				iv++;
+				//      }
+			  }
+			if (verbosity>3) 
+			  {
+				cout << "    Nb Of New Point " << iv ;
+				cout << " Nb swap = " << NbSwap << " to  split internal edges with border vertices" ;}
+
+				nbv = iv;
+		  }
+		if (NbSplitEdge >  nbv-nbvold)
+		 cout << " Warning not enough vertices  to split all internal edges "  << endl
+			<< "    we lost " << NbSplitEdge - ( nbv-nbvold) << " Edges Sorry " << endl;
+		if (verbosity>2)
+		 cout << "SplitInternalEdgeWithBorderVertices: Number of splited edge " << NbSplitEdge << endl;
+		return  NbSplitEdge;
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::InsertNewPoints{{{1*/
+	Int4 Triangles::InsertNewPoints(Int4 nbvold,Int4 & NbTSwap) {
+		long int verbosity=2;
+		Real8 seuil= 1.414/2 ;// for two close point 
+		Int4 i;
+		// insertion part --- 
+
+		const Int4 nbvnew = nbv-nbvold;
+		if (verbosity>5) 
+		 cout << "    Try to Insert the " <<nbvnew<< " new points " << endl;  
+		Int4 NbSwap=0;
+		Icoor2 dete[3];
+
+		// construction d'un ordre aleatoire 
+		if (! nbvnew) 
+		 return 0; 
+		if (nbvnew) {
+			const Int4 PrimeNumber= AGoodNumberPrimeWith(nbv)  ;
+			Int4 k3 = rand()%nbvnew ; 
+			for (Int4 is3=0; is3<nbvnew; is3++) {
+				register Int4 j = nbvold +(k3 = (k3 + PrimeNumber)% nbvnew);
+				register Int4 i = nbvold+is3; 
+				ordre[i]= vertices + j;
+				ordre[i]->ReferenceNumber=i;
+			}
+			// be carefull 
+			Int4  iv = nbvold;
+			for (i=nbvold;i<nbv;i++) 
+			  {// for all the new point
+				Vertex & vi = *ordre[i];
+				vi.i = toI2(vi.r);
+				vi.r = toR2(vi.i);
+				Real4 hx,hy;
+				vi.m.Box(hx,hy);
+				Icoor1 hi=(Icoor1) (hx*coefIcoor),hj=(Icoor1) (hy*coefIcoor);
+				if (!quadtree->ToClose(vi,seuil,hi,hj)) 
+				  {
+					// a good new point 
+					Vertex & vj = vertices[iv];
+					Int4 j = vj.ReferenceNumber; 
+					assert( &vj== ordre[j]);
+					if(i!=j)
+					  { //  for valgring 
+						Exchange(vi,vj);
+						Exchange(ordre[j],ordre[i]);
+					  }
+					vj.ReferenceNumber=0; 
+					//	cout << " Add " << Number(vj) << " " << vj 
+					// << "   " <<  Number(vi) << " <--> " << Number(vj) <<endl;
+					Triangle *tcvj = FindTriangleContening(vj.i,dete);
+					if (tcvj && !tcvj->link) 
+					  {
+						cerr << i <<  " PB insert point " << Number(vj) << vj << Number(vi) 
+						  << " tcvj = " << tcvj << " " << tcvj->link << endl;
+						cerr << (*tcvj)[1] <<  (*tcvj)[2] << endl;
+						tcvj = FindTriangleContening(vj.i,dete);
+						cout << (*tcvj)[1] <<  (*tcvj)[2] << endl;
+						MeshError(1001,this);
+					  }
+
+
+					quadtree->Add(vj);
+					assert (tcvj && tcvj->det >= 0) ;// internal 
+					Add(vj,tcvj,dete);
+					NbSwap += vj.Optim(1);          
+					iv++;
+				  }
+			  } 
+			if (verbosity>3) {
+				cout << "    Nb Of New Point " << iv << " Nb Of To close Points " << nbv-iv ;
+				cout << " Nb swap = " << NbSwap << " after " ;}
+
+				nbv = iv;
+		}
+
+		for (i=nbvold;i<nbv;i++) 
+		 NbSwap += vertices[i].Optim(1);  
+		if (verbosity>3) 
+		 cout << " NbSwap = " <<  NbSwap << endl;
+
+
+		NbTSwap +=  NbSwap ;
+		return nbv-nbvold;
+
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::NewPoints{{{1*/
+	void  Triangles::NewPoints(Triangles & Bh,int KeepBackVertex) {
+		long int verbosity=2;
+		Int4 nbtold(nbt),nbvold(nbv);
+		if (verbosity>2) 
+		 cout << "  -- Triangles::NewPoints ";
+		if (verbosity>3)cout <<  " nbv (in)  on Boundary  = " << nbv  <<endl;
+		Int4 i,k;
+		int j;
+		Int4 *first_np_or_next_t = new Int4[nbtx];
+		Int4 NbTSwap =0;
+		//    insert old point
+		nbtold = nbt;
+
+		if (KeepBackVertex && (&Bh != this) && (nbv+Bh.nbv< nbvx)) 
+		  {
+			//   Bh.SetVertexFieldOn();
+			for (i=0;i<Bh.nbv;i++)
+			  { 
+				Vertex & bv = Bh[i];
+				if (!bv.on) {
+					vertices[nbv].r = bv.r;
+					vertices[nbv++].m = bv.m;}
+			  }
+			int nbv1=nbv;
+			Bh.ReMakeTriangleContainingTheVertex();     
+			InsertNewPoints(nbvold,NbTSwap)   ;            
+			if (verbosity>2)
+			 cout <<  "      (Nb of Points from background mesh  = " 
+				<< nbv-nbvold  << " / " << nbv1-nbvold << ")" << endl;
+		  }  
+		else 
+		 Bh.ReMakeTriangleContainingTheVertex();     
+
+		Triangle *t;
+		// generation of the list of next Triangle 
+		// at 1 time we test all the triangles
+		Int4 Headt =0,next_t;
+		for(i=0;i<nbt;i++)
+		 first_np_or_next_t[i]=-(i+1);
+		// end list i >= nbt 
+		// the list of test triangle is 
+		// the next traingle on i is  -first_np_or_next_t[i]
+		int iter=0;
+		// Big loop 
+		do {
+			iter++;
+			nbtold = nbt;
+			nbvold = nbv;
+
+			// default size of  IntersectionTriangle
+
+			i=Headt;
+			next_t=-first_np_or_next_t[i];
+			for(t=&triangles[i];i<nbt;t=&triangles[i=next_t],next_t=-first_np_or_next_t[i]) 
+			  { // for each triangle  t
+				// we can change first_np_or_next_t[i]
+				//      cout << " Do the triangle " << i << " Next_t=" << next_t << endl;
+				assert(i>=0 && i < nbt );
+				first_np_or_next_t[i] = iter; 
+				for(j=0;j<3;j++)
+				  { // for each edge 
+					TriangleAdjacent tj(t,j);
+					Vertex & vA = * tj.EdgeVertex(0);
+					Vertex & vB = * tj.EdgeVertex(1);
+
+					if (!t->link) continue;// boundary
+					if (t->det <0) continue;
+					if (t->Locked(j)) continue;
+
+					TriangleAdjacent tadjj = t->Adj(j);	  
+					Triangle * ta= tadjj;
+
+					if (ta->det <0) continue;	  
+
+					R2 A = vA;
+					R2 B = vB;
+
+					k=Number(ta);
+
+					if(first_np_or_next_t[k]==iter)  // this edge is done before 
+					 continue; // next edge of the triangle 
+
+					//const Int4 NbvOld = nbv;
+					lIntTria.SplitEdge(Bh,A,B);
+					lIntTria.NewPoints(vertices,nbv,nbvx);
+				  } // end loop for each edge 
+
+			  }// for triangle   
+
+			if (!InsertNewPoints(nbvold,NbTSwap)) 
+			 break;
+
+			for (i=nbtold;i<nbt;i++)
+			 first_np_or_next_t[i]=iter;
+
+			Headt = nbt; // empty list 
+			for (i=nbvold;i<nbv;i++) 
+			  { // for all the triangle contening the vertex i
+				Vertex * s  = vertices + i;
+				TriangleAdjacent ta(s->t, EdgesVertexTriangle[s->vint][1]);
+				Triangle * tbegin= (Triangle*) ta;
+				Int4 kt;
+				do { 
+					kt = Number((Triangle*) ta);
+					if (first_np_or_next_t[kt]>0) 
+					 first_np_or_next_t[kt]=-Headt,Headt=kt;
+					assert( ta.EdgeVertex(0) == s);
+					ta = Next(Adj(ta));
+				} while ( (tbegin != (Triangle*) ta)); 
+			  }   
+
+		} while (nbv!=nbvold);
+
+		delete []  first_np_or_next_t;
+
+		Int4 NbSwapf =0,NbSwp;
+
+		// bofbof 
+
+
+		NbSwp = NbSwapf;
+		for (i=0;i<nbv;i++)
+		 NbSwapf += vertices[i].Optim(0);
+		/*
+			for (i=0;i<nbv;i++)
+			NbSwapf += vertices[i].Optim(0);
+			for (i=0;i<nbv;i++)
+			NbSwapf += vertices[i].Optim(0);
+			for (i=0;i<nbv;i++)
+			NbSwapf += vertices[i].Optim(0);
+			for (i=0;i<nbv;i++)
+			NbSwapf += vertices[i].Optim(0);
+			*/
+		NbTSwap +=  NbSwapf ;
+		if (verbosity>3) cout << "   " ;
+		if (verbosity>2) 
+		 cout << " Nb Of Vertices =" << nbv << " Nb of triangles = " << nbt-NbOutT 
+			<< " NbSwap final = " << NbSwapf << " Nb Total Of Swap = " << NbTSwap << endl;
+
+
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::NewPointsOld{{{1*/
+	void  Triangles::NewPointsOld(Triangles & Bh) {
+		long int verbosity=2;
+		Real8 seuil= 0.7 ;// for two neart point 
+		if (verbosity>1) 
+		 cout << " begin :  Triangles::NewPointsOld " << endl;
+		Int4 i,k;
+		int j;
+		Int4 BeginNewPoint[3];
+		Int4 EndNewPoint[3];
+#ifdef TRACETRIANGLE
+		Int4 trace=0;
+#endif
+		int step[3];
+		Int4 *first_np_or_next_t = new Int4[nbtx];
+		Int4 ColorEdge[3];
+		Int4 color=-1;
+		Triangle *t;
+		// generation of the list of next Triangle 
+		// at 1 time we test all the triangles
+		Int4 Headt =0,next_t;
+		for(i=0;i<nbt;i++)
+		 first_np_or_next_t[i]=-(i+1);
+		// end list i >= nbt 
+		// the list of test triangle is 
+		// the next Triangle on i is  -first_np_or_next_t[i]
+		Int4 nbtold,nbvold;
+
+		// Big loop 
+		do {
+			nbtold = nbt;
+			nbvold = nbv;
+			// default size of  IntersectionTriangle
+
+			i=Headt;
+			next_t=-first_np_or_next_t[i];
+			for(t=&triangles[i];i<nbt;t=&triangles[i=next_t],next_t=-first_np_or_next_t[i]) 
+			  { // for each triangle  t
+				// we can change first_np_or_next_t[i]
+#ifdef TRACETRIANGLE
+				trace =  TRACETRIANGLE <0 ? 1 : i == TRACETRIANGLE;
+#endif
+				//      cout << " Do the triangle " << i << " Next_t=" << next_t << endl;
+				assert(i>=0 && i < nbt );
+				first_np_or_next_t[i] = nbv; // to save the fist new point of triangle
+				for(j=0;j<3;j++)
+				  { // for each edge 
+					TriangleAdjacent tj(t,j);
+					// color++;// the color is 3i+j
+					color = 3*i + j ;;
+					ColorEdge[j]=color;
+					BeginNewPoint[j]=nbv;
+					EndNewPoint[j]=nbv-1;
+					step[j]=1;// right sens 
+					Vertex & vA = * tj.EdgeVertex(0);
+					Vertex & vB = * tj.EdgeVertex(1);
+
+#ifdef TRACETRIANGLE
+					if(trace) {
+						cout << " i " << Number(vA) <<" j "<<  Number(vB) 
+						  << " "  << t->Locked(j) ;
+					}
+#endif
+					if (!t->link) continue;// boundary
+					if (t->det <0) continue;
+					if (t->Locked(j)) continue;
+
+					TriangleAdjacent tadjj = t->Adj(j);	  
+					Triangle * ta= tadjj;
+
+					if (ta->det <0) continue;	  
+
+					R2 A = vA;
+					R2 B = vB;
+
+					k=Number(ta);
+					// the 2 opposite vertices 
+					const Vertex & vC1  =  *tj.OppositeVertex();
+					const Vertex & vC2 = *tadjj.OppositeVertex();
+
+#ifdef TRACETRIANGLE
+					trace = trace || k == TRACETRIANGLE;
+					if(trace) {
+						cout << "Test Arete " << i << " AB = " << A << B 
+						  << "i "  <<Number(vA)<< "j" <<Number(vB); 
+						cout << " link" <<(int)t->link << " ta=" << Number( ta) 
+						  << " det " <<ta->det ;
+						cout << " hA = " <<vA.m.h << " hB = " <<vB.m.h ;
+						cout << " loc " << ta->Locked(j) << endl;
+					}
+#endif
+
+					if(first_np_or_next_t[k]>0) { // this edge is done before 
+						// find the color of the edge and begin , end of newpoint
+						register int kk = t->NuEdgeTriangleAdj(j);
+						assert ((*t)(VerticesOfTriangularEdge[j][0]) == (*ta)(VerticesOfTriangularEdge[kk][1]));
+						assert ((*t)(VerticesOfTriangularEdge[j][1]) == (*ta)(VerticesOfTriangularEdge[kk][0]));
+						register Int4 kolor =3*k + kk;
+						ColorEdge[j]=kolor;
+						register Int4 kkk= 1;
+						step[j]=-1;// other sens 
+						BeginNewPoint[j]=0;
+						EndNewPoint[j]=-1; // empty list          
+						for (Int4 iv=first_np_or_next_t[k];iv<nbv;iv++) 
+						 if (vertices[iv].color > kolor) 
+						  break; // the color is passed            
+						 else if (vertices[iv].color == kolor) {
+							 EndNewPoint[j]=iv; 
+							 if (kkk) // one time test
+							  kkk=0,BeginNewPoint[j]=iv;}
+							 continue; // next edge of the triangle 
+					} // end  if( k < i) 
+
+
+					const Int4 NbvOld = nbv;
+					lIntTria.SplitEdge(Bh,A,B);
+					// Int4 NbvNp =
+					lIntTria.NewPoints(vertices,nbv,nbvx);
+					Int4 nbvNew=nbv;
+					nbv = NbvOld;
+					for (Int4 iv=NbvOld;iv<nbvNew;iv++) {
+						vertices[nbv].color = color;
+						vertices[nbv].ReferenceNumber=nbv;// circular link
+						R2 C =  vertices[iv].r;
+						vertices[nbv].r =  C;
+						vertices[nbv].m =  vertices[iv].m ;
+						// test if the new point is not to close to the 2 opposite vertex
+						R2 CC1 = C-vC1 , CC2 = C-vC2;
+						if (   (  (vC1.m(CC1) + vertices[nbv].m(CC1)) >  seuil)
+									&& (  (vC2.m(CC2) + vertices[nbv].m(CC2)) >  seuil) )
+						 nbv++;
+					}
+
+					EndNewPoint[j] = nbv-1;
+				  } // end loop for each edge 
+
+#ifdef TRACETRIANGLE
+				if(trace) {
+					// verification des point cree 
+					cout << "\n ------------ " << t->link << " " << t->det 
+					  << " b " << BeginNewPoint[0] << " " << BeginNewPoint[1]
+					  << " " << BeginNewPoint[2] << " " 
+					  << " e " << EndNewPoint[0] << " " << EndNewPoint[1] 
+					  << " " << EndNewPoint[2] << " " 
+					  << " s " << step[0] << " " << step[1] << " " << step[2] << " " 
+					  <<  endl;
+				}
+#endif
+
+				if (!t->link) continue;// boundary
+				if (t->det<=0) continue;// outside 
+				//      continue;
+				for(int j0=0;j0<3;j0++)
+				 for (Int4 i0= BeginNewPoint[j0]; i0 <= EndNewPoint[j0];i0++)
+					{
+					 // find the neart  point one the opposite edge 
+					 // to compute i1
+					 Vertex & vi0 = vertices[i0];
+					 int kstack = 0;
+					 Int4 stack[10];
+					 //   Int4 savRef[10];
+					 int j1 = j0; 
+					 while (j0 != (j1 = NextEdge[j1])) {//loop on the 2 other edge
+						 // computation of the intersection of edge j1 and DOrto
+						 // take the good sens 
+
+						 if (BeginNewPoint[j1]> EndNewPoint[j1])
+						  continue; // 
+						 else if (EndNewPoint[j1] - BeginNewPoint[j1] <1) {
+							 for (Int4 ii1= BeginNewPoint[j1];ii1<=EndNewPoint[j1];ii1++)
+							  stack[kstack++] = ii1;
+							 continue;}
+
+
+							 int k0,k1;
+							 if (step[j1]<0) k0=1,k1=0; // reverse
+							 else k0=0,k1=1; 
+							 R2 V10 = (R2)(*t)[VerticesOfTriangularEdge[j1][k0]];
+							 R2 V11 = (R2)(*t)[VerticesOfTriangularEdge[j1][k1]];
+							 R2 D = V11-V10;
+							 Real8 c0 =  vi0.m(D,(R2) vi0);
+
+							 Real8 c10 =  vi0.m(D,V10);
+							 Real8 c11 =  vi0.m(D,V11);
+
+							 Real8 s;
+							 //cout << " --i0 = " << i0  << D  << V10 << V11 << endl ;
+							 //cout << "   c10 " <<  c10 << " c0 " << c0 << " c11 " << c11 << endl;
+							 if (( c10 < c0 ) && (c0 < c11)) 
+							  s = (c11-c0)/(c11-c10);
+							 else if  (( c11 < c0 ) && (c0 < c10)) 
+							  s = (c11-c0) /(c11-c10);
+							 else break;
+							 R2 VP = V10*s + V11*(1-s);
+							 int sss = (c11-c10) >0 ? 1 : -1;
+							 // find the 2 point by dichotomie
+							 //cout << "   t =" << Number(t) << " c0 " << c0  ;
+							 Int4 ii0 =  BeginNewPoint[j1];
+							 Int4 ii1 =  EndNewPoint[j1];	     
+							 Real8 ciii=-1,cii0=-1,cii1=-1  ;
+							 if ( sss * ((cii0=vi0.m(D,(R2) vertices[ii0]))- c0) >0 )  
+							  stack[kstack++] = ii0;//cout << " add+0 " << ii0;
+							 else if ( sss * ((cii1=  vi0.m(D ,(R2) vertices[ii1]))- c0) < 0 )  
+							  stack[kstack++] = ii1;//cout << " add+1 " << ii1;
+							 else {
+								 while ((ii1-ii0)> 1) {
+									 Int4 iii = (ii0+ii1)/2;
+									 ciii = vi0.m( D ,(R2) vertices[iii]);
+									 //cout << " (iii = " << iii << " " <<  ciii << ") ";
+									 if ( sss * (ciii - c0) <0 )  ii0 = iii;
+									 else ii1 = iii;}	        	      
+									 stack[kstack++] = ii0;// cout << " add0 " << ii0;
+									 if (ii1 != ii0)  stack[kstack++] = ii1;//cout << " add1 " << ii1;
+							 }
+							 if (kstack >5) // bug ?
+							  cout << "NewPoints: bug????? " << kstack << " stack  " << stack[kstack]<< endl;
+					 }
+
+					 stack[kstack++] = -1; // to stop
+					 Int4 i1;
+					 kstack =0; 
+					 while( (i1=stack[kstack++]) >= 0) 
+						{ // the two parameter is i0 and i1 
+						 assert(i1 < nbv && i1 >= 0);
+						 assert(i0 < nbv && i0 >= 0);
+						 assert(i1 != i0);
+						 R2 v01 = (R2) vertices[i1]- (R2) vertices[i0];
+						 Real8 d01 = (vertices[i0].m(v01) + vertices[i1].m(v01));
+
+
+#ifdef TRACETRIANGLE
+						 if(trace) {
+							 cout << "\n test j" << j <<" "  << i0 
+								<< " " << i1 << " d01=" << d01 <<endl;}
+#endif
+						 assert (i0 >= nbvold);
+						 assert (i1 >= nbvold);
+						 assert(i0 != i1);
+						 if (d01 == 0) 
+						  break; 
+						 if ( d01 < seuil) 
+						  if (i1<nbvold) {
+							  // remove all the points i0;
+							  register Int4 ip,ipp;
+							  for  (ip=i0;i0 != (ipp = vertices[ip].ReferenceNumber);ip=ipp)
+								vertices[ip].ReferenceNumber = -1;// mark remove
+							  vertices[ip].ReferenceNumber = -1;// mark remove
+						  }
+						  else {
+							  // remove on of two points
+							  register Int4 ip0, ip1, ipp0,ipp1;
+							  register int kk0=1,kk1=1;
+							  // count the number of common points to compute weight w0,w1
+							  for  (ip0=i0;i0 != (ipp0 = vertices[ip0].ReferenceNumber);ip0=ipp0) kk0++;
+							  for  (ip1=i1;i1 != (ipp1 = vertices[ip1].ReferenceNumber);ip1=ipp1) kk1++;
+
+							  register Real8 w0 = ((Real8) kk0)/(kk0+kk1);
+							  register Real8 w1 = ((Real8) kk1)/(kk0+kk1);
+
+							  // make a circular link
+							  Exchange(vertices[i0].ReferenceNumber,vertices[i1].ReferenceNumber);
+							  // the new coordinate 
+							  R2 C //= vertices[i0] ;
+							  =  vertices[i0].r *w0 + vertices[i1].r* w1;
+
+#ifdef TRACETRIANGLE
+							  if(trace) {
+								  cout << "\n ref = "<< vertices[i0].ref << " " <<vertices[i1].ref <<endl;
+							  }
+#endif    
+							  // update the new point points of the list 
+							  for  (ip0=i0;i0 != (ipp0 = vertices[ip0].ReferenceNumber);ip0=ipp0)
+								vertices[ip0].r = C;	      
+							  vertices[ip0].r = C;
+						  }
+						}
+					} // for (i0= ....
+			  }// for triangle   
+
+			// remove of all the double points
+
+			Int4 ip,ipp,kkk=nbvold;
+			for (i=nbvold;i<nbv;i++) 
+			 if (vertices[i].ReferenceNumber>=0) {// good points
+				 //  cout <<" i = " << i ;
+				 for  (ip=i;i != (ipp = vertices[ip].ReferenceNumber);ip=ipp)
+				  vertices[ip].ReferenceNumber = -1;// mark remove
+				 vertices[ip].ReferenceNumber = -1;// mark remove
+				 // cout << i << " ---> " << kkk << endl;        
+				 vertices[kkk] = vertices[i];
+				 vertices[kkk].i = toI2(vertices[kkk].r);
+				 vertices[kkk++].ReferenceNumber = 0;
+
+			 } 
+
+			// insertion part --- 
+
+			const Int4 nbvnew = kkk-nbvold;
+
+			cout << "    Remove " << nbv - kkk  << " to close  vertex " ;
+			cout << " and   Insert the " <<nbvnew<< " new points " << endl;  
+			nbv = kkk;
+			Int4 NbSwap=0;
+			Icoor2 dete[3];
+
+			// construction d'un ordre aleatoire 
+			if (! nbvnew) 
+			 break; 
+			if (nbvnew) {
+				const Int4 PrimeNumber= AGoodNumberPrimeWith(nbv)  ;
+				Int4 k3 = rand()%nbvnew ; 
+				for (Int4 is3=0; is3<nbvnew; is3++) 
+				 ordre[nbvold+is3]= &vertices[nbvold +(k3 = (k3 + PrimeNumber)% nbvnew)];
+
+				for (i=nbvold;i<nbv;i++) 
+				  { Vertex * vi = ordre[i];
+					Triangle *tcvi = FindTriangleContening(vi->i,dete);
+					//     Vertex * nv =  quadtree->NearestVertex(vi->i.x,vi->i.y);
+					//      cout << " Neart Vertex of "  << Number(vi)<< vi->i << " is " 
+					//   << Number(nv) << nv->i  << endl;
+					// Int4  kt = Number(tcvi);
+					// 
+
+					quadtree->Add(*vi); //
+					assert (tcvi->det >= 0) ;// internal 
+					Add(*vi,tcvi,dete),NbSwap += vi->Optim(1);          
+				  }  
+			}
+			cout << " Nb swap = " << NbSwap << " after " ;
+
+			for (i=nbvold;i<nbv;i++) 
+			 NbSwap += vertices[i].Optim(1);  
+			cout << NbSwap << endl;
+
+			for (i=nbtold;i<nbt;i++)
+			 first_np_or_next_t[i]=1;
+
+			Headt = nbt; // empty list 
+			for (i=nbvold;i<nbv;i++) 
+			  { // for all the triangle contening the vertex i
+				Vertex * s  = vertices + i;
+				TriangleAdjacent ta(s->t, EdgesVertexTriangle[s->vint][1]);
+				Triangle * tbegin= (Triangle*) ta;
+				Int4 kt;
+				do { 
+					kt = Number((Triangle*) ta);
+					if (first_np_or_next_t[kt]>0) 
+					 first_np_or_next_t[kt]=-Headt,Headt=kt;
+					assert( ta.EdgeVertex(0) == s);
+					ta = Next(Adj(ta));
+				} while ( (tbegin != (Triangle*) ta)); 
+			  }
+
+
+		} while (nbv!=nbvold);
+		delete []  first_np_or_next_t;
+		cout << " end :  Triangles::NewPoints old  nbv=" << nbv << endl;
+
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::Insert{{{1*/
+	void Triangles::Insert() {
+		long int verbosity=2;
+		if (verbosity>2) cout << "  -- Insert initial " << nbv << " vertices " << endl ;
+		Triangles * OldCurrentTh =CurrentTh;
+
+		CurrentTh=this;
+		double time0=CPUtime(),time1,time2,time3;
+		SetIntCoor();
+		Int4 i;
+		for (i=0;i<nbv;i++) 
+		 ordre[i]= &vertices[i] ;
+
+		// construction d'un ordre aleatoire 
+		const Int4 PrimeNumber= AGoodNumberPrimeWith(nbv) ;
+		Int4 k3 = rand()%nbv ; 
+		for (int is3=0; is3<nbv; is3++) 
+		 ordre[is3]= &vertices[k3 = (k3 + PrimeNumber)% nbv];
+
+
+
+
+		for (i=2 ; det( ordre[0]->i, ordre[1]->i, ordre[i]->i ) == 0;) 
+		 if  ( ++i >= nbv) {
+			 cerr << " All the vertices are aline " << endl;
+			 MeshError(998,this); }
+
+			 // echange i et 2 dans ordre afin 
+			 // que les 3 premiers ne soit pas aligne
+			 Exchange( ordre[2], ordre[i]);
+
+			 // on ajoute un point a l'infini pour construire le maillage
+			 // afin d'avoir une definition simple des aretes frontieres
+			 nbt = 2;
+
+
+			 // on construit un maillage trivale forme
+			 // d'une arete et de 2 triangles
+			 // construit avec le 2 aretes orientes et 
+			 Vertex *  v0=ordre[0], *v1=ordre[1];
+
+			 triangles[0](0) = 0; // sommet pour infini 
+			 triangles[0](1) = v0;
+			 triangles[0](2) = v1;
+
+			 triangles[1](0) = 0;// sommet pour infini 
+			 triangles[1](2) = v0;
+			 triangles[1](1) = v1;
+			 const int e0 = OppositeEdge[0];
+			 const int e1 = NextEdge[e0];
+			 const int e2 = PreviousEdge[e0];
+			 triangles[0].SetAdj2(e0, &triangles[1] ,e0);
+			 triangles[0].SetAdj2(e1, &triangles[1] ,e2);
+			 triangles[0].SetAdj2(e2, &triangles[1] ,e1);
+
+			 triangles[0].det = -1;  // faux triangles
+			 triangles[1].det = -1;  // faux triangles
+
+			 triangles[0].SetTriangleContainingTheVertex();
+			 triangles[1].SetTriangleContainingTheVertex();
+
+			 triangles[0].link=&triangles[1];
+			 triangles[1].link=&triangles[0];
+
+			 //  nbtf = 2;
+			 if (  !quadtree )  quadtree = new QuadTree(this,0);
+			 quadtree->Add(*v0);
+			 quadtree->Add(*v1);
+
+			 // on ajoute les sommets un Ò un 
+			 Int4 NbSwap=0;
+
+			 time1=CPUtime();
+
+			 if (verbosity>3) cout << "  -- Begin of insertion process " << endl;
+
+			 for (Int4 icount=2; icount<nbv; icount++) {
+				 Vertex *vi  = ordre[icount];
+				 //    cout << " Insert " << Number(vi) << endl;
+				 Icoor2 dete[3];
+				 Triangle *tcvi = FindTriangleContening(vi->i,dete);
+				 quadtree->Add(*vi); 
+				 Add(*vi,tcvi,dete);
+				 NbSwap += vi->Optim(1,0);
+
+			 }// fin de boucle en icount
+			 time2=CPUtime();
+			 if (verbosity>3) 
+			  cout << "    NbSwap of insertion " <<    NbSwap 
+				 << " NbSwap/Nbv " <<  (float) NbSwap / (float) nbv 
+				 << " NbUnSwap " << NbUnSwap << " Nb UnSwap/Nbv " 
+				 << (float)NbUnSwap /(float) nbv 
+				 <<endl;
+			 NbUnSwap = 0;
+			 // construction d'un ordre aleatoire 
+			 //  const int PrimeNumber= (nbv % 999983) ? 1000003: 999983 ;
+#ifdef NBLOOPOPTIM
+
+			 k3 = rand()%nbv ; 
+			 for (int is4=0; is4<nbv; is4++) 
+			  ordre[is4]= &vertices[k3 = (k3 + PrimeNumber)% nbv];
+
+			 double timeloop = time2 ;
+			 for(int Nbloop=0;Nbloop<NBLOOPOPTIM;Nbloop++) 
+				{
+				 double time000 = timeloop;
+				 Int4  NbSwap = 0;
+				 for (int is1=0; is1<nbv; is1++) 
+				  NbSwap += ordre[is1]->Optim(0,0);
+				 timeloop = CPUtime();
+				 if (verbosity>3) 
+				  cout << "    Optim Loop "<<Nbloop<<" NbSwap: " <<  NbSwap 
+					 << " NbSwap/Nbv " 	   <<  (float) NbSwap / (float) nbv 
+					 << " CPU=" << timeloop - time000 << "  s, " 
+					 << " NbUnSwap/Nbv " << (float)NbUnSwap /(float) nbv  
+					 <<  endl;
+				 NbUnSwap = 0;
+				 if(!NbSwap) break;
+				}
+			 ReMakeTriangleContainingTheVertex(); 
+			 // because we break the TriangleContainingTheVertex
+#endif
+			 time3=CPUtime();
+			 if (verbosity>4) 
+			  cout << "    init " << time1 - time0 << " initialisation,  " 
+				 << time2 - time1 << "s, insert point  " 
+				 << time3 -time2 << "s, optim " << endl
+				 << "     Init Total Cpu Time = " << time3 - time0 << "s " << endl;
+
+			 CurrentTh=OldCurrentTh;
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::ForceBoundary{{{1*/
+	void Triangles::ForceBoundary() {
+		long int verbosity=2;
+		if (verbosity > 2)
+		 cout << "  -- ForceBoundary  nb of edge " << nbe << endl;
+		int k=0;
+		Int4  nbfe=0,nbswp=0,Nbswap=0;
+		for (Int4 t = 0; t < nbt; t++)  
+		 if (!triangles[t].det)
+		  k++,cerr << " det T" << t << " = " << 0 << endl;
+		if (k!=0) {
+			cerr << " ther is  " << k << "  triangles of mes = 0 " << endl;
+			MeshError(11,this);}
+
+			TriangleAdjacent ta(0,0);
+			for (Int4 i = 0; i < nbe; i++) 
+			  {
+				nbswp =  ForceEdge(edges[i][0],edges[i][1],ta);
+
+				if ( nbswp < 0) 	k++;
+				else Nbswap += nbswp;
+				if (nbswp) nbfe++;
+				if ( nbswp < 0 && k < 5)
+				  {
+					cerr << " Missing  Edge " << i << " v0 =  " << Number(edges[i][0]) << edges[i][0].r
+					  <<" v1= " << Number(edges[i][1]) << edges[i][1].r << " " << edges[i].on->Cracked() << "  " << (Triangle *) ta ;
+					if(ta.t)
+					  {
+						Vertex *aa = ta.EdgeVertex(0), *bb = ta.EdgeVertex(1);  
+						cerr << " crossing with  [" << Number(aa) << ", " << Number(bb) << "]\n";
+					  }
+					else cerr << endl;
+
+				  }
+				if ( nbswp >=0 && edges[i].on->Cracked())
+				 ta.SetCracked();
+			  }
+
+
+			if (k!=0) {
+				cerr << " they is " << k << " lost edges " << endl;
+				cerr << " The boundary is crossing may be!" << endl;
+				MeshError(10,this);
+			}
+			for (Int4 j=0;j<nbv;j++)
+			 Nbswap +=  vertices[j].Optim(1,0);
+			if (verbosity > 3)
+			 cout << "     Nb of inforced edge = " << nbfe << " Nb of Swap " << Nbswap << endl;
+
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::FindSubDomain{{{1*/
+	void Triangles::FindSubDomain(int OutSide=0) {
+		long int verbosity=0;
+
+		if (verbosity >2)
+		  {
+			if (OutSide)
+			 cout << "  -- Find all external sub-domain ";	
+			else
+			 cout << "  -- Find all internal sub-domain ";
+			if(verbosity>99)
+			  {
+
+				for(int i=0;i<nbt;++i)
+				 cout << i<< " " << triangles[i] << endl;
+			  }
+
+		  }
+		// if (verbosity > 4) cout << " OutSide=" << OutSide << endl;
+		short * HeapArete = new short[nbt];
+		Triangle  **  HeapTriangle = new Triangle*  [nbt];
+		Triangle *t,*t1;
+		Int4 k,it;
+
+		for (Int4 itt=0;itt<nbt;itt++) 
+		 triangles[itt].link=0; // par defaut pas de couleur
+
+		Int4  NbSubDomTot =0;
+		for ( it=0;it<nbt;it++)  { 
+			if ( ! triangles[it].link  ) {
+				t = triangles + it;
+				NbSubDomTot++;; // new composante connexe
+				Int4 i = 0; // niveau de la pile 
+				t->link = t ; // sd forme d'un triangle cicular link
+
+				HeapTriangle[i] =t ; 
+				HeapArete[i] = 3;
+
+				while (i >= 0) // boucle sur la pile
+				  { while ( HeapArete[i]--) // boucle sur les 3 aretes 
+					  { 
+						int na =  HeapArete[i];
+						Triangle * tc =  HeapTriangle[i]; // triangle courant
+						if( ! tc->Locked(na)) // arete non frontiere
+						  {
+							Triangle * ta = tc->TriangleAdj(na) ; // næ triangle adjacent
+							if (ta->link == 0 ) // non deja chainer => on enpile
+							  { 
+								i++;
+								ta->link = t->link ;  // on chaine les triangles
+								t->link = ta ;  // d'un meme sous domaine          
+								HeapArete[i] = 3; // pour les 3 triangles adjacents
+								HeapTriangle[i] = ta;
+							  }}
+					  } // deplie fin de boucle sur les 3 adjacences
+					i--;
+				  }          
+			}      
+		}
+
+		// supression de tous les sous domaine infini <=>  contient le sommet NULL
+		it =0;
+		NbOutT = 0;
+		while (it<nbt) {
+			if (triangles[it].link) 
+			  { 
+				if (!( triangles[it](0) &&  triangles[it](1) &&  triangles[it](2) )) 
+				  {
+					// infini triangle 
+					NbSubDomTot --;
+					//  cout << " triangle infini " << it << triangles[it] << endl;
+					t=&triangles[it];
+					NbOutT--;  // on fait un coup de trop. 
+					while  (t){ // cout << Number(t) << " " << endl;
+						NbOutT++;
+						t1=t;
+						t=t->link;
+						t1->link=0;}//while (t)
+				  }
+			  }   
+			it++;} // end while (it<nbt)
+			if (nbt == NbOutT ||  !NbSubDomTot) 
+			  {
+				cout << "\n error : " <<  NbOutT << " " << NbSubDomTot <<" " << nbt << endl;
+				cerr << "Error: The boundary is not close => All triangles are outside " << endl;
+				MeshError(888,this);
+			  }
+
+			delete [] HeapArete;
+			delete [] HeapTriangle;
+
+
+			if (OutSide|| !Gh.subdomains || !Gh.NbSubDomains ) 
+			  { // No geom sub domain
+				Int4 i;
+				if (subdomains) delete [] subdomains;
+				subdomains = new SubDomain[ NbSubDomTot];
+				NbSubDomains=  NbSubDomTot;
+				for ( i=0;i<NbSubDomains;i++) {
+					subdomains[i].head=NULL;
+					subdomains[i].ref=i+1;
+				}
+				Int4 * mark = new Int4[nbt];
+				for (it=0;it<nbt;it++)
+				 mark[it]=triangles[it].link ? -1 : -2;
+
+				it =0;
+				k = 0;
+				while (it<nbt) {
+					if (mark[it] == -1) {
+						t1 = & triangles[it];
+						t = t1->link;
+						mark[it]=k;
+						subdomains[k].head = t1;
+						// cout << " New -- " << Number(t1) << " " << it << endl;
+						do {// cout << " k " << k << " " << Number(t) << endl;
+							mark[Number(t)]=k;
+							t=t->link;
+						} while (t!=t1);
+						mark[it]=k++;}
+						//    else if(mark[it] == -2 ) triangles[it].Draw(999);
+						it++;} // end white (it<nbt)
+						assert(k== NbSubDomains);
+						if(OutSide) 
+						  {
+							//  to remove all the sub domain by parity adjacents
+							//  because in this case we have only the true boundary edge
+							// so teh boundary is manifold
+							Int4 nbk = NbSubDomains;
+							while (nbk)
+							 for (it=0;it<nbt && nbk ;it++)
+							  for (int na=0;na<3 && nbk ;na++)
+								 {
+								  Triangle *ta = triangles[it].TriangleAdj(na);
+								  Int4 kl = ta ? mark[Number(ta)] : -2;
+								  Int4 kr = mark[it];
+								  if(kr !=kl) {
+									  //cout << kl << " " << kr << " rl "  << subdomains[kl].ref
+									  // << " rr " << subdomains[kr].ref ;
+									  if (kl >=0 && subdomains[kl].ref <0 && kr >=0 && subdomains[kr].ref>=0)
+										nbk--,subdomains[kr].ref=subdomains[kl].ref-1;
+									  if (kr >=0 && subdomains[kr].ref <0 && kl >=0 && subdomains[kl].ref>=0)
+										nbk--,subdomains[kl].ref=subdomains[kr].ref-1;
+									  if(kr<0 && kl >=0 && subdomains[kl].ref>=0)
+										nbk--,subdomains[kl].ref=-1;
+									  if(kl<0 && kr >=0 && subdomains[kr].ref>=0)
+										nbk--,subdomains[kr].ref=-1;
+									  //   cout << " after \t "   
+									  //	 << kl << subdomains[kl].ref << " rr " << kr 
+									  // << subdomains[kr].ref << endl;
+								  }
+								 }
+							//  cout << subdomains[0].ref << subdomains[1].ref << endl;
+							Int4  j=0;
+							for ( i=0;i<NbSubDomains;i++)
+							 if((-subdomains[i].ref) %2) { // good 
+								 //cout << " sudom ok  = " << i << " " << subdomains[i].ref
+								 // << " " << (-subdomains[i].ref) %2 << endl;
+								 if(i != j) 
+								  Exchange(subdomains[i],subdomains[j]);
+								 j++;}
+							 else
+								{ //cout << " remove sub domain " << i << endl;
+								 t= subdomains[i].head;
+								 while  (t){// cout << Number(t) << " " << endl;
+									 NbOutT++;
+									 t1=t;
+									 t=t->link;
+									 t1->link=0;}//while (t)
+								}
+
+							if(verbosity>4)
+							 cout << " Number of remove sub domain (OutSideMesh) =" << NbSubDomains-j << endl;
+							NbSubDomains=j;
+						  }
+
+						delete []  mark; 
+
+			  }
+			else
+			  { // find the head for all sub domaine
+				if (Gh.NbSubDomains != NbSubDomains && subdomains)
+				 delete [] subdomains, subdomains=0;
+				if (! subdomains  ) 
+				 subdomains = new SubDomain[ Gh.NbSubDomains];
+				NbSubDomains =Gh.NbSubDomains;
+				if(verbosity>4)
+				 cout << "     find the " << NbSubDomains << " sub domain " << endl;
+				Int4 err=0;
+				ReMakeTriangleContainingTheVertex();
+				Int4 * mark = new Int4[nbt];
+				Edge **GeometricalEdgetoEdge = MakeGeometricalEdgeToEdge();
+
+				for (it=0;it<nbt;it++)
+				 mark[it]=triangles[it].link ? -1 : -2;
+				Int4 inew =0;
+				for (Int4 i=0;i<NbSubDomains;i++) 
+				  {
+					GeometricalEdge &eg = *Gh.subdomains[i].edge;
+					subdomains[i].ref = Gh.subdomains[i].ref;
+					int ssdlab = subdomains[i].ref;
+					// by carefull is not easy to find a edge create from a GeometricalEdge 
+					// see routine MakeGeometricalEdgeToEdge
+					Edge &e = *GeometricalEdgetoEdge[Gh.Number(eg)];
+					assert(&e);
+					Vertex * v0 =  e(0),*v1 = e(1);
+					Triangle *t  = v0->t;
+					int sens = Gh.subdomains[i].sens;
+					// test if ge and e is in the same sens 
+					//	cout << " geom edge = " <<  Gh.Number(eg) <<" @" << &eg << " ref = " << subdomains[i].ref 
+					//     << " ref edge =" << eg.ref << " sens " << sens ;
+					if (((eg[0].r-eg[1].r),(e[0].r-e[1].r))<0)
+					 sens = -sens ;
+					subdomains[i].sens = sens;
+					subdomains[i].edge = &e;
+					//	cout << " sens " << sens << " in geom " << eg[0].r << eg[1].r << " in mesh  " << e[0].r << e[1].r << endl;
+					//	cout << "  v0 , v1 = " << Number(v0) << " "  << Number(v1) << endl;
+					assert(t && sens);
+
+					TriangleAdjacent  ta(t,EdgesVertexTriangle[v0->vint][0]);// previous edges
+
+					while (1) 
+					  {
+						assert( v0 == ta.EdgeVertex(1) );
+						//	 cout << " recherche " << Number( ta.EdgeVertex(0)) << endl;
+						if (ta.EdgeVertex(0) == v1) { // ok we find the edge
+							if (sens>0)  
+							 subdomains[i].head=t=Adj(ta);
+							else 
+							 subdomains[i].head=t=ta;
+							//cout << "      triangle  =" << Number(t) << " = " << (*t)[0].r <<  (*t)[1].r <<  (*t)[2].r << endl;
+							if(t<triangles || t >= triangles+nbt || t->det < 0 
+										|| t->link == 0) // Ajoute aout 200 
+							  {
+								cerr << " Error in the def of sub domain "<<i
+								  << " form border " << NbSubDomains - i  << "/" << NbSubDomains
+								  << ": Bad sens  " << Gh.Number(eg) <<" "<< sens <<  endl;  
+								err++;
+								break;}
+								Int4 it = Number(t);
+								if (mark[it] >=0) {
+									if(verbosity>10)
+									 cerr << "     Warning: the sub domain " << i << " ref = " << subdomains[i].ref 
+										<< " is previouly defined with "  <<mark[it] << " ref = " << subdomains[mark[it]].ref
+										<< " skip this def " << endl;
+									break;}
+									if(i != inew) 
+									 Exchange(subdomains[i],subdomains[inew]);
+									inew++;
+									Triangle *tt=t;
+									Int4 kkk=0;
+									do 
+									  {
+										kkk++;
+										assert(mark[Number(tt)]<0);
+										mark[Number(tt)]=i;
+										tt=tt->link;
+									  } while (tt!=t);
+									if(verbosity>7)
+									 cout << "     Nb de triangles dans le sous domaine " << i << " de ref " << subdomains[i].ref << " = " << kkk << endl;
+									break;}
+									ta = Previous(Adj(ta));         
+									if(t == (Triangle *) ta) {
+										err++;
+										cerr << " Error in the def of sub domain " << i 
+										  << " edge=" << Gh.Number(eg) << " " << sens << endl;
+										break;}
+										//         cout << " NB of remove subdomain " << NbSubDomTot-NbSubDomains<< endl;
+
+					  }
+
+				  }
+				if (err) MeshError(777,this);
+
+				if (inew < NbSubDomains) {
+					if (verbosity>5) 
+					 cout << "     Warning: We remove " << NbSubDomains-inew << " SubDomains " << endl;
+					NbSubDomains=inew;}
+
+
+					for (it=0;it<nbt;it++)
+					 if ( mark[it] ==-1 ) 
+					  NbOutT++,triangles[it].link =0;
+					delete [] GeometricalEdgetoEdge;
+					delete [] mark;
+
+			  }
+			NbOutT=0;
+			for (it=0;it<nbt;it++) 
+			 if(!triangles[it].link)  NbOutT++;
+			if (verbosity> 4)
+			 cout << "    " ;
+			if (verbosity> 2)
+			 cout << " Nb of Sub borned Domain  = " <<  NbSubDomTot << " NbOutTriangles = " << NbOutT <<endl;
+
+
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::ReNumberingVertex{{{1*/
+	void Triangles::ReNumberingVertex(Int4 * renu) {
+		// warning be carfull because pointeur
+		// from on mesh to over mesh 
+		//  --  so do ReNumbering a the beginning
+		Vertex * ve = vertices+nbv;
+		Int4 it,ie,i;
+
+		for ( it=0;it<nbt;it++) 
+		 triangles[it].ReNumbering(vertices,ve,renu);
+
+		for ( ie=0;ie<nbe;ie++) 
+		 edges[ie].ReNumbering(vertices,ve,renu);
+
+		for (i=0;i< NbVerticesOnGeomVertex;i++)
+		  {
+			Vertex *v = VerticesOnGeomVertex[i].mv;
+			if (v>=vertices && v < ve)
+			 VerticesOnGeomVertex[i].mv=vertices+renu[Number(v)];
+		  }
+
+		for (i=0;i< NbVerticesOnGeomEdge;i++)
+		  {
+			Vertex *v =VerticesOnGeomEdge[i].mv;
+			if (v>=vertices && v < ve)
+			 VerticesOnGeomEdge[i].mv=vertices+renu[Number(v)];
+		  }
+
+		for (i=0;i< NbVertexOnBThVertex;i++)
+		  {
+			Vertex *v=VertexOnBThVertex[i].v;
+			if (v>=vertices && v < ve)
+			 VertexOnBThVertex[i].v=vertices+renu[Number(v)];
+		  }
+
+		for (i=0;i< NbVertexOnBThEdge;i++)
+		  {
+			Vertex *v=VertexOnBThEdge[i].v;
+			if (v>=vertices && v < ve)
+			 VertexOnBThEdge[i].v=vertices+renu[Number(v)];
+		  }
+
+		// move the Vertices without a copy of the array 
+		// be carefull not trivial code 
+		Int4 j;
+		for ( it=0;it<nbv;it++) // for all sub cycles of the permutation renu
+		 if (renu[it] >= 0) // a new sub cycle
+			{ 
+			 i=it;
+			 Vertex ti=vertices[i],tj;
+			 while ( (j=renu[i]) >= 0) 
+				{ // i is old, and j is new 
+				 renu[i] = -1-renu[i]; // mark 
+				 tj = vertices[j]; // save new
+				 vertices[j]= ti; // new <- old
+				 i=j;     // next 
+				 ti = tj;
+				}  
+			}
+		if (quadtree) 
+		  {  delete quadtree;
+			quadtree = new QuadTree(this);
+		  }
+		for ( it=0;it<nbv;it++)
+		 renu[i]= -renu[i]-1;
+
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::ReNumberingTheTriangleBySubDomain{{{1*/
+	void Triangles::ReNumberingTheTriangleBySubDomain(bool justcompress) {
+		long int verbosity=0;
+		Int4 *renu= new Int4[nbt];
+		register Triangle *t0,*t,*te=triangles+nbt;
+		register Int4 k=0,it,i,j;
+
+		for ( it=0;it<nbt;it++) 
+		 renu[it]=-1; // outside triangle 
+		for ( i=0;i<NbSubDomains;i++)
+		  { 
+			t=t0=subdomains[i].head;
+			assert(t0); // no empty sub domain
+			do { 
+				Int4 kt = Number(t);
+				assert(kt>=0 && kt < nbt );
+				assert(renu[kt]==-1);
+				renu[kt]=k++;
+			}
+			while (t0 != (t=t->link));
+		  }
+		if (verbosity>9)
+		 cout << " number of inside triangles " << k << " nbt = " << nbt << endl;
+		// take is same numbering if possible    
+		if(justcompress)
+		 for ( k=0,it=0;it<nbt;it++) 
+		  if(renu[it] >=0 ) 
+			renu[it]=k++;
+
+		// put the outside triangles at the end
+		for ( it=0;it<nbt;it++) 
+		 if (renu[it]==-1) 
+		  renu[it]=k++;
+
+		assert(k == nbt);
+		// do the change on all the pointeur 
+		for ( it=0;it<nbt;it++)
+		 triangles[it].ReNumbering(triangles,te,renu);
+
+		for ( i=0;i<NbSubDomains;i++)
+		 subdomains[i].head=triangles+renu[Number(subdomains[i].head)];
+
+		// move the Triangles  without a copy of the array 
+		// be carefull not trivial code 
+		for ( it=0;it<nbt;it++) // for all sub cycles of the permutation renu
+		 if (renu[it] >= 0) // a new sub cycle
+			{ 
+			 i=it;
+			 Triangle ti=triangles[i],tj;
+			 while ( (j=renu[i]) >= 0) 
+				{ // i is old, and j is new 
+				 renu[i] = -1; // mark 
+				 tj = triangles[j]; // save new
+				 triangles[j]= ti; // new <- old
+				 i=j;     // next 
+				 ti = tj;
+				}  
+			}
+		delete [] renu;
+		nt = nbt - NbOutT;
+
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::ConsRefTriangle{{{1*/
+	Int4  Triangles::ConsRefTriangle(Int4 *reft) const {
+		long int verbosity=0;
+		assert(reft);
+		register Triangle *t0,*t;
+		register Int4 k=0, num;   
+		for (Int4 it=0;it<nbt;it++) 
+		 reft[it]=-1; // outside triangle 
+		for (Int4 i=0;i<NbSubDomains;i++)
+		  { 
+			t=t0=subdomains[i].head;
+			assert(t0); // no empty sub domain
+			// register Int4 color=i+1;// because the color 0 is outside triangle
+			do { k++;
+				num = Number(t);
+				assert(num>=0 &&num < nbt);
+				reft[num]=i;
+				//  cout << Number(t0) << " " <<Number(t)<< " "  << i << endl;
+			}
+			while (t0 != (t=t->link));
+		  }
+		//  NbOutT = nbt - k;
+		if (verbosity>5) 
+		 cout << " Nb of Sub Domain =" << NbSubDomains  << " Nb of In Triangles " << k 
+			<< " Nbt = " << nbt << " Out Triangles = " << nbt - k <<  endl;
+
+		return k;   
+
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::GeomToTriangles1{{{1*/
+	void Triangles::GeomToTriangles1(Int4 inbvx,int KeepBackVertices) { 
+		Gh.NbRef++;// add a ref to Gh
+
+
+		/************************************************************************* 
+		// methode in 2 step
+		// 1 - compute the number of new edge to allocate
+		// 2 - construct the edge
+remark: 
+in this part we suppose to have a background mesh with the same
+geometry 
+
+To construct the discretisation of the new mesh we have to 
+rediscretize the boundary of background Mesh 
+because we have only the pointeur from the background mesh to the geometry.
+We need the abcisse of the background mesh vertices on geometry
+so a vertex is 
+0 on GeometricalVertex ;
+1 on GeometricalEdge + abcisse
+2 internal 
+
+		 *************************************************************************/
+		assert(&BTh.Gh == &Gh);
+
+		long int verbosity=0;
+		BTh.NbRef++; // add a ref to BackGround Mesh
+		PreInit(inbvx);
+		BTh.SetVertexFieldOn();
+		int * bcurve = new int[Gh.NbOfCurves]; // 
+
+		// we have 2 ways to make the loop 
+		// 1) on the geometry 
+		// 2) on the background mesh
+		//  if you do the loop on geometry, we don't have the pointeur on background,
+		//  and if you do the loop in background we have the pointeur on geometry
+		// so do the walk on  background
+		//  Int4 NbVerticesOnGeomVertex;
+		//  VertexOnGeom * VerticesOnGeomVertex;  
+		//  Int4 NbVerticesOnGeomEdge;
+		//  VertexOnGeom * VerticesOnGeomEdge;
+
+
+		NbVerticesOnGeomVertex=0;
+		NbVerticesOnGeomEdge=0;
+		//1 copy of the  Required vertex
+		int i; 
+		for ( i=0;i<Gh.nbv;i++)
+		 if (Gh[i].Required()) NbVerticesOnGeomVertex++;
+
+		VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];
+		VertexOnBThVertex = new VertexOnVertex[NbVerticesOnGeomVertex];
+		//
+		if( NbVerticesOnGeomVertex >= nbvx) 
+		  {
+			cerr << " Too much vertices on geometry " << NbVerticesOnGeomVertex << " >= " << nbvx << endl; 
+			MeshError(1,this);
+		  }
+		assert(vertices);
+		for (i=0;i<Gh.nbv;i++)
+		 if (Gh[i].Required()) {//Gh  vertices Required
+			 vertices[nbv] =  Gh[i];
+			 vertices[nbv].i = I2(0,0);
+			 Gh[i].to = vertices + nbv;// save Geom -> Th
+			 VerticesOnGeomVertex[nbv]= VertexOnGeom(vertices[nbv],Gh[i]);
+			 // cout << "--------- "  <<Number(Gh[i].to) << " " << Gh[i].to << " " << i << endl;
+			 nbv++;}
+		 else Gh[i].to=0;
+		// 
+		for (i=0;i<BTh.NbVerticesOnGeomVertex;i++)
+		  { 
+			VertexOnGeom & vog = BTh.VerticesOnGeomVertex[i];
+			if (vog.IsRequiredVertex()) {
+				GeometricalVertex * gv = vog;
+				Vertex *bv = vog;
+				assert(gv->to);// use of Geom -> Th
+				VertexOnBThVertex[NbVertexOnBThVertex++] = VertexOnVertex(gv->to,bv);
+				gv->to->m = bv->m; // for taking the metrix of the background mesh
+				;}
+		  }
+		assert(NbVertexOnBThVertex == NbVerticesOnGeomVertex);
+		// new stuff FH with curve
+		//  find the begin of the curve in BTh
+		  {
+			Gh.UnMarkEdges();	
+			int bfind=0;
+			/*
+				cout << " nb curves = " << Gh.NbOfCurves << endl;
+				for(int i=0;i<Gh.NbOfCurves ;i++)
+				{
+				cout << " Curve " << i << " begin e=" << Gh.Number(Gh.curves[i].be) << " k=" << Gh.curves[i].kb 
+				<< "  end e= " << Gh.Number(Gh.curves[i].ee) << " k=" << Gh.curves[i].ke << endl;
+				}*/
+			for (int i=0;i<Gh.NbOfCurves;i++)
+			  {
+				bcurve[i]=-1; 
+			  }
+
+			for (int iedge=0;iedge<BTh.nbe;iedge++) 
+			  {      
+				Edge & ei = BTh.edges[iedge];
+				for(int je=0;je<2;je++) // for the 2 extremites
+				 if (!ei.on->Mark() && ei[je].on->IsRequiredVertex() )
+					{
+					 // a begin of curve 
+					 int nc = ei.on->CurveNumber;
+
+					 //cout << "curve " <<  nc << " v " << Gh.Number((GeometricalVertex *) *ei[je].on) << " "
+					 //     << " e "  << " " << Gh.Number(ei.on) << " vc " << Gh.Number((*Gh.curves[nc].be)[Gh.curves[nc].kb]) << endl;
+					 if(
+								 ei.on==Gh.curves[nc].be    && 
+								 (GeometricalVertex *) *ei[je].on == &(*Gh.curves[nc].be)[Gh.curves[nc].kb] //  same extremity 
+						)     
+						{ 
+						 // cout << " find " << endl;
+						 bcurve[nc]=iedge*2+je;
+						 bfind++;	
+						}      
+					}
+			  } 
+			assert( bfind==Gh.NbOfCurves);
+		  }          
+		// method in 2 + 1 step 
+		//  0.0) compute the length and the number of vertex to do allocation
+		//  1.0)  recompute the length
+		//  1.1)   compute the  vertex 
+		Int4 nbex=0,NbVerticesOnGeomEdgex=0;
+		for (int step=0; step <2;step++)
+		  {
+			Int4 NbOfNewPoints=0;
+			Int4 NbOfNewEdge=0;
+			Int4 iedge;
+			Gh.UnMarkEdges();	
+			/*   add Curve loop  FH    
+			// find a starting back groud edges to walk 
+			for (iedge=0;iedge<BTh.nbe;iedge++) {      
+			Edge & ei = BTh.edges[iedge];
+			for(int jedge=0;jedge<2;jedge++) // for the 2 extremites
+			if (!ei.on->Mark() && ei[jedge].on->IsRequiredVertex() )
+			{
+			*/  
+			// new code FH 2004 
+			Real8 L=0;
+			for (int icurve=0;icurve<Gh.NbOfCurves;icurve++)
+			  { 
+				iedge=bcurve[icurve]/2;
+				int jedge=bcurve[icurve]%2;
+				if( ! Gh.curves[icurve].master) continue; // we skip all equi curve
+				Edge & ei = BTh.edges[iedge];
+				// warning: ei.on->Mark() can be change in
+				// loop for(jedge=0;jedge<2;jedge++) 
+				// new curve  
+				// good the find a starting edge 
+				Real8 Lstep=0,Lcurve=0;// step between two points   (phase==1) 
+				Int4 NbCreatePointOnCurve=0;// Nb of new points on curve     (phase==1) 
+
+
+				//    cout.precision(16);
+				for(int phase=0;phase<=step;phase++) 
+				  {
+
+					for(Curve * curve= Gh.curves+icurve;curve;curve= curve->next)
+					  {
+
+						int icurveequi= Gh.Number(curve);
+
+						if( phase == 0 &&  icurveequi != icurve)  continue;
+
+						int k0=jedge,k1;
+						Edge * pe=  BTh.edges+iedge;
+						//GeometricalEdge *ong = ei.on;
+						int iedgeequi=bcurve[icurveequi]/2;
+						int jedgeequi=bcurve[icurveequi]%2;
+
+						int k0equi=jedgeequi,k1equi;		  
+						Edge * peequi= BTh.edges+iedgeequi;
+						GeometricalEdge *ongequi = peequi->on;
+
+						Real8 sNew=Lstep;// abcisse of the new points (phase==1) 
+						L=0;// length of the curve
+						Int4 i=0;// index of new points on the curve
+						register GeometricalVertex * GA0 = *(*peequi)[k0equi].on;
+						Vertex *A0;
+						A0 = GA0->to;  // the vertex in new mesh
+						Vertex *A1;
+						VertexOnGeom *GA1;
+						Edge * PreviousNewEdge = 0;
+						//  cout << "  --------------New Curve phase " << phase 
+						//       << "---------- A0=" << *A0 << ei[k0]  <<endl;
+						assert (A0-vertices>=0 && A0-vertices <nbv);
+						if(ongequi->Required() ) 
+						  {
+							GeometricalVertex *GA1 = *(*peequi)[1-k0equi].on;
+							A1 = GA1->to;  //
+						  }       
+						else 
+						 for(;;) 
+							{
+							 //   assert(pe && BTh.Number(pe)>=0 && BTh.Number(pe)<=BTh.nbe);
+							 Edge &ee=*pe; 
+							 Edge &eeequi=*peequi; 
+							 k1 = 1-k0; // next vertex of the edge 
+							 k1equi= 1 - k0equi;
+
+							 assert(pe  && ee.on);
+							 ee.on->SetMark();
+							 Vertex & v0=ee[0], & v1=ee[1];
+							 R2 AB= (R2) v1 - (R2) v0;
+							 Real8 L0=L,LAB;
+							 LAB =  LengthInterpole(v0.m,v1.m,AB);
+							 L+= LAB;    
+							 if (phase) {// computation of the new points
+								 while ((i!=NbCreatePointOnCurve) && sNew <= L) { 
+									 //    cout  << " L0= " << L0 << " L " << L << " sN=" 
+									 //         << sNew << " LAB=" << LAB << " NBPC =" <<NbCreatePointOnCurve<< " i " << i  << endl;
+									 assert (sNew >= L0);
+									 assert(LAB);
+
+
+									 assert(vertices && nbv<nbvx);
+									 assert(edges && nbe < nbex);
+									 assert(VerticesOnGeomEdge && NbVerticesOnGeomEdge < NbVerticesOnGeomEdgex);
+									 // new vertex on edge
+									 A1=vertices+nbv++;
+									 GA1=VerticesOnGeomEdge+NbVerticesOnGeomEdge;
+									 Edge *e = edges + nbe++;
+									 Real8 se= (sNew-L0)/LAB;
+									 assert(se>=0 && se < 1.000000001);
+									 se =  abscisseInterpole(v0.m,v1.m,AB,se,1);
+									 assert(se>=0 && se <= 1);
+									 //((k1==1) != (k1==k1equi))
+									 se = k1 ? se : 1. - se;
+									 se = k1==k1equi ? se : 1. - se;
+									 VertexOnBThEdge[NbVerticesOnGeomEdge++] = VertexOnEdge(A1,&eeequi,se); // save 
+									 ongequi = Gh.ProjectOnCurve(eeequi,se,*A1,*GA1); 
+									 A1->ReferenceNumber = eeequi.ref;
+									 A1->DirOfSearch =NoDirOfSearch;
+									 //cout << icurveequi << " " << i << " " <<  *A1 << endl;
+									 e->on = ongequi;
+									 e->v[0]=  A0;
+									 e->v[1]=  A1;
+									 if(verbosity>99)
+									  cout << i << "+ New P "<< nbv-1 << " "  <<sNew<< " L0=" << L0 
+										 << " AB=" << LAB << " s=" << (sNew-L0)/LAB << " se= "  
+										 << se <<" B edge " << BTh.Number(ee) << " signe = " << k1 <<" " << A1->r <<endl;
+
+									 e->ref = eeequi.ref;
+									 e->adj[0]=PreviousNewEdge;
+
+									 if (PreviousNewEdge)
+									  PreviousNewEdge->adj[1] =  e;
+									 PreviousNewEdge = e;
+									 A0=A1;
+									 sNew += Lstep;
+									 //   cout << " sNew = " << sNew << " L = " << L 
+									 //        << "  ------" <<NbCreatePointOnCurve << " " << i <<  endl;
+									 if (++i== NbCreatePointOnCurve) break;
+								 }
+
+							 }               
+							 assert(ee.on->CurveNumber==ei.on->CurveNumber);
+							 if(verbosity>98) cout <<  BTh.Number(ee) << " " << " on=" << *ee[k1].on << " "<< ee[k1].on->IsRequiredVertex() <<  endl;
+							 if ( ee[k1].on->IsRequiredVertex()) {
+								 assert(eeequi[k1equi].on->IsRequiredVertex());
+								 register GeometricalVertex * GA1 = *eeequi[k1equi].on;
+								 A1=GA1->to;// the vertex in new mesh
+								 assert (A1-vertices>=0 && A1-vertices <nbv);
+								 break;}
+								 if (!ee.adj[k1])
+									{cerr << "Error adj edge " << BTh.Number(ee) << ", nbe = "  << nbe 
+									 << " Gh.vertices " << Gh.vertices 
+										<< " k1 = " << k1 << " on=" << *ee[k1].on << endl;
+									 cerr << ee[k1].on->gv-Gh.vertices << endl;
+									}
+								 pe = ee.adj[k1]; // next edge
+								 k0 = pe->Intersection(ee); 
+								 peequi= eeequi.adj[k1equi];  // next edge
+								 k0equi=peequi->Intersection(eeequi);            
+							}// for(;;) end of the curve
+
+
+						if (phase) // construction of the last edge
+						  {
+							Edge *e = edges + nbe++;
+							if (verbosity>10) 
+							 cout << " Fin curve A1" << *A1 << " " << icurve << " <=> " << icurveequi <<"-----" <<
+								NbCreatePointOnCurve << " == " <<i<<endl;
+							e->on  = ongequi;
+							e->v[0]=  A0;
+							e->v[1]=	A1;
+							e->ref = peequi->ref;
+							e->adj[0]=PreviousNewEdge;
+							e->adj[1]=0;
+							if (PreviousNewEdge)
+							 PreviousNewEdge->adj[1] =  e;
+							PreviousNewEdge = e;
+
+							assert(i==NbCreatePointOnCurve);
+
+						  }
+					  } //  end loop on equi curve 
+
+					if (!phase)  { // 
+						Int4 NbSegOnCurve = Max((Int4)(L+0.5),(Int4) 1);// nb of seg
+						Lstep = L/NbSegOnCurve; 
+						Lcurve = L;
+						NbCreatePointOnCurve = NbSegOnCurve-1;
+
+						for(Curve * curve= Gh.curves+icurve;curve;curve= curve->next)
+						  {
+							NbOfNewEdge += NbSegOnCurve;
+							NbOfNewPoints += NbCreatePointOnCurve;
+						  }
+						if(verbosity>5)
+						 cout << icurve << " NbSegOnCurve = " <<  NbSegOnCurve << " Lstep=" 
+							<< Lstep <<" " << NbOfNewPoints<< " NBPC= " << NbCreatePointOnCurve <<endl;
+						// do'nt 
+						//  if(NbCreatePointOnCurve<1) break;
+					}
+				  }//for(phase;;)
+				/*  modif FH add Curve class  		  
+					 }}//for (iedge=0;iedge<BTh.nbe;iedge++) 
+					 */
+				// new code Curve class  	
+		  } //  end of curve loop 
+		// end new code	    
+		// do the allocation
+		if(step==0) 
+		  {
+			//if(!NbOfNewPoints) break;// nothing ????? bug 
+			if(nbv+NbOfNewPoints > nbvx) 
+			  {
+				cerr << " Too much vertices on geometry " << nbv+NbOfNewPoints  << " >= " << nbvx << endl;
+				MeshError(3,this);
+			  }
+			//cout << " NbOfNewEdge" << NbOfNewEdge << " NbOfNewPoints " << NbOfNewPoints << endl;
+			edges = new Edge[NbOfNewEdge];
+			nbex = NbOfNewEdge;
+			if(NbOfNewPoints) { // 
+				VerticesOnGeomEdge = new VertexOnGeom[NbOfNewPoints];
+				NbVertexOnBThEdge =NbOfNewPoints;
+				VertexOnBThEdge = new  VertexOnEdge[NbOfNewPoints];
+				NbVerticesOnGeomEdgex = NbOfNewPoints; }
+				NbOfNewPoints =0;
+				NbOfNewEdge = 0;
+		  }
+		  } // for(step;;)
+		assert(nbe);
+
+		delete [] bcurve;
+
+
+		Insert();
+		ForceBoundary();
+		FindSubDomain();
+
+		NewPoints(BTh,KeepBackVertices) ;
+		CurrentTh = 0;
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::GeomToTriangles0{{{1*/
+	void Triangles::GeomToTriangles0(Int4 inbvx) {
+		Gh.NbRef++;// add a ref to GH
+
+
+		Int4 i,NbOfCurves=0,NbNewPoints,NbEdgeCurve;
+		Real8 lcurve, lstep,s;
+
+		R2 AB;
+		GeometricalVertex *a,*b;
+		Vertex *va,*vb;
+		GeometricalEdge * e;
+		PreInit(inbvx);
+		int  background = &BTh != this;
+		//  int  SameGeom = background && (&BTh.Gh == &Gh);
+		nbv = 0;
+		NbVerticesOnGeomVertex=0;
+		NbVerticesOnGeomEdge=0;
+		for (i=0;i<Gh.nbv;i++)
+		 if (Gh[i].Required() && Gh[i].IsThe() ) NbVerticesOnGeomVertex++;
+		VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];  
+		//
+		if( NbVerticesOnGeomVertex >= nbvx) 
+		  {
+			cerr << " Too much vertices on geometry " << NbVerticesOnGeomVertex << " >= " << nbvx << endl;
+			MeshError(1,this);
+		  }
+		for (i=0;i<Gh.nbv;i++)
+		 if (Gh[i].Required()&& Gh[i].IsThe()  ) {//Gh  vertices Required
+			 if (nbv < nbvx)
+			  vertices[nbv] = Gh[i];
+			 Gh[i].to = vertices + nbv;// save Geom -> Th
+			 VerticesOnGeomVertex[nbv]= VertexOnGeom(*Gh[i].to,Gh[i]);
+			 //  cout << "--------- "  <<Number(Gh[i].to) << " " << Gh[i].to << " " << i << endl;
+			 nbv++;
+		 }
+		//  assert( Gh.nbv < nbvx);
+
+		// Method in 2 step:  0 and 1 
+		// 1) compute de nb of edge 
+		// 2) construct the edge    
+		// generation of the curves
+		assert(! edges);
+		// 2 step 
+		// --step=0 to compute the number of edges + alloc at end
+		// --step=1 to construct the edges
+		for (int step=0;step<2;step++) 
+		  {//  for (int step=0;step<2;step++) 
+			Int4 nbex = 0;
+			nbe = 0;
+			Int4 NbVerticesOnGeomEdge0=NbVerticesOnGeomEdge;
+			//  cout <<  "  -------------- step =" << step << endl;
+			Gh.UnMarkEdges();	
+			NbOfCurves = 0;
+			for (i=0;i<Gh.nbe;i++) {
+				GeometricalEdge & ei = Gh.edges[i];   
+				if (!ei.Dup()) // a good curve (not dup )
+				 for(int j=0;j<2;j++) 
+				  if (!ei.Mark() && ei[j].Required()) { 
+					  // warning ei.Mark() can be change in loop for(j=0;j<2;j++) 
+					  //  cout << " New curve = " << NbOfCurves << endl;
+					  Int4 nbvend  =0;
+
+					  Edge * PreviousNewEdge=0;
+
+					  lstep = -1;//to do not create points
+					  if(ei.Required())
+						 {
+						  if (j==0)
+							if(step==0)
+							 nbe++;
+							else
+							  { 
+								e = & ei;
+								a=ei(0)->The();
+								b=ei(1)->The();
+								assert(edges);
+								edges[nbe].v[0]=a->to;
+								edges[nbe].v[1]=b->to;;
+								edges[nbe].ref = e->ref;
+								edges[nbe].on = e;
+								edges[nbe].adj[0] = 0;
+								edges[nbe].adj[1] = 0;
+								nbe++;}
+						 }
+					  else 
+						 { // on curve ------
+						  for ( int kstep=0;kstep<= step;kstep++)
+							 { // begin  for ( int kstep=0;kstep<= step;kstep++)
+							  // if 2nd step where 2 step
+							  // -- 1 compute le length of the curve
+							  // -- create the points and edge
+							  PreviousNewEdge=0;
+							  NbNewPoints=0;
+							  NbEdgeCurve=0;
+							  assert(nbvend < nbvx); 
+							  lcurve =0;
+							  s = lstep;
+							  int k=j;
+							  e = & ei;
+							  a=ei(k)->The();
+							  va = a->to;
+							  e->SetMark();
+							  //  cout << " New curve " ;
+
+							  // if SameGeo  We have go in the background geometry 
+							  // to find the discretisation of the curve
+
+							  for(;;) 
+								 { 
+								  k = 1-k;
+								  b= (*e)(k)->The();
+								  AB = b->r - a->r;
+								  Metric MA = background ? BTh.MetricAt(a->r) :a->m ;
+								  Metric MB =  background ? BTh.MetricAt(b->r) :b->m ;
+								  Real8 ledge = (MA(AB) + MB(AB))/2;
+								  // 
+								  const int MaxSubEdge = 10;
+								  int NbSubEdge = 1;
+								  Real8 lSubEdge[MaxSubEdge];
+								  R2 A,B;
+								  if (ledge < 1.5) 
+									lSubEdge[0] = ledge;
+								  else {
+									  NbSubEdge = Min( MaxSubEdge, (int) (ledge +0.5));
+									  A= a->r;
+									  Metric MAs =MA,MBs;
+									  // cout << " lSubEdge old=" << ledge 
+									  //      << " new " << A << MA << endl;
+									  ledge = 0; 
+									  Real8 x =0, xstep= 1. /  NbSubEdge;
+									  for (int kk=0; kk < NbSubEdge; kk++,A=B,MAs=MBs ) {
+										  x += xstep;
+										  B =  e->F(k ? x : 1-x);
+										  MBs= background ? BTh.MetricAt(B) :Metric(1-x, MA, x ,MB);
+										  AB = A-B;
+										  lSubEdge[kk]= (ledge += (MAs(AB)+MBs(AB))/2);
+										  // cout << "     " << lSubEdge[kk] << " x " << x  
+										  //      << " " << A << B << MA << MB<< endl ;
+									  }
+									  //  cout << endl;
+								  }
+
+								  Real8 lcurveb = lcurve+ ledge ;
+								  while (lcurve<=s && s <= lcurveb && nbv < nbvend)
+									 {
+									  // New points
+
+									  // Real8 aa=(lcurveb-s)/ledge;
+									  // Real8 bb=(s-lcurve)/ledge;
+
+									  Real8 ss = s-lcurve;
+									  // 1) find the SubEdge containing ss by dichotomie
+									  int kk0=-1,kk1=NbSubEdge-1,kkk;
+									  Real8 ll0=0,ll1=ledge,llk;
+									  while (kk1-kk0>1)
+										 {
+										  if (ss < (llk=lSubEdge[kkk=(kk0+kk1)/2]))
+											kk1=kkk,ll1=llk;
+										  else
+											kk0=kkk,ll0=llk;}
+										  assert(kk1 != kk0);
+
+										  Real8 sbb = (ss-ll0  )/(ll1-ll0);
+										  Real8 bb = (kk1+sbb)/NbSubEdge, aa=1-bb;
+
+										  // new vertex on edge
+										  vb = &vertices[nbv++];
+										  vb->m = Metric(aa,a->m,bb,b->m);
+										  vb->ReferenceNumber = e->ref;
+										  vb->DirOfSearch =NoDirOfSearch;
+										  Real8 abcisse = k ? bb : aa;
+										  vb->r =  e->F( abcisse );
+										  VerticesOnGeomEdge[NbVerticesOnGeomEdge++]= VertexOnGeom(*vb,*e,abcisse);        
+
+										  // to take in account the sens of the edge
+
+										  s += lstep;
+										  edges[nbe].v[0]=va;
+										  edges[nbe].v[1]=vb;
+										  edges[nbe].ref = e->ref;
+										  edges[nbe].on = e;
+										  edges[nbe].adj[0] = PreviousNewEdge;
+										  if(PreviousNewEdge)
+											PreviousNewEdge->adj[1] = &edges[nbe];
+										  PreviousNewEdge = edges + nbe;
+										  nbe++;
+										  va = vb;
+									 }
+								  lcurve = lcurveb;
+								  e->SetMark();
+								  // cout << e-Gh.edges << ", " << k << " " 
+								  //      <<(*e)[k].r <<" " <<(*e)[1-k].r <<" " 
+								  //      << lcurve<< ";; " ;                          
+								  a=b;
+								  if (b->Required() ) break;
+								  int kprev=k;
+								  k = e->SensAdj[kprev];// next vertices
+								  e = e->Adj[kprev];
+								  assert(e);
+								 }// for(;;)
+							  vb = b->to;
+							  //            cout << endl;
+							  NbEdgeCurve = Max((Int4) (lcurve +0.5), (Int4) 1);
+							  NbNewPoints = NbEdgeCurve-1;
+							  if(!kstep)
+								 { NbVerticesOnGeomEdge0 += NbNewPoints;
+								  NbOfCurves++;}
+
+								  nbvend=nbv+NbNewPoints; 
+
+								  lstep = lcurve / NbEdgeCurve;
+								  //   cout <<"lstep " << lstep << " lcurve " 
+								  //    << lcurve << " NbEdgeCurve " << NbEdgeCurve << " " <<NbVerticesOnGeomEdge0<<" " <<NbVerticesOnGeomEdge<<" step =" <<step<<  endl;
+							 } 
+						  // end of curve --
+						  if (edges) { // last edges of the curves 
+							  edges[nbe].v[0]=va;
+							  edges[nbe].v[1]=vb;
+							  edges[nbe].ref = e->ref;
+							  edges[nbe].on = e;
+							  edges[nbe].adj[0] = PreviousNewEdge;
+							  edges[nbe].adj[1] = 0;
+							  if(PreviousNewEdge)
+								PreviousNewEdge->adj[1] = & edges[nbe];
+
+							  nbe++;}
+						  else
+							nbe += NbEdgeCurve;
+						 } // end on  curve ---
+				  } // if (edges[i][j].Corner())  
+			} // for (i=0;i<nbe;i++)
+			if(!step) {
+				// cout << "edges " << edges << " VerticesOnGeomEdge " <<VerticesOnGeomEdge << endl;
+				assert(!edges);
+				assert(!VerticesOnGeomEdge);
+				edges = new Edge[nbex=nbe];
+				if(NbVerticesOnGeomEdge0)
+				 VerticesOnGeomEdge = new VertexOnGeom[NbVerticesOnGeomEdge0];
+				assert(edges);
+				assert(VerticesOnGeomEdge || NbVerticesOnGeomEdge0 ==0);
+				// do the vertex on a geometrical vertex
+				NbVerticesOnGeomEdge0 = NbVerticesOnGeomEdge;       
+			}
+			else 
+			 assert(NbVerticesOnGeomEdge == NbVerticesOnGeomEdge0);
+			//     cout << " Nb of Curves = " << NbOfCurves << "nbe = " << nbe 
+			//	  << "== " << nbex << "  nbv = " << nbv <<  endl;
+			assert(nbex=nbe);
+		  } // for (step=0;step<2;step++)
+
+		Insert();
+		ForceBoundary();
+		FindSubDomain();
+
+		// NewPointsOld(*this) ;
+		NewPoints(*this,0) ;
+		CurrentTh = 0;
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::MakeGeometricalEdgeToEdge{{{1*/
+	Edge** Triangles::MakeGeometricalEdgeToEdge() {
+		assert(Gh.nbe);
+		Edge **e= new (Edge* [Gh.nbe]);
+
+		Int4 i;
+		for ( i=0;i<Gh.nbe ; i++)
+		 e[i]=NULL;
+		for ( i=0;i<nbe ; i++) 
+		  { 
+			Edge * ei = edges+i;
+			GeometricalEdge *on = ei->on; 
+			e[Gh.Number(on)] = ei;    
+		  }
+		for ( i=0;i<nbe ; i++) 
+		 for (int ii=0;ii<2;ii++) { 
+			 Edge * ei = edges+i;
+			 GeometricalEdge *on = ei->on;
+			 int j= ii;
+			 while (!(*on)[j].Required()) { 
+				 //	cout << i << " " << ii << " j= " << j << " curve = " 
+				 //           <<  on->CurveNumber << "  " << Gh.Number(on) << " on " << j 
+				 //   << " s0 " << Gh.Number( (*on)[0]) << " s1  " << Gh.Number( (*on)[1]) 
+				 //   << " ->  " ;
+				 Adj(on,j); // next geom edge
+				 j=1-j;
+				 //       cout << Gh.Number(on) << "  " << j  << " e[ON] =  " <<  e[Gh.Number(on)] 
+				 //    << " s0 " << Gh.Number( (*on)[0]) << " s1  " << Gh.Number( (*on)[1]) << endl; 
+				 if (e[Gh.Number(on)])  break; // optimisation     
+				 e[Gh.Number(on)] = ei; 
+			 }
+		 }
+
+		int kk=0;
+		for ( i=0;i<Gh.nbe ; i++)
+		 if (!e[i]) 
+		  if(kk++<10) {
+			  cerr << " Bug -- the geometrical edge " << i << " is on no edge curve = " << Gh.edges[i].CurveNumber 
+				 << " s0 " << Gh.Number( Gh.edges[i][0]) << " s1  " << Gh.Number( Gh.edges[i][1]) << endl; 
+			  //	 assert( e[i]);
+		  }
+		if(kk) MeshError(997,this);
+
+		return e;
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::SetIntCoor{{{1*/
+	void Triangles::SetIntCoor(const char * strfrom) {
+		pmin =  vertices[0].r;
+		pmax =  vertices[0].r;
+
+		// recherche des extrema des vertices pmin,pmax
+		Int4 i;
+		for (i=0;i<nbv;i++) {
+			pmin.x = Min(pmin.x,vertices[i].r.x);
+			pmin.y = Min(pmin.y,vertices[i].r.y);
+			pmax.x = Max(pmax.x,vertices[i].r.x);
+			pmax.y = Max(pmax.y,vertices[i].r.y);
+		}
+		R2 DD = (pmax-pmin)*0.05;
+		pmin = pmin-DD;
+		pmax = pmax+DD; 
+		coefIcoor= (MaxICoor)/(Max(pmax.x-pmin.x,pmax.y-pmin.y));
+		assert(coefIcoor >0);
+
+		// generation of integer coord  
+		for (i=0;i<nbv;i++) {
+			vertices[i].i = toI2(vertices[i].r);    
+		}
+
+		// computation of the det 
+		int Nberr=0;
+		for (i=0;i<nbt;i++)
+		  {
+			Vertex & v0 = triangles[i][0];
+			Vertex & v1 = triangles[i][1];
+			Vertex & v2 = triangles[i][2];
+			if ( &v0 && &v1 &&  &v2 ) // a good triangles;
+			  {
+				triangles[i].det= det(v0,v1,v2);
+				if (triangles[i].det <=0 && Nberr++ <10)
+				  {
+					if(Nberr==1)
+					 if (strfrom)
+					  cerr << "+++ Fatal Error " << strfrom << "(SetInCoor)  Error :  area of Triangle < 0 " << endl; 
+					 else 
+					  cerr << "+++  Fatal Error Triangle (in SetInCoor) area of Triangle < 0" << endl;
+					cerr << " Triangle " << i << "  det  (I2) = " << triangles[i].det ;
+					cerr << " (R2) " << Det(v1.r-v0.r,v2.r-v0.r);
+					cerr << "; The 3  vertices " << endl;
+					cerr << Number(v0) << " "  << Number(v1) << " " 
+					  << Number(v2) << " : " ;
+					cerr << v0.r << v1.r << v2.r << " ; ";
+					cerr << v0.i << v1.i << v2.i << endl;
+				  }
+			  }
+			else
+			 triangles[i].det= -1; // Null triangle; 
+		  }
+		if (Nberr) MeshError(899,this);
+
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::FillHoleInMesh{{{1*/
+	void Triangles::FillHoleInMesh() {
+
+		Triangles* OldCurrentTh =CurrentTh;
+		CurrentTh=this;
+
+		int verbosity=0;
+
+		// generation of the integer coordinate
+		  {
+
+			// find extrema coordinates of vertices pmin,pmax
+			Int4 i;
+			if(verbosity>2) printf("      Filling holes in mesh of %i vertices\n",nbv); 
+
+			//initialize ordre
+			assert(ordre);
+			for (i=0;i<nbv;i++) ordre[i]=0;
+
+			NbSubDomains =0;
+
+			/* generation of the adjacence of the triangles*/
+
+			SetOfEdges4* edge4= new SetOfEdges4(nbt*3,nbv);
+
+			//initialize st
+			Int4* st = new Int4[nbt*3];
+			for (i=0;i<nbt*3;i++) st[i]=-1;
+
+			//check number of edges
+			Int4 kk =0;
+			for (i=0;i<nbe;i++){
+				kk=kk+(i == edge4->addtrie(Number(edges[i][0]),Number(edges[i][1])));
+			}
+			if (kk != nbe) { 
+				throw ErrorException(__FUNCT__,exprintf("Some Double edge in the mesh, the number is %i",kk-nbe));
+			}
+
+			//
+			for (i=0;i<nbt;i++){
+				for (int j=0;j<3;j++) {
+					Int4 k =edge4->addtrie(Number(triangles[i][VerticesOfTriangularEdge[j][0]]),
+								Number(triangles[i][VerticesOfTriangularEdge[j][1]]));
+					Int4 invisible = triangles[i].Hidden(j);
+					if(st[k]==-1){
+						st[k]=3*i+j;
+					}
+					else if(st[k]>=0) {
+						assert( ! triangles[i].TriangleAdj(j) && !triangles[st[k] / 3].TriangleAdj((int) (st[k]%3)));
+
+						triangles[i].SetAdj2(j,triangles + st[k] / 3,(int) (st[k]%3));
+						if (invisible)  triangles[i].SetHidden(j);
+						if (k<nbe) {
+							triangles[i].SetLocked(j);
+						}
+						st[k]=-2-st[k]; 
+					}
+					else {
+						throw ErrorException(__FUNCT__,exprintf("The edge (%i , %i) belongs to more than 2 triangles",
+										Number(triangles[i][VerticesOfTriangularEdge[j][0]]),Number(triangles[i][VerticesOfTriangularEdge[j][1]])));
+					}
+				}
+			}
+			if(verbosity>5) {
+				printf("         info on Mesh %s:\n",name);
+				printf("            - number of vertices    = %i \n",nbv); 
+				printf("            - number of triangles   = %i \n",nbt); 
+				printf("            - number of given edges = %i \n",nbe); 
+				printf("            - number of all edges   = %i \n"  ,edge4->nb()); 
+				printf("            - Euler number 1 - nb of holes = %i \n"  ,nbt-edge4->nb()+nbv); 
+			}
+
+			// check the consistant of edge[].adj and the geometrical required  vertex
+			Int4 k=0;
+			for (i=0;i<edge4->nb();i++){
+				if (st[i] >=0){ // edge alone 
+					if (i < nbe) {
+						Int4 i0=edge4->i(i);
+						ordre[i0] = vertices+i0;
+						Int4 i1=edge4->j(i);
+						ordre[i1] = vertices+i1;
+					}
+					else {
+						k=k+1;
+						if (k <20) {
+							throw ErrorException(__FUNCT__,exprintf("Lost boundary edges %i : %i %i",i,edge4->i(i),edge4->j(i)));
+						}
+					}
+				}
+			}
+			if(k != 0) {
+				throw ErrorException(__FUNCT__,exprintf("%i boundary edges  are not defined as edges",k));
+			}
+
+			/* mesh generation with boundary points*/
+			Int4 nbvb = 0;
+			for (i=0;i<nbv;i++){ 
+				vertices[i].t=0;
+				vertices[i].vint=0;
+				if (ordre[i]){ 
+					ordre[nbvb++] = ordre[i];
+				}
+			}
+
+			Triangle* savetriangles= triangles;
+			Int4 savenbt=nbt;
+			Int4 savenbtx=nbtx;
+			SubDomain * savesubdomains = subdomains;
+			subdomains = 0;
+
+			Int4  Nbtriafillhole = 2*nbvb;
+			Triangle* triafillhole =new Triangle[Nbtriafillhole];
+			triangles =  triafillhole;
+
+			nbt=2;
+			nbtx= Nbtriafillhole;
+
+			for (i=2 ; det( ordre[0]->i, ordre[1]->i, ordre[i]->i ) == 0;) 
+			 if  ( ++i >= nbvb) {
+				 cerr << "FillHoleInMesh: All the vertices are aline " << nbvb << endl;
+				 MeshError(998,this); }
+				 Exchange( ordre[2], ordre[i]);
+
+				 Vertex *  v0=ordre[0], *v1=ordre[1];
+
+
+				 triangles[0](0) = 0; // sommet pour infini 
+				 triangles[0](1) = v0;
+				 triangles[0](2) = v1;
+
+				 triangles[1](0) = 0;// sommet pour infini 
+				 triangles[1](2) = v0;
+				 triangles[1](1) = v1;
+				 const int e0 = OppositeEdge[0];
+				 const int e1 = NextEdge[e0];
+				 const int e2 = PreviousEdge[e0];
+				 triangles[0].SetAdj2(e0, &triangles[1] ,e0);
+				 triangles[0].SetAdj2(e1, &triangles[1] ,e2);
+				 triangles[0].SetAdj2(e2, &triangles[1] ,e1);
+
+				 triangles[0].det = -1;  // faux triangles
+				 triangles[1].det = -1;  // faux triangles
+
+				 triangles[0].SetTriangleContainingTheVertex();
+				 triangles[1].SetTriangleContainingTheVertex();
+
+				 triangles[0].link=&triangles[1];
+				 triangles[1].link=&triangles[0];
+
+				 if (!quadtree ) 
+				  delete  quadtree; // ->ReInitialise();
+
+				 quadtree = new QuadTree(this,0);
+				 quadtree->Add(*v0);
+				 quadtree->Add(*v1);
+
+				 // We add the vertices one by one
+				 Int4 NbSwap=0;
+				 for (Int4 icount=2; icount<nbvb; icount++) {
+					 Vertex *vi  = ordre[icount];
+					 //	  cout << " Add vertex " <<  Number(vi) << endl;
+					 Icoor2 dete[3];
+					 Triangle *tcvi = FindTriangleContening(vi->i,dete);
+					 quadtree->Add(*vi); 
+					 Add(*vi,tcvi,dete);
+					 NbSwap += vi->Optim(1,1);
+				 }
+
+				 // inforce the boundary 
+				 TriangleAdjacent ta(0,0);
+				 Int4 nbloss = 0,knbe=0;
+				 for ( i = 0; i < nbe; i++){
+					 if (st[i] >=0){  // edge alone => on border ...  FH oct 2009
+						 Vertex & a=edges[i][0], & b =    edges[i][1];
+						 if (a.t && b.t) // le bug est la si maillage avec des bod non raffine 1.
+							{
+							 knbe++;
+							 if (ForceEdge(a,b,ta)<0)
+							  nbloss++;
+							}
+					 }
+				 }
+				 if(nbloss) {
+					 cerr << " we loss some  " << nbloss << " "  << " edges other " << knbe << endl;
+					 MeshError(1100,this);
+				 }
+
+				 FindSubDomain(1);
+				 // remove all the hole 
+				 // remove all the good sub domain
+				 Int4 krm =0;
+				 for (i=0;i<nbt;i++){
+					 if (triangles[i].link){ // remove triangles
+						 krm++;
+						 for (int j=0;j<3;j++)
+							{
+							 TriangleAdjacent ta =  triangles[i].Adj(j);
+							 Triangle & tta = * (Triangle *) ta;
+							 if(! tta.link) // edge between remove and not remove 
+								{ // change the link of ta;
+								 int ja = ta;
+								 Vertex *v0= ta.EdgeVertex(0);
+								 Vertex *v1= ta.EdgeVertex(1);
+								 Int4 k =edge4->addtrie(v0?Number(v0):nbv,v1? Number(v1):nbv);
+								 assert(st[k] >=0); 
+								 tta.SetAdj2(ja,savetriangles + st[k] / 3,(int) (st[k]%3));
+								 ta.SetLock();
+								 st[k]=-2-st[k]; 
+								}
+							}
+					 }
+				 }
+				 Int4 NbTfillHoll =0;
+				 for (i=0;i<nbt;i++){
+					 if (triangles[i].link) {
+						 triangles[i]=Triangle((Vertex *) NULL,(Vertex *) NULL,(Vertex *) NULL);
+						 triangles[i].color=-1;
+					 }
+					 else
+						{
+						 triangles[i].color= savenbt+ NbTfillHoll++;
+						}
+				 }
+				 // cout <<      savenbt+NbTfillHoll << " " <<  savenbtx  << endl;
+				 assert(savenbt+NbTfillHoll <= savenbtx );
+				 // copy of the outside triangles in saveTriangles 
+				 for (i=0;i<nbt;i++){
+					 if(triangles[i].color>=0) {
+						 savetriangles[savenbt]=triangles[i];
+						 savetriangles[savenbt].link=0;
+						 savenbt++;
+					 }
+				 }
+				 // gestion of the adj
+				 k =0;
+				 Triangle * tmax = triangles + nbt;
+				 for (i=0;i<savenbt;i++)  
+					{ 
+					 Triangle & ti = savetriangles[i];
+					 for (int j=0;j<3;j++)
+						{
+						 Triangle * ta = ti.TriangleAdj(j);
+						 int aa = ti.NuEdgeTriangleAdj(j);
+						 int lck = ti.Locked(j);
+						 if (!ta) k++; // bug 
+						 else if ( ta >= triangles && ta < tmax) 
+							{
+							 ta= savetriangles + ta->color;
+							 ti.SetAdj2(j,ta,aa);
+							 if(lck) ti.SetLocked(j);
+							}
+						}
+					}
+				 //	 OutSidesTriangles = triangles;
+				 //	Int4 NbOutSidesTriangles = nbt;
+
+				 // restore triangles;
+				 nbt=savenbt;
+				 nbtx=savenbtx;
+				 delete [] triangles;
+				 delete [] subdomains;
+				 triangles = savetriangles;
+				 subdomains = savesubdomains;
+				 //	 cout <<  triangles << " <> " << OutSidesTriangles << endl; 
+				 /*	 k=0;
+						 for (i=0;i<nbt;i++)
+						 for (int j=0;j<3;j++)
+						 if (!triangles[i].TriangleAdj(j))
+						 k++;
+						 */
+				 if (k) {
+					 cerr << "Error Nb of triangles edge alone = " << k << endl;
+					 MeshError(9997,this);
+				 }
+				 FindSubDomain();
+				 // cout << " NbTOld = " << NbTold << " ==  " << nbt - NbOutT << " " << nbt << endl;
+
+				 delete edge4;
+				 delete [] st;
+				 for (i=0;i<nbv;i++)
+				  quadtree->Add(vertices[i]);
+
+				 SetVertexFieldOn();
+
+				 for (i=0;i<nbe;i++)
+				  if(edges[i].on) 
+					for(int j=0;j<2;j++)
+					 if (!edges[i].adj[j])
+					  if(!edges[i][j].on->IsRequiredVertex()) {
+						  cerr << " Erreur adj et sommet requis edges [" << i <<  "][ " << j << "]= "
+							 <<  Number(edges[i][j]) << " : "  << " on = " << Gh.Number(edges[i].on) ;
+						  if (edges[i][j].on->OnGeomVertex())
+							cerr << " vertex " << Gh.Number(edges[i][j].on->gv);
+						  else if (edges[i][j].on->OnGeomEdge())
+							cerr << "Edges " << Gh.Number(edges[i][j].on->ge);
+						  else
+							cerr << " = " << edges[i][j].on ;
+						  cerr << endl;
+					  }
+		  }
+		CurrentTh=OldCurrentTh;
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::Optim{{{1*/
+	Int4  Triangle::Optim(Int2 i,int koption) {
+		// turne around in positif sens
+		Int4 NbSwap =0;
+		Triangle  *t = this;
+		int k=0,j =OppositeEdge[i];
+		int jp = PreviousEdge[j];
+		// initialise   tp, jp the previous triangle & edge
+		Triangle *tp= at[jp];
+		jp = aa[jp]&3;
+		do {
+			//    cout << *t << " " <<  j  << "\n\t try swap " ;
+			while (t->swap(j,koption))
+			  {
+				NbSwap++;
+				assert(k++<20000);
+				t=  tp->at[jp];      // set unchange t qnd j for previous triangles
+				j=  NextEdge[tp->aa[jp]&3];
+				//   cout << "\n\t s  " <<  *t << " " << j << endl;
+			  }
+			// end on this  Triangle 
+			tp = t;
+			jp = NextEdge[j];
+
+			t=  tp->at[jp];      // set unchange t qnd j for previous triangles
+			j=  NextEdge[tp->aa[jp]&3];
+
+		} while( t != this);
+		return NbSwap;
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::SmoothingVertex{{{1*/
+	void Triangles::SmoothingVertex(int nbiter,Real8 omega ) { 
+		long int verbosity=0;
+		//  if quatree exist remove it end reconstruct
+		if (quadtree) delete quadtree;
+		quadtree=0;
+		ReMakeTriangleContainingTheVertex();
+		Triangle vide; // a triangle to mark the boundary vertex
+		Triangle   ** tstart= new Triangle* [nbv];
+		Int4 i,j,k;
+		//   attention si Background == Triangle alors on ne peut pas utiliser la rechech rapide 
+		if ( this == & BTh)
+		 for ( i=0;i<nbv;i++)
+		  tstart[i]=vertices[i].t;     
+		else 
+		 for ( i=0;i<nbv;i++)
+		  tstart[i]=0;
+		for ( j=0;j<NbVerticesOnGeomVertex;j++ ) 
+		 tstart[ Number(VerticesOnGeomVertex[j].mv)]=&vide;
+		for ( k=0;k<NbVerticesOnGeomEdge;k++ ) 
+		 tstart[ Number(VerticesOnGeomEdge[k].mv)]=&vide;
+		if(verbosity>2) 
+		 cout << "  -- SmoothingVertex: nb Iteration = " << nbiter << " Omega = " << omega << endl;
+		for (k=0;k<nbiter;k++)
+		  {
+			Int4 i,NbSwap =0;
+			Real8 delta =0;
+			for ( i=0;i<nbv;i++)
+			 if (tstart[i] != &vide) // not a boundary vertex 
+			  delta=Max(delta,vertices[i].Smoothing(*this,BTh,tstart[i],omega));
+			if (!NbOfQuad)
+			 for ( i=0;i<nbv;i++)
+			  if (tstart[i] != &vide) // not a boundary vertex 
+				NbSwap += vertices[i].Optim(1);
+			if (verbosity>3)
+			 cout << "    Move max = " <<  sqrt(delta) << " iteration = " 
+				<< k << " Nb of Swap = " << NbSwap << endl;
+		  }
+
+		delete [] tstart;
+		if (quadtree) quadtree= new QuadTree(this);
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::MakeQuadTree{{{1*/
+	void Triangles::MakeQuadTree() {  
+		long int verbosity=0;
+		if(verbosity>8)
+		 cout << "      MakeQuadTree" << endl;
+		if (  !quadtree )  quadtree = new QuadTree(this);
+
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::ShowRegulaty{{{1*/
+	void  Triangles::ShowRegulaty() const {
+		const  Real8  sqrt32=sqrt(3.)*0.5; 
+		const Real8  aireKh=sqrt32*0.5;
+		D2  Beq(1,0),Heq(0.5,sqrt32);
+		D2xD2 Br(D2xD2(Beq,Heq).t());
+		D2xD2 B1r(Br.inv());
+		/*   D2xD2 BB = Br.t()*Br;
+			  cout << " BB = " << BB << " " << Br*B1r <<  endl; 
+			  MetricAnIso MMM(BB.x.x,BB.x.y,BB.y.y);
+			  MatVVP2x2 VMM(MMM);
+			  cout << " " << VMM.lambda1 << " " << VMM.lambda2 <<  endl; 
+			  */
+		double gammamn=1e100,hmin=1e100;
+		double gammamx=0,hmax=0;
+		double beta=1e100;
+		double beta0=0;
+		double  alpha2=0;
+		double area=0,Marea=0;
+		// Real8 cf= Real8(coefIcoor);
+		// Real8 cf2= 6.*cf*cf;
+		int nt=0;
+		for (int it=0;it<nbt;it++)
+		 if ( triangles[it].link) 
+			{
+			 nt++;
+			 Triangle &K=triangles[it];
+			 Real8  area3= Area2((R2) K[0],(R2) K[1],(R2) K[2])/6.;
+			 area+= area3;
+			 D2xD2 B_Kt(K[0],K[1],K[2]);
+			 D2xD2 B_K(B_Kt.t());
+			 D2xD2 B1K = Br*B_K.inv();
+			 D2xD2 BK =  B_K*B1r;
+			 D2xD2 B1B1 = B1K.t()*B1K;
+			 MetricAnIso MK(B1B1.x.x,B1B1.x.y,B1B1.y.y);
+			 MatVVP2x2 VMK(MK);
+			 alpha2 = Max(alpha2,Max(VMK.lambda1/VMK.lambda2,VMK.lambda2/VMK.lambda1));
+			 // cout << B_K << " * " << B1r << " == " << BK << " " << B_K*B_K.inv() << endl;
+			 Real8 betaK=0;
+
+			 for (int j=0;j<3;j++)
+				{
+				 Real8 he= Norme2(R2(K[j],K[(j+1)%3]));
+				 hmin=Min(hmin,he);
+				 hmax=Max(hmax,he);
+				 Vertex & v=K[j];
+				 D2xD2 M((MetricAnIso)v);
+				 betaK += sqrt(M.det());
+
+				 D2xD2 BMB = BK.t()*M*BK;
+				 MetricAnIso M1(BMB.x.x,BMB.x.y,BMB.y.y);
+				 MatVVP2x2 VM1(M1);
+				 //cout << B_K <<" " <<  M << " " <<  he << " " << BMB << " " << VM1.lambda1 << " " << VM1.lambda2<<   endl; 
+				 gammamn=Min3(gammamn,VM1.lambda1,VM1.lambda2);
+				 gammamx=Max3(gammamx,VM1.lambda1,VM1.lambda2);		
+				}
+			 betaK *= area3;//  1/2 (somme sqrt(det))* area(K)
+			 Marea+= betaK;
+			 // cout << betaK << " " << area3 << " " << beta << " " << beta0 << " " << area3*3*3*3 <<endl;
+			 beta=min(beta,betaK);
+			 beta0=max(beta0,betaK);
+			}   
+		area*=3; 
+		gammamn=sqrt(gammamn);
+		gammamx=sqrt(gammamx);    
+		cout << "  -- adaptmesh Regulary:  Nb triangles " << nt <<  " , h  min " << hmin  << " , h max " << hmax << endl;  
+		cout << "     area =  " << area << " , M area = " << Marea << " , M area/( |Khat| nt) " << Marea/(aireKh*nt) << endl; 
+		cout << "     infiny-regulaty:  min " << gammamn << "  max " << gammamx << endl;  
+		cout << "     anisomax  "<< sqrt(alpha2) << ", beta max = " << 1./sqrt(beta/aireKh) 
+		  << " min  "<<  1./sqrt(beta0/aireKh)  << endl;
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::ShowHistogram{{{1*/
+	void  Triangles::ShowHistogram() const {
+
+		const Int4 kmax=10;
+		const Real8 llmin = 0.5,llmax=2;
+		const Real8 lmin=log(llmin),lmax=log(llmax),delta= kmax/(lmax-lmin);
+		Int4 histo[kmax+1];
+		Int4 i,it,k, nbedges =0;
+		for (i=0;i<=kmax;i++) histo[i]=0;
+		for (it=0;it<nbt;it++)
+		 if ( triangles[it].link) 
+			{
+
+			 for (int j=0;j<3;j++)
+				{
+				 Triangle *ta = triangles[it].TriangleAdj(j);
+				 if ( !ta || !ta->link || Number(ta) >= it) 
+					{ 
+					 Vertex & vP = triangles[it][VerticesOfTriangularEdge[j][0]];
+					 Vertex & vQ = triangles[it][VerticesOfTriangularEdge[j][1]];
+					 if ( !& vP || !&vQ) continue;
+					 R2 PQ = vQ.r - vP.r;
+					 Real8 l = log(LengthInterpole(vP,vQ,PQ));
+					 nbedges++;
+					 k = (int) ((l - lmin)*delta);
+					 k = Min(Max(k,0L),kmax);
+					 histo[k]++;
+					}
+				}
+			}  
+		cout << "  -- Histogram of the unit mesh,  nb of edges" << nbedges << endl <<endl;
+
+		cout << "        length of edge in   | % of edge  | Nb of edges " << endl;
+		cout << "        ------------------- | ---------- | ----------- " << endl;
+		for   (i=0;i<=kmax;i++)
+		  { 
+			cout << "    " ;
+			cout.width(10);
+			if (i==0) cout  << " 0 " ;
+			else cout  << exp(lmin+i/delta) ;
+			cout.width(); cout << "," ;
+			cout.width(10);
+			if (i==kmax) cout << " +infty " ;
+			else cout  << exp(lmin+(i+1)/delta) ;
+			cout.width();cout << "   |   " ;
+
+			cout.precision(4);
+			cout.width(6);
+			cout <<  ((long)  ((10000.0 * histo[i])/ nbedges))/100.0 ;
+			cout.width();
+			cout.precision();
+			cout <<  "   |   " << histo[i] <<endl;
+		  }
+		cout << "        ------------------- | ---------- | ----------- " << endl <<endl;
+
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::Crack{{{1*/
+	int  Triangles::Crack() { 
+		assert(NbCrackedEdges ==0 || NbCrackedVertices >0); 
+		for (int i=0;i<NbCrackedEdges;i++)
+		 CrackedEdges[i].Crack();
+		return NbCrackedEdges;
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::UnCrack{{{1*/
+	int Triangles::UnCrack() { 
+		assert(NbCrackedEdges ==0 || NbCrackedVertices >0); 
+		for (int i=0;i<NbCrackedEdges;i++)
+		 CrackedEdges[i].UnCrack();
+		return NbCrackedEdges;
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::CrackMesh{{{1*/
+	int Triangles::CrackMesh() {
+		long int verbosity=0;
+		Triangles *CurrentThOld = CurrentTh;
+		//  computed the number of cracked edge
+		int i,k;
+		for (k=i=0;i<nbe;i++)
+		 if(edges[i].on->Cracked()) k++;
+		if( k==0) return 0;
+		CurrentTh = this;
+		cout << " Nb of Cracked Edges = " << k << endl;
+		NbCrackedEdges =k;
+		CrackedEdges = new  CrackedEdge[k];
+		//  new edge
+		Edge * e = new Edge[ nbe + k];
+
+		// copy
+		for (i=0;i<nbe;i++) 
+		 e[i] = edges[i];
+		delete edges;
+		edges = e;
+
+		const int  nbe0  = nbe;
+		for (k=i=0;i<nbe0;i++) // on double les arete cracked 
+		 if(edges[i].on->Cracked())
+			{
+			 e[nbe] = e[i];
+			 //  return the edge 
+			 e[nbe].v[0] =  e[i].v[1];
+			 e[nbe].v[1] =  e[i].v[0];
+			 e[nbe].on = e[i].on->link ; // fqux 
+			 CrackedEdges[k++]=CrackedEdge(edges,i,nbe);
+			 nbe++;
+			}
+		ReMakeTriangleContainingTheVertex() ; 
+		//  
+		int nbcrakev  =0;
+		Vertex *vlast = vertices + nbv;
+		Vertex *vend = vertices + nbvx; // end of array
+		for (int iv=0;iv<nbv;iv++) // vertex 
+		  {
+			Vertex & v= vertices[iv];
+			Vertex * vv = & v;  
+			int kk=0; // nb cracked
+			int kc=0; 
+			int kkk =0; // nb triangle  with same number 
+			Triangle * tbegin = v.t;
+			int i  = v.vint;       
+			assert(tbegin && (i >= 0 ) && (i <3));
+			// turn around the vertex v
+			TriangleAdjacent ta(tbegin,EdgesVertexTriangle[i][0]);// previous edge
+			int k=0;
+			do {
+				int kv = VerticesOfTriangularEdge[ta][1];
+				k++; 
+				Triangle * tt (ta);
+				if ( ta.Cracked() ) 
+				  {   
+					TriangleAdjacent tta=(ta.Adj());
+					assert(tta.Cracked());
+					if ( kk == 0) tbegin=ta,kkk=0;  //  begin by a cracked edge  => restart                
+					if (  kkk ) { kc =1;vv = vlast++;  kkk = 0; } // new vertex if use 
+					kk++;// number of cracked edge view                 
+				  }
+				if ( tt->link ) { // if good triangles store the value 
+					int it = Number(tt);
+					assert(it < nt);
+					(*tt)(kv)= vv; //   Change the vertex of triangle 
+					if(vv<vend) {*vv= v;vv->ReferenceNumber=iv;} // copy the vertex value + store the old vertex number in ref 
+					//	  tt->SetTriangleContainingTheVertex();
+					kkk++;
+				} else if (kk) { // crack + boundary 
+					if (  kkk ) { kc =1;vv = vlast++;  kkk = 0; } // new vertex if use 
+				}
+
+				ta = Next(ta).Adj(); 
+			} while ( (tbegin != ta)); 
+			assert(k);
+			if (kc)  nbcrakev++;
+		  }
+
+		if ( nbcrakev ) 
+		 for (int iec =0;iec < NbCrackedEdges; iec ++)
+		  CrackedEdges[iec].Set();
+
+		//  set the ref 
+		cout << " set the ref " <<  endl ;
+		NbCrackedVertices =   nbcrakev;
+		// int nbvo = nbv;
+		nbv = vlast - vertices;
+		int nbnewv =  nbv - nbv; // nb of new vrtices 
+		if (nbcrakev && verbosity > 1 )
+		 cout << " Nb of craked vertices = " << nbcrakev << " Nb of created vertices " <<   nbnewv<< endl;
+		// all the new vertices are on geometry 
+		//  BOFBO--  A VOIR
+		if (nbnewv)
+		  { // 
+			Int4 n = nbnewv+NbVerticesOnGeomVertex;
+			Int4 i,j,k;
+			VertexOnGeom * vog = new VertexOnGeom[n];
+			for ( i =0; i<NbVerticesOnGeomVertex;i++) 
+			 vog[i]=VerticesOnGeomVertex[i];
+			delete [] VerticesOnGeomVertex;
+			VerticesOnGeomVertex = vog;
+			// loop on cracked edge 
+			Vertex * LastOld = vertices + nbv - nbnewv;
+			for (int iec =0;iec < NbCrackedEdges; iec ++)
+			 for (k=0;k<2;k++)
+				{
+				 Edge & e = *( k ? CrackedEdges[iec].a.edge : CrackedEdges[iec].b.edge);
+				 for (j=0;j<2;j++) 
+					{
+					 Vertex * v = e(j);
+					 if ( v >=  LastOld)
+						{ // a new vertex 
+						 Int4 old = v->ReferenceNumber ; // the old same vertex 
+						 Int4 i  = ( v - LastOld);
+						 //  if the old is on vertex => warning
+						 // else the old is on edge => ok 
+						 vog[i] = vog[old];
+						 //  		    vog[i].mv = v;
+						 //g[i].ge = ;
+						 //og[i].abcisse = ;
+						}
+
+					}
+				}
+
+			NbVerticesOnGeomVertex = n;
+		  }
+		SetVertexFieldOn();
+
+
+		if (vlast >= vend)
+		  {  
+			cerr << " Not enougth vertices to crack the mesh we need " << nbv << " vertices " << endl;
+			MeshError(555,this);
+		  }
+		cout << "  NbCrackedVertices " <<  NbCrackedVertices << endl;
+		CurrentTh = CurrentThOld;
+		return  NbCrackedVertices;
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::FindTriangleContening{{{1*/
+	Triangle * Triangles::FindTriangleContening(const I2 & B,Icoor2 dete[3], Triangle *tstart) const {
+		Triangle * t=0;	
+		int j,jp,jn,jj;
+		if (tstart) 
+		 t=tstart;
+		else 
+		  {
+			assert(quadtree);
+			Vertex *a = quadtree->NearestVertex(B.x,B.y) ;
+
+			if (! a || !a->t ) {
+				if (a) 
+				  {cerr << " Attention PB TriangleConteningTheVertex  vertex number=" << Number(a) << endl;
+					cerr  << "We forget a call to ReMakeTriangleContainingTheVertex" << endl;}
+					cerr << " Pb with " << B << toR2(B) << endl;
+					MeshError(7777);
+			}
+			assert(a>= vertices && a < vertices+nbv);
+			//  int k=0;
+			t = a->t;
+			assert(t>= triangles && t < triangles+nbt);
+
+		  }
+		Icoor2  detop ;
+		int kkkk =0; // number of test triangle 
+
+		while ( t->det < 0) 
+		  { // the initial triangles is outside  
+			int k0=(*t)(0) ?  ((  (*t)(1) ? ( (*t)(2) ? -1 : 2) : 1  )) : 0;
+			assert(k0>=0); // k0 the NULL  vertex 
+			int k1=NextVertex[k0],k2=PreviousVertex[k0];
+			dete[k0]=det(B,(*t)[k1],(*t)[k2]);
+			dete[k1]=dete[k2]=-1;     
+			if (dete[k0] > 0) // outside B 
+			 return t; 
+			t = t->TriangleAdj(OppositeEdge[k0]);
+			assert(kkkk++ < 2);
+		  }
+
+		jj=0;
+		detop = det(*(*t)(VerticesOfTriangularEdge[jj][0]),*(*t)(VerticesOfTriangularEdge[jj][1]),B);
+
+		while(t->det  > 0 ) 
+		  { 
+			assert( kkkk++ < 2000 ); 
+			j= OppositeVertex[jj];
+			dete[j] = detop;  //det(*b,*s1,*s2);
+			jn = NextVertex[j];
+			jp = PreviousVertex[j];
+			dete[jp]= det(*(*t)(j),*(*t)(jn),B);
+			dete[jn] = t->det-dete[j] -dete[jp];
+
+			// count the number k of  dete <0
+			int k=0,ii[3];
+			if (dete[0] < 0 ) ii[k++]=0; 
+			if (dete[1] < 0 ) ii[k++]=1;
+			if (dete[2] < 0 ) ii[k++]=2;
+			// 0 => ok
+			// 1 => go in way 1
+			// 2 => two way go in way 1 or 2 randomly
+
+			if (k==0) 
+			 break;
+			if (k == 2 && BinaryRand())
+			 Exchange(ii[0],ii[1]);
+			assert ( k  < 3);
+			TriangleAdjacent t1 = t->Adj(jj=ii[0]);
+			if ((t1.det() < 0 ) && (k == 2))
+			 t1 = t->Adj(jj=ii[1]);
+			t=t1;
+			j=t1;// for optimisation we now the -det[OppositeVertex[j]];
+			detop = -dete[OppositeVertex[jj]];
+			jj = j;
+		  }
+
+		if (t->det<0) // outside triangle 
+		 dete[0]=dete[1]=dete[2]=-1,dete[OppositeVertex[jj]]=detop;
+		//  NbOfTriangleSearchFind += kkkk;  
+		return t;
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::IntersectGeomMetric{{{1*/
+	void Triangles::IntersectGeomMetric(const Real8 err=1,const int iso=0){
+		long int verbosity=0;
+
+		if(verbosity>1)
+		 cout << "  -- IntersectGeomMetric geometric err=" << err << (iso ? " iso " : " aniso "  ) << endl;
+		Real8 ss[2]={0.00001,0.99999};
+		Real8 errC = 2*sqrt(2*err);
+		Real8 hmax = Gh.MaximalHmax();
+		Real8 hmin = Gh.MinimalHmin();
+		Real8 maxaniso = 1e6;
+		assert(hmax>0);
+		SetVertexFieldOn();
+		if (errC > 1) errC = 1;
+		for (Int4  i=0;i<nbe;i++)
+		 for (int j=0;j<2;j++)
+			{
+
+			 Vertex V;
+			 VertexOnGeom GV;
+			 // cerr << Number(edges[i]) << " " << ss[j] << endl;
+			 Gh.ProjectOnCurve(edges[i],ss[j],V,GV);
+				{
+				 GeometricalEdge * eg = GV;
+				 Real8 s = GV;
+				 R2 tg;
+				 //	   cerr << i << " " << j << " " << Number(V) << " on = " 
+				 //	<< Gh.Number(eg) << " at s = " << s << " " << endl;
+				 Real8  R1= eg->R1tg(s,tg);
+				 // cerr << " R = " << 1/Max(R1,1e-20) << tg << " on x " 
+				 //    << V.r << errC/ Max(R1,1e-20) <<  " hold=" <<V.m(tg) << " "  << endl;
+				 Real8 ht = hmax;
+				 if (R1>1.0e-20) 
+					{  // err relative to the length of the edge
+					 ht = Min(Max(errC/R1,hmin),hmax);
+					}
+				 Real8 hn = iso? ht : Min(hmax,ht*maxaniso);
+				 //cerr << ht << " " << hn << "m=" << edges[i][j].m <<  endl;
+				 assert(ht>0 && hn>0);
+				 MatVVP2x2 Vp(1/(ht*ht),1/(hn*hn),tg);
+				 //cerr << " : " ;
+				 Metric MVp(Vp);
+				 // cerr << " : "  << MVp  << endl;
+				 edges[i][j].m.IntersectWith(MVp);
+				 //cerr << " . " << endl;
+				}
+
+			}
+		// the problem is for the vertex on vertex 
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::BoundAnisotropy{{{1*/
+	void  Triangles::BoundAnisotropy(Real8 anisomax,Real8 hminaniso) {
+		long int verbosity=0;
+
+		double lminaniso = 1/ (Max(hminaniso*hminaniso,1e-100));
+		if (verbosity > 1) 
+		 cout << "  -- BoundAnisotropy by  " << anisomax << endl; 
+		Real8 h1=1.e30,h2=1e-30,rx=0;
+		Real8 coef = 1./(anisomax*anisomax);
+		Real8 hn1=1.e30,hn2=1e-30,rnx =1.e-30;  
+		for (Int4 i=0;i<nbv;i++)
+		  {
+
+			MatVVP2x2 Vp(vertices[i]);
+			double lmax=Vp.lmax();
+			h1=Min(h1,Vp.lmin());
+			h2=Max(h2,Vp.lmax());
+			rx = Max(rx,Vp.Aniso2());
+
+			Vp *= Min(lminaniso,lmax)/lmax;
+
+			Vp.BoundAniso2(coef);
+
+			hn1=Min(hn1,Vp.lmin());
+			hn2=Max(hn2,Vp.lmax());
+			rnx = Max(rnx,Vp.Aniso2());
+
+
+			vertices[i].m = Vp;
+
+		  }
+
+		if (verbosity>2)
+		  {
+			cout << "     input :  Hmin = " << sqrt(1/h2)  << " Hmax = " << sqrt(1/h1) 
+			  << " factor of anisotropy max  = " << sqrt(rx) << endl;
+			cout << "     output:  Hmin = " << sqrt(1/hn2) << " Hmax = " << sqrt(1/hn1) 
+			  << " factor of anisotropy max  = " << sqrt(rnx) << endl;
+		  }
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::IntersectConsMetric{{{1*/
+	void Triangles::IntersectConsMetric(const double * s,const Int4 nbsol,const int * typsols,
+				const  Real8 hmin1,const Real8 hmax1,const Real8 coef,
+				const Real8 anisomax ,const Real8 CutOff,const int NbJacobi,
+				const int DoNormalisation,const double power,const int choice)
+	  { //  the array of solution s is store    
+		// sol0,sol1,...,soln    on vertex 0
+		//  sol0,sol1,...,soln   on vertex 1
+		//  etc.
+		//  choise = 0 =>  H is computed with green formule
+		//   otherwise  => H is computed from P2 on 4T 
+		const int dim = 2;
+
+		long int verbosity=0;
+
+		int sizeoftype[] = { 1, dim ,dim * (dim+1) / 2, dim * dim } ; 
+
+		// computation of the nb of field 
+		Int4 ntmp = 0;
+		if (typsols)
+		  {
+			for (Int4 i=0;i<nbsol;i++)
+			 ntmp += sizeoftype[typsols[i]];
+		  }
+		else
+		 ntmp = nbsol;
+
+		// n is the total number of fields
+
+		const Int4 n = ntmp;
+
+		Int4 i,k,iA,iB,iC,iv;
+		R2 O(0,0);
+		int RelativeMetric = CutOff>1e-30;
+		Real8 hmin = Max(hmin1,MinimalHmin());
+		Real8 hmax = Min(hmax1,MaximalHmax());
+		Real8 coef2 = 1/(coef*coef);
+
+		if(verbosity>1) 
+		  {
+			cout << "  -- Construction of Metric: Nb of field. " << n << " nbt = " 
+			  << nbt << " nbv= " << nbv 
+			  << " coef = " << coef << endl
+			  << "     hmin = " << hmin << " hmax=" << hmax 
+			  << " anisomax = " << anisomax <<  " Nb Jacobi " << NbJacobi << " Power = " << power ;
+			if (RelativeMetric)
+			 cout << " RelativeErr with CutOff= "  <<  CutOff << endl;
+			else
+			 cout << " Absolute Err" <<endl;
+		  }
+		double *ss=(double*)s;//, *ssiii = ss;
+
+		double sA,sB,sC;
+
+		Real8 *detT = new Real8[nbt];
+		Real8 *Mmass= new Real8[nbv];
+		Real8 *Mmassxx= new Real8[nbv];
+		Real8 *dxdx= new Real8[nbv];
+		Real8 *dxdy= new Real8[nbv];
+		Real8 *dydy= new Real8[nbv];
+		Real8 *workT= new Real8[nbt];
+		Real8 *workV= new Real8[nbv];
+		int *OnBoundary = new int[nbv];
+		for (iv=0;iv<nbv;iv++)
+		  {
+			Mmass[iv]=0;
+			OnBoundary[iv]=0;
+			Mmassxx[iv]=0;
+		  }
+
+		for (i=0;i<nbt;i++) 
+		 if(triangles[i].link) // the real triangles 
+			{
+			 const Triangle &t=triangles[i];
+			 // coor of 3 vertices 
+			 R2 A=t[0];
+			 R2 B=t[1];
+			 R2 C=t[2];
+
+
+			 // number of the 3 vertices
+			 iA = Number(t[0]);
+			 iB = Number(t[1]);
+			 iC = Number(t[2]);
+
+			 Real8 dett = bamg::Area2(A,B,C);
+			 detT[i]=dett;
+			 dett /= 6;
+
+			 // construction of on boundary 
+			 int nbb =0;
+			 for(int j=0;j<3;j++)
+				{
+				 Triangle *ta=t.Adj(j);
+				 if ( ! ta || !ta->link) // no adj triangle => edge on boundary
+				  OnBoundary[Number(t[VerticesOfTriangularEdge[j][0]])]=1,
+					 OnBoundary[Number(t[VerticesOfTriangularEdge[j][1]])]=1,
+					 nbb++;
+				}
+
+			 workT[i] = nbb;
+			 Mmass[iA] += dett;
+			 Mmass[iB] += dett;
+			 Mmass[iC] += dett;
+
+			 if((nbb==0)|| !choice)
+				{
+				 Mmassxx[iA] += dett;
+				 Mmassxx[iB] += dett;
+				 Mmassxx[iC] += dett;
+				}
+			}
+		 else
+		  workT[i]=-1;
+
+		for (Int4 nusol=0;nusol<nbsol;nusol++)
+		  { //for all Solution  
+
+			Real8 smin=ss[0],smax=ss[0];
+
+			Real8 h1=1.e30,h2=1e-30,rx=0;
+			Real8 coef = 1./(anisomax*anisomax);
+			Real8 hn1=1.e30,hn2=1e-30,rnx =1.e-30;  
+			int nbfield = typsols? sizeoftype[typsols[nusol]] : 1; 
+			if (nbfield == 1) 
+			 for ( iv=0,k=0; iv<nbv; iv++,k+=n )
+				{
+				 dxdx[iv]=dxdy[iv]=dydy[iv]=0;
+				 smin=Min(smin,ss[k]);
+				 smax=Max(smax,ss[k]);
+				}
+			else
+			  {
+				//  cas vectoriel 
+				for ( iv=0,k=0; iv<nbv; iv++,k+=n )
+				  {	
+					double v=0;		     
+					for (int i=0;i<nbfield;i++) 
+					 v += ss[k+i]*ss[k+i];
+					v = sqrt(v);
+					smin=Min(smin,v);
+					smax=Max(smax,v);
+				  }
+			  }
+			Real8 sdelta = smax-smin;
+			Real8 absmax=Max(Abs(smin),Abs(smax));
+			Real8 cnorm = DoNormalisation ? coef2/sdelta : coef2;
+
+			if(verbosity>2) 
+			 cout << "    Solution " << nusol <<  " Min = " << smin << " Max = " 
+				<< smax << " Delta =" << sdelta << " cnorm = " << cnorm <<  " Nb of fields =" << nbfield << endl;
+
+
+			if ( sdelta < 1.0e-10*Max(absmax,1e-20) && (nbfield ==1)) 
+			  {
+				if (verbosity>2)
+				 cout << "      Solution " << nusol << " is constant. We skip. " 
+					<< " Min = " << smin << " Max = " << smax << endl;
+				continue;
+			  }
+
+			double *sf  = ss; 
+			for (Int4 nufield=0;nufield<nbfield;nufield++,ss++) 
+			  {
+				for ( iv=0,k=0; iv<nbv; iv++,k+=n )
+				 dxdx[iv]=dxdy[iv]=dydy[iv]=0;
+				for (i=0;i<nbt;i++) 
+				 if(triangles[i].link)
+					{// for real all triangles 
+					 // coor of 3 vertices 
+					 R2 A=triangles[i][0];
+					 R2 B=triangles[i][1];
+					 R2 C=triangles[i][2];
+
+
+					 // warning the normal is internal and the 
+					 //   size is the length of the edge
+					 R2 nAB = Orthogonal(B-A);
+					 R2 nBC = Orthogonal(C-B);
+					 R2 nCA = Orthogonal(A-C);
+					 // remark :  nAB + nBC + nCA == 0 
+
+					 // number of the 3 vertices
+					 iA = Number(triangles[i][0]);
+					 iB = Number(triangles[i][1]);
+					 iC = Number(triangles[i][2]);
+
+					 // for the test of  boundary edge
+					 // the 3 adj triangles 
+					 Triangle *tBC = triangles[i].TriangleAdj(OppositeEdge[0]);
+					 Triangle *tCA = triangles[i].TriangleAdj(OppositeEdge[1]);
+					 Triangle *tAB = triangles[i].TriangleAdj(OppositeEdge[2]);
+
+					 // value of the P1 fonction on 3 vertices 
+					 sA = ss[iA*n];
+					 sB = ss[iB*n];
+					 sC = ss[iC*n];
+
+					 R2 Grads = (nAB * sC + nBC * sA + nCA * sB ) /detT[i] ;
+					 if(choice) 
+						{
+						 int nbb = 0;
+						 Real8 dd = detT[i];
+						 Real8 lla,llb,llc,llf;
+						 Real8  taa[3][3],bb[3];
+						 // construction of the trans of lin system
+						 for (int j=0;j<3;j++)
+							{
+							 int ie = OppositeEdge[j];
+							 TriangleAdjacent ta = triangles[i].Adj(ie);
+							 Triangle *tt = ta;
+							 if (tt && tt->link)
+								{
+								 Vertex &v = *ta.OppositeVertex();
+								 R2 V = v;
+								 Int4 iV = Number(v);
+								 Real8 lA  = bamg::Area2(V,B,C)/dd;
+								 Real8 lB  = bamg::Area2(A,V,C)/dd;
+								 Real8 lC  = bamg::Area2(A,B,V)/dd;
+								 taa[0][j] =  lB*lC;
+								 taa[1][j] =  lC*lA;
+								 taa[2][j] =  lA*lB;
+								 //Real8 xx = V.x-V.y;
+								 //Real8 yy = V.x + V.y;
+								 //cout << " iv " << ss[iV*n] << " == " << (8*xx*xx+yy*yy)
+								 //     << " l = " << lA << " " << lB << " " << lC 
+								 //     << " = " << lA+lB+lC << " " <<  V << " == " << A*lA+B*lB+C*lC << endl;
+
+								 lla = lA,llb=lB,llc=lC,llf=ss[iV*n] ;
+
+								 bb[j]     =  ss[iV*n] - ( sA*lA + sB*lB + sC*lC ) ;
+								}
+							 else
+								{
+								 nbb++;
+								 taa[0][j]=0;
+								 taa[1][j]=0;
+								 taa[2][j]=0;
+								 taa[j][j]=1;
+								 bb[j]=0;
+								}
+							}
+
+						 // resolution of 3x3 lineaire system transpose
+						 Real8 det33 =  det3x3(taa[0],taa[1],taa[2]);		
+						 Real8 cBC   =  det3x3(bb,taa[1],taa[2]);
+						 Real8 cCA   =  det3x3(taa[0],bb,taa[2]);
+						 Real8 cAB   =  det3x3(taa[0],taa[1],bb);
+
+						 assert(det33);
+						 //	det33=1;
+						 // verif
+						 //	cout << " " << (taa[0][0]*cBC +  taa[1][0]*cCA + taa[2][0] * cAB)/det33 << " == " << bb[0] ;
+						 //	cout << " " << (taa[0][1]*cBC +  taa[1][1]*cCA + taa[2][1] * cAB)/det33 << " == " << bb[1];
+						 //	cout << " " << (taa[0][2]*cBC +  taa[1][2]*cCA + taa[2][2] * cAB)/det33 << " == " << bb[2] 
+						 //	     << "  -- " ;
+						 //cout << lla*sA + llb*sB+llc*sC+ (lla*llb* cAB +  llb*llc* cBC + llc*lla*cCA)/det33 
+						 //   << " == " << llf <<  endl;
+						 // computation of the gradient in the element 
+
+						 // H( li*lj) = grad li grad lj + grad lj grad lj
+						 // grad li = njk  / detT ; with i j k =(A,B,C)
+						 Real8 Hxx = cAB * ( nBC.x*nCA.x) +  cBC * ( nCA.x*nAB.x) + cCA * (nAB.x*nBC.x);
+						 Real8 Hyy = cAB * ( nBC.y*nCA.y) +  cBC * ( nCA.y*nAB.y) + cCA * (nAB.y*nBC.y);
+						 Real8 Hxy = cAB * ( nBC.y*nCA.x) +  cBC * ( nCA.y*nAB.x) + cCA * (nAB.y*nBC.x) 
+							+ cAB * ( nBC.x*nCA.y) +  cBC * ( nCA.x*nAB.y) + cCA * (nAB.x*nBC.y);
+						 Real8 coef = 1.0/(3*dd*det33);
+						 Real8 coef2 = 2*coef;
+						 //	cout << " H = " << Hxx << " " << Hyy << " " <<  Hxy/2 << " coef2 = " << coef2 << endl;
+						 Hxx *= coef2;
+						 Hyy *= coef2;
+						 Hxy *= coef2;
+						 //cout << i  << " H = " << 3*Hxx/dd << " " << 3*Hyy/dd << " " <<  3*Hxy/(dd*2) << " nbb = " << nbb << endl;
+						 if(nbb==0)
+							{
+							 dxdx[iA] += Hxx;
+							 dydy[iA] += Hyy;
+							 dxdy[iA] += Hxy;
+
+							 dxdx[iB] += Hxx;
+							 dydy[iB] += Hyy;
+							 dxdy[iB] += Hxy;
+
+							 dxdx[iC] += Hxx;
+							 dydy[iC] += Hyy;
+							 dxdy[iC] += Hxy;
+							}
+
+						}
+					 else
+						{
+
+						 // if edge on boundary no contribution  => normal = 0
+						 if ( ! tBC || ! tBC->link ) nBC = O;
+						 if ( ! tCA || ! tCA->link ) nCA = O;
+						 if ( ! tAB || ! tAB->link ) nAB = O;
+
+						 // remark we forgot a 1/2 because
+						 //       $\\int_{edge} w_i = 1/2 $ if $i$ is in edge 
+						 //                          0  if not
+						 // if we don't take the  boundary 
+						 // dxdx[iA] += ( nCA.x + nAB.x ) *Grads.x;
+
+						 dxdx[iA] += ( nCA.x + nAB.x ) *Grads.x;
+						 dxdx[iB] += ( nAB.x + nBC.x ) *Grads.x;
+						 dxdx[iC] += ( nBC.x + nCA.x ) *Grads.x;
+
+						 // warning optimization (1) the divide by 2 is done on the metrix construction
+						 dxdy[iA] += (( nCA.y + nAB.y ) *Grads.x + ( nCA.x + nAB.x ) *Grads.y) ;
+						 dxdy[iB] += (( nAB.y + nBC.y ) *Grads.x + ( nAB.x + nBC.x ) *Grads.y) ;
+						 dxdy[iC] += (( nBC.y + nCA.y ) *Grads.x + ( nBC.x + nCA.x ) *Grads.y) ; 
+
+						 dydy[iA] += ( nCA.y + nAB.y ) *Grads.y;
+						 dydy[iB] += ( nAB.y + nBC.y ) *Grads.y;
+						 dydy[iC] += ( nBC.y + nCA.y ) *Grads.y;
+						}
+
+					} // for real all triangles 
+				Int4 kk=0;
+				for ( iv=0,k=0 ; iv<nbv; iv++,k+=n )
+				 if(Mmassxx[iv]>0) 
+					{
+					 dxdx[iv] /= 2*Mmassxx[iv];
+					 // warning optimization (1) on term dxdy[iv]*ci/2 
+					 dxdy[iv] /= 4*Mmassxx[iv];
+					 dydy[iv] /= 2*Mmassxx[iv];
+					 // Compute the matrix with abs(eigen value)
+					 Metric M(dxdx[iv], dxdy[iv], dydy[iv]);
+					 MatVVP2x2 Vp(M);
+					 //cout <<iv <<  "  M  = " <<  M <<  " aniso= " << Vp.Aniso() ;
+					 Vp.Abs();
+					 M = Vp;
+					 dxdx[iv] = M.a11;
+					 dxdy[iv] = M.a21;
+					 dydy[iv] = M.a22;
+					 //  cout << " (abs)  iv M  = " <<  M <<  " aniso= " << Vp.Aniso() <<endl;
+					}
+				 else kk++;
+
+
+				// correction of second derivate
+				// by a laplacien
+
+				Real8 *d2[3] = { dxdx, dxdy, dydy};
+				Real8 *dd;
+				for (int xy = 0;xy<3;xy++)
+				  {
+					dd = d2[xy];
+					// do leat 2 iteration for boundary problem
+					for (int ijacobi=0;ijacobi<Max(NbJacobi,2);ijacobi++)
+					  {
+						for (i=0;i<nbt;i++) 
+						 if(triangles[i].link) // the real triangles 
+							{
+							 // number of the 3 vertices
+							 iA = Number(triangles[i][0]);
+							 iB = Number(triangles[i][1]);
+							 iC = Number(triangles[i][2]);
+							 Real8 cc=3;
+							 if(ijacobi==0)
+							  cc = Max((Real8) ((Mmassxx[iA]>0)+(Mmassxx[iB]>0)+(Mmassxx[iC]>0)),1.);
+							 workT[i] = (dd[iA]+dd[iB]+dd[iC])/cc;
+							}
+						for (iv=0;iv<nbv;iv++)
+						 workV[iv]=0;
+
+						for (i=0;i<nbt;i++) 
+						 if(triangles[i].link) // the real triangles 
+							{
+							 // number of the 3 vertices
+							 iA = Number(triangles[i][0]);
+							 iB = Number(triangles[i][1]);
+							 iC = Number(triangles[i][2]);
+							 Real8 cc =  workT[i]*detT[i];
+							 workV[iA] += cc;
+							 workV[iB] += cc;
+							 workV[iC] += cc;
+							}
+
+						for (iv=0;iv<nbv;iv++)
+						 if( ijacobi<NbJacobi || OnBoundary[iv])
+						  dd[iv] = workV[iv]/(Mmass[iv]*6);
+
+
+					  }
+
+
+				  }
+
+				// constuction  of the metrix from the Hessian dxdx. dxdy,dydy
+
+				Real8 rCutOff=CutOff*absmax;// relative cut off 
+
+				for ( iv=0,k=0 ; iv<nbv; iv++,k+=n )
+				  { // for all vertices 
+					//{
+					//Metric M(dxdx[iv], dxdy[iv], dydy[iv]);
+					// MatVVP2x2 Vp(M);	  
+					//cout << " iv M="<<  M << "  Vp = " << Vp << " aniso  " << Vp.Aniso() << endl;
+					//}
+					MetricIso Miso;
+					// new code to compute ci ---	  
+					Real8 ci ;
+					if (RelativeMetric)
+					  { //   compute the norm of the solution
+						double xx =0,*sfk=sf+k; 
+						for (int ifield=0;ifield<nbfield;ifield++,sfk++)
+						 xx += *sfk* *sfk;	       
+						xx=sqrt(xx);
+						ci = coef2/Max(xx,rCutOff);
+					  }
+					else ci = cnorm;
+
+					// old 
+					//	  Real8 ci = RelativeMetric ? coef2/(Max(Abs(ss[k]),rCutOff)) : cnorm ;
+					//   modif F Hecht 101099
+					Metric Miv(dxdx[iv]*ci, dxdy[iv]*ci,  dydy[iv]*ci);
+					MatVVP2x2 Vp(Miv);
+
+					Vp.Abs();
+					if(power!=1.0) 
+					 Vp.pow(power);
+
+
+
+					h1=Min(h1,Vp.lmin());
+					h2=Max(h2,Vp.lmax());
+
+					Vp.Maxh(hmin);
+					Vp.Minh(hmax);
+
+					rx = Max(rx,Vp.Aniso2());
+
+					Vp.BoundAniso2(coef);
+
+					hn1=Min(hn1,Vp.lmin());
+					hn2=Max(hn2,Vp.lmax());
+					rnx = Max(rnx,Vp.Aniso2());
+
+					Metric MVp(Vp);
+					vertices[iv].m.IntersectWith(MVp);
+				  }// for all vertices 
+				if (verbosity>2)
+				  { 
+					cout << "              Field " << nufield << " of solution " << nusol  << endl;
+					cout << "              before bounding :  Hmin = " << sqrt(1/h2) << " Hmax = " 
+					  << sqrt(1/h1)  << " factor of anisotropy max  = " << sqrt(rx) << endl;
+					cout << "              after  bounding :  Hmin = " << sqrt(1/hn2) << " Hmax = " 
+					  << sqrt(1/hn1)  << " factor of anisotropy max  = " << sqrt(rnx) << endl;
+				  }
+			  } //  end of for all field
+		  }// end for all solution 
+
+		delete [] detT;
+		delete [] Mmass;
+		delete [] dxdx;
+		delete [] dxdy;
+		delete [] dydy;
+		delete []  workT;
+		delete [] workV;
+		delete [] Mmassxx;
+		delete []  OnBoundary;
+
+	  }
+	/*}}}1*/
+	/*FUNCTION Triangles::MaxSubDivision{{{1*/
+	void  Triangles::MaxSubDivision(Real8 maxsubdiv) {
+		long int verbosity=0;
+
+		const  Real8 maxsubdiv2 = maxsubdiv*maxsubdiv;
+		if(verbosity>1)
+		 cout << "  -- Limit the subdivision of a edges in the new mesh by " << maxsubdiv <<   endl  ;
+		// for all the edges 
+		// if the len of the edge is to long 
+		Int4 it,nbchange=0;    
+		Real8 lmax=0;
+		for (it=0;it<nbt;it++)
+		  {
+			Triangle &t=triangles[it];
+			for (int j=0;j<3;j++)
+			  {
+				Triangle &tt = *t.TriangleAdj(j);
+				if ( ! &tt ||  it < Number(tt) && ( tt.link || t.link)) 
+				  {
+					Vertex &v0 = t[VerticesOfTriangularEdge[j][0]];
+					Vertex &v1 = t[VerticesOfTriangularEdge[j][1]];
+					R2 AB= (R2) v1-(R2) v0;
+					Metric M = v0;
+					Real8 l = M(AB,AB);
+					lmax = Max(lmax,l);
+					if(l> maxsubdiv2)
+					  { R2 AC = M.Orthogonal(AB);// the ortogonal vector of AB in M
+						Real8 lc = M(AC,AC);
+						D2xD2 Rt(AB,AC);// Rt.x = AB , Rt.y = AC;
+						D2xD2 Rt1(Rt.inv());
+						D2xD2 D(maxsubdiv2,0,0,lc);
+						D2xD2 MM = Rt1*D*Rt1.t();
+						v0.m =  M = MetricAnIso(MM.x.x,MM.y.x,MM.y.y);
+						nbchange++;
+					  }
+					M = v1;
+					l = M(AB,AB);
+					lmax = Max(lmax,l);
+					if(l> maxsubdiv2)
+					  { R2 AC = M.Orthogonal(AB);// the ortogonal vector of AB in M
+						Real8 lc = M(AC,AC);
+						D2xD2 Rt(AB,AC);// Rt.x = AB , Rt.y = AC;
+						D2xD2 Rt1(Rt.inv());
+						D2xD2 D(maxsubdiv2,0,0,lc);
+						D2xD2  MM = Rt1*D*Rt1.t();
+						v1.m =  M = MetricAnIso(MM.x.x,MM.y.x,MM.y.y);
+						nbchange++;
+					  }
+
+
+				  }
+			  }
+		  }
+		if(verbosity>3)
+		 cout << "    Nb of metric change = " << nbchange 
+			<< " Max  of the subdivision of a edges before change  = " << sqrt(lmax) << endl;
+
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::SmoothMetric{{{1*/
+	void Triangles::SmoothMetric(Real8 raisonmax) { 
+		long int verbosity=0;
+
+		if(raisonmax<1.1) return;
+		if(verbosity > 1)
+		 cout << "  -- Triangles::SmoothMetric raisonmax = " << raisonmax << " " <<nbv <<endl;
+		ReMakeTriangleContainingTheVertex();
+		Int4 i,j,kch,kk,ip;
+		Int4 *first_np_or_next_t0 = new Int4[nbv];
+		Int4 *first_np_or_next_t1 = new Int4[nbv];
+		Int4 Head0 =0,Head1=-1;
+		Real8 logseuil= log(raisonmax);
+
+		for(i=0;i<nbv-1;i++)
+		 first_np_or_next_t0[i]=i+1; 
+		first_np_or_next_t0[nbv-1]=-1;// end;
+		for(i=0;i<nbv;i++)
+		 first_np_or_next_t1[i]=-1;
+		kk=0;
+		while (Head0>=0&& kk++<100) {
+			kch=0;
+			for (i=Head0;i>=0;i=first_np_or_next_t0[ip=i],first_np_or_next_t0[ip]=-1)
+			  {  //  pour tous les triangles autour du sommet s
+				// 	cout << kk << " i = " << i << " " << ip << endl;
+				register Triangle * t= vertices[i].t;
+				assert(t);
+				Vertex & vi = vertices[i];
+				TriangleAdjacent ta(t,EdgesVertexTriangle[vertices[i].vint][0]);
+				Vertex *pvj0 = ta.EdgeVertex(0);
+				while (1) {
+					//	  cout << i << " " <<  Number(ta.EdgeVertex(0)) << " "
+					//      << Number(ta.EdgeVertex(1)) << "  ---> " ;
+					ta=Previous(Adj(ta));
+					// cout <<  Number(ta.EdgeVertex(0)) << " " << Number(ta.EdgeVertex(1)) << endl;
+					assert(vertices+i == ta.EdgeVertex(1));
+					Vertex & vj = *(ta.EdgeVertex(0));
+					if ( &vj ) {
+						j= &vj-vertices;
+						assert(j>=0 && j < nbv);
+						R2 Aij = (R2) vj - (R2) vi;
+						Real8 ll =  Norme2(Aij);
+						if (0) {  
+							Real8 hi = ll/vi.m(Aij);
+							Real8 hj = ll/vj.m(Aij);
+							if(hi < hj)
+							  {
+								Real8 dh=(hj-hi)/ll;
+								//cout << " dh = " << dh << endl;
+								if (dh>logseuil) {
+									vj.m.IntersectWith(vi.m/(1 +logseuil*ll/hi));
+									if(first_np_or_next_t1[j]<0)
+									 kch++,first_np_or_next_t1[j]=Head1,Head1=j;
+								}
+							  }
+						} 
+						else
+						  {
+							Real8 li = vi.m(Aij);
+							//Real8 lj = vj.m(Aij);
+							//		if ( i == 2 || j == 2)
+							//  cout << " inter " << i << " " << j << " " << ((1 +logseuil*li)) <<  endl;
+							if( vj.m.IntersectWith(vi.m/(1 +logseuil*li)) )
+							 //if( vj.m.IntersectWith(vi.m*(lj/li/(1 +logseuil*lj))) )
+							 if(first_np_or_next_t1[j]<0) // if the metrix change 
+							  kch++,first_np_or_next_t1[j]=Head1,Head1=j;
+						  }
+					}
+					if  ( &vj ==  pvj0 ) break;
+				}
+			  }
+			Head0 = Head1;
+			Head1 = -1;
+			Exchange(first_np_or_next_t0,first_np_or_next_t1);
+			if(verbosity>5)
+			 cout << "     Iteration " << kk << " Nb de  vertices with change  " << kch << endl;
+		}
+		if(verbosity>2 && verbosity < 5) 
+		 cout << "    Nb of Loop " << kch << endl;
+		delete [] first_np_or_next_t0;
+		delete [] first_np_or_next_t1;
+	}
+	/*}}}1*/
+	/*FUNCTION Triangles::NearestVertex{{{1*/
+	Vertex * Triangles::NearestVertex(Icoor1 i,Icoor1 j) {
+		return  quadtree->NearestVertex(i,j); 
+	} 
+	/*}}}1*/
+	/*FUNCTION Triangles::PreInit{{{1*/
+	void Triangles::PreInit(Int4 inbvx,char *fname) {
+		long int verbosity=0;
+
+		srand(19999999);
+		OnDisk =0;
+		NbRef=0;
+		//  allocGeometry=0;
+		identity=0;
+		NbOfTriangleSearchFind =0;
+		NbOfSwapTriangle =0;
+		nbiv=0;
+		nbv=0;
+		nbvx=inbvx;
+		nbt=0;
+		NbOfQuad = 0;
+		nbtx=2*inbvx-2;
+		NbSubDomains=0;
+		NbVertexOnBThVertex=0;
+		NbVertexOnBThEdge=0;
+		VertexOnBThVertex=0;
+		VertexOnBThEdge=0;
+
+		NbCrackedVertices=0;
+		NbCrackedEdges =0;
+		CrackedEdges  =0;  
+		nbe = 0; 
+		name = fname ;
+
+		if (inbvx) {
+			vertices=new Vertex[nbvx];
+			assert(vertices);
+			ordre=new (Vertex* [nbvx]);
+			assert(ordre);
+			triangles=new Triangle[nbtx];
+			assert(triangles);}
+		else {
+			vertices=0;
+			ordre=0;
+			triangles=0;
+			nbtx=0;
+		}
+		if ( name || inbvx)
+		  {
+			time_t timer =time(0);
+			char buf[70];     
+			strftime(buf ,70,", Date: %y/%m/%d %H:%M %Ss",localtime(&timer));
+			counter++; 
+			char countbuf[30];   
+			sprintf(countbuf,"%d",counter);
+			int lg =0 ;
+			if (&BTh != this && BTh.name)
+			 lg = strlen(BTh.name)+4;
+			identity = new char[ lg + strlen(buf) + strlen(countbuf)+ 2  + 10 + ( Gh.name ? strlen(Gh.name) + 4 : 0)];
+			identity[0]=0;
+			if (lg)
+			 strcat(strcat(strcat(identity,"B="),BTh.name),", ");
+
+			if (Gh.name)
+			 strcat(strcat(identity,"G="),Gh.name);
+			strcat(strcat(identity,";"),countbuf);
+			strcat(identity,buf);
+			// cout << "New MAILLAGE "<< identity << endl;
+		  } 
+
+		quadtree=0;
+		//  edgescomponante=0;
+		edges=0;
+		VerticesOnGeomVertex=0;
+		VerticesOnGeomEdge=0;
+		NbVerticesOnGeomVertex=0;
+		NbVerticesOnGeomEdge=0;
+		//  nbMaxIntersectionTriangles=0;
+		//  lIntTria;
+		subdomains=0;
+		NbSubDomains=0;
+		//  Meshbegin = vertices;
+		//  Meshend  = vertices + nbvx;
+		if (verbosity>98) 
+		 cout << "Triangles::PreInit() " << nbvx << " " << nbtx 
+			<< " " << vertices 
+			<< " " << ordre << " " <<  triangles <<endl;
+	}
+	/*}}}1*/
+
+} // end of namespace bamg 
