ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/toIbrep/src/toibrep.cpp
Revision: 285
Committed: Sat Oct 8 00:28:41 2011 UTC (13 years, 7 months ago) by francois
File size: 56057 byte(s)
Log Message:
mailleur de delaunay non contraint par les frontieres d'une carte de taille a priori 

File Contents

# User Rev Content
1 bechet 105 #include "gestionversion.h"
2 francois 259 #include "toibrep.h"
3 francois 104 #include "mg_file.h"
4     #include "ot_mathematique.h"
5     #include "tpl_map_entite.h"
6 francois 222 #include "tpl_relation_entite.h"
7 francois 104 #include "tpl_octree.h"
8 francois 259 #include "toibrep_point.h"
9 francois 106 #include "vct.h"
10 francois 104 #include <math.h>
11 francois 259 #include <fstream>
12 francois 262 #include <string>
13 francois 259 #include "IBrep.h"
14 francois 276 #include "ot_cpu.h"
15 francois 104
16    
17 francois 222
18 francois 276 TOIBREP::TOIBREP(class MG_GESTIONNAIRE *g,class MG_GEOMETRIE *ge,class FEM_MAILLAGE* femm,int nbpas,OT_CPU* compt):geo(ge),gest(g),mai(femm),NPAS(nbpas),affichageactif(0),compteur(compt)
19 francois 104 {
20     }
21    
22 francois 276 TOIBREP::TOIBREP(class MG_GESTIONNAIRE *g,class MG_GEOMETRIE *ge,class FEM_MAILLAGE* femm,int nbpas):geo(ge),gest(g),mai(femm),NPAS(nbpas),affichageactif(0),compteur(NULL)
23     {
24     }
25     TOIBREP::TOIBREP(class MG_GESTIONNAIRE *g,class MG_GEOMETRIE *ge,class FEM_MAILLAGE* femm):geo(ge),gest(g),mai(femm),NPAS(50),affichageactif(0),compteur(NULL)
26     {
27     }
28     TOIBREP::TOIBREP(class MG_GESTIONNAIRE *g,class MG_GEOMETRIE *ge,class FEM_MAILLAGE* femm,class OT_CPU* compt):geo(ge),gest(g),mai(femm),NPAS(50),affichageactif(0),compteur(compt)
29     {
30     }
31 francois 104
32 francois 259 TOIBREP::~TOIBREP()
33 francois 104 {
34     }
35    
36    
37    
38 francois 276 void TOIBREP::active_affichage(void (*fonc)(char*))
39     {
40     affiche=fonc;
41     affichageactif=1;
42     }
43    
44     int TOIBREP::compare_etat(int etat,int valeur)
45     {
46 francois 281 if ((etat==1) && (valeur==INTERIEUR)) return 1;
47     if ((etat==3) && (valeur==INTERIEUR)) return 1;
48     if ((etat==3) && (valeur==STRICTINTERIEUR)) return 1;
49     if ((etat==1) && (valeur==SUR_FACE)) return 1;
50 francois 276 return 0;
51     }
52    
53    
54    
55 francois 259 int TOIBREP::estdansletetra(FEM_TETRA *tet,double x,double y, double z)
56 francois 104 {
57 francois 222 double *xyz1,*xyz2,*xyz3,*xyz4;
58     if (tet->get_nb_fem_noeud()==4)
59     {
60     xyz1=tet->get_fem_noeud(0)->get_coord();
61     xyz2=tet->get_fem_noeud(1)->get_coord();
62     xyz3=tet->get_fem_noeud(2)->get_coord();
63     xyz4=tet->get_fem_noeud(3)->get_coord();
64     }
65     if (tet->get_nb_fem_noeud()==10)
66     {
67     xyz1=tet->get_fem_noeud(0)->get_coord();
68     xyz2=tet->get_fem_noeud(2)->get_coord();
69     xyz3=tet->get_fem_noeud(4)->get_coord();
70     xyz4=tet->get_fem_noeud(9)->get_coord();
71     }
72 francois 104 OT_VECTEUR_3D v1(xyz2[0]-xyz1[0],xyz2[1]-xyz1[1],xyz2[2]-xyz1[2]);
73     OT_VECTEUR_3D v2(xyz3[0]-xyz1[0],xyz3[1]-xyz1[1],xyz3[2]-xyz1[2]);
74     OT_VECTEUR_3D v3(xyz4[0]-xyz1[0],xyz4[1]-xyz1[1],xyz4[2]-xyz1[2]);
75     OT_VECTEUR_3D v4(x-xyz1[0],y-xyz1[1],z-xyz1[2]);
76     OT_MATRICE_3D mat(v1,v2,v3);
77     OT_MATRICE_3D mat1(v4,v2,v3);
78     OT_MATRICE_3D mat2(v1,v4,v3);
79     OT_MATRICE_3D mat3(v1,v2,v4);
80     double det=mat.get_determinant();
81     double xsi=mat1.get_determinant()/det;
82     double eta=mat2.get_determinant()/det;
83     double dseta=mat3.get_determinant()/det;
84 francois 276 int reponse1=1;
85     int reponse2=1;
86 francois 281 double eps=0.0000001;
87 francois 276 if (xsi<-eps) reponse1=0;
88     if (eta<-eps) reponse1=0;
89     if (dseta<-eps) reponse1=0;
90     if (xsi+eta+dseta>1.+eps) reponse1=0;
91     if (xsi<eps) reponse2=0;
92     if (eta<eps) reponse2=0;
93     if (dseta<eps) reponse2=0;
94     if (xsi+eta+dseta>1.-eps) reponse2=0;
95     return reponse1+2*reponse2;
96 francois 104 }
97    
98 francois 276
99    
100 francois 259 double TOIBREP::calculdist(double *n,double x,double y,double z,FEM_NOEUD* noeud)
101 francois 104 {
102     double* xyz=noeud->get_coord();
103     double dist=sqrt((xyz[0]-x)*(xyz[0]-x)+(xyz[1]-y)*(xyz[1]-y)+(xyz[2]-z)*(xyz[2]-z));
104     OT_VECTEUR_3D vec1(n[0],n[1],n[2]);
105     OT_VECTEUR_3D vec2(xyz[0]-x,xyz[1]-y,xyz[2]-z);
106     double ps=vec1*vec2;
107     if (ps<0.) dist=-dist;
108     return dist;
109     }
110    
111 francois 281 void TOIBREP::recherche_arete_tangeante(TPL_MAP_ENTITE<MG_ARETE*> &lst,TPL_MAP_ENTITE<MG_ELEMENT_TOPOLOGIQUE*> &lsttopo)
112     {
113    
114    
115     LISTE_MG_ARETE::iterator it;
116     for (MG_ARETE* are=geo->get_premier_arete(it);are!=NULL;are=geo->get_suivant_arete(it))
117     {
118     if (lsttopo.existe(are))
119     if (ot.arete_virtuelle(are)) lst.ajouter(are);
120     }
121    
122     }
123    
124    
125 francois 259 //void TOIBREP::importer(std::string nomfichier,class MagXchange* data,std::string nomfichierout)
126 francois 276 IBrep TOIBREP::importer(std::string nomfichier,std::string nomfichieribrep,MG_GROUPE_TOPOLOGIQUE* mggt)
127 francois 104 {
128 francois 222 TPL_MAP_ENTITE<MG_ELEMENT_TOPOLOGIQUE*> lst;
129     if (mggt!=NULL)
130     {
131     int nb=mggt->get_nb();
132     for (int i=0;i<nb;i++)
133     {
134     lst.ajouter(mggt->get(i));
135     mggt->get(i)->get_topologie_sousjacente(&lst);
136     }
137     }
138     else
139     {
140     int nbvol=geo->get_nb_mg_volume();
141     for (int i=0;i<nbvol;i++)
142     {
143     lst.ajouter(geo->get_mg_volume(i));
144     geo->get_mg_volume(i)->get_topologie_sousjacente(&lst);
145     }
146     }
147 francois 281 affiche((char*)"Recherche aretes tangeantes");
148     TPL_MAP_ENTITE<MG_ARETE*> lstaretetan;
149     recherche_arete_tangeante(lstaretetan,lst);
150     char mess[300];
151     sprintf(mess," Nombre d'aretes tangeantes %d",lstaretetan.get_nb());
152     affiche(mess);
153     if (compteur!=NULL) compteur->ajouter_etape("Aretes tangeantes");
154     affiche((char*)"Traitement de base");
155     int nbface=geo->get_nb_mg_face();
156 francois 222 int nbvraiface=0;
157     TPL_MAP_ENTITE<MG_ELEMENT_TOPOLOGIQUE*>::ITERATEUR it;
158     for (MG_ELEMENT_TOPOLOGIQUE* ele=lst.get_premier(it);ele!=NULL;ele=lst.get_suivant(it))
159     if (ele->get_dimension()==2) nbvraiface++;
160 francois 276 //if (compteur!=NULL) compteur->ajouter_etape("Traitement de base selection");
161 francois 222 int nb_noeud=mai->get_nb_fem_noeud();
162 francois 276 int nb_tetra=mai->get_nb_fem_tetra();
163     std::string nomfichier2=nomfichier+"_dis.sol";
164 francois 281 FEM_SOLUTION* solution=new FEM_SOLUTION(mai,nbvraiface+lstaretetan.get_nb(),(char*)nomfichier2.c_str(),nb_noeud,"LS",ENTITE_NOEUD);
165 francois 222 int i=0;
166 francois 276 gest->ajouter_fem_solution(solution);
167     nomfichier2=nomfichier+"_ele.sol";
168 francois 281 FEM_SOLUTION* solution_ele=new FEM_SOLUTION(mai,nbvraiface+lstaretetan.get_nb(),(char*)nomfichier2.c_str(),nb_tetra,"A",ENTITE_TETRA);
169 francois 276 gest->ajouter_fem_solution(solution_ele);
170 francois 222 for (MG_ELEMENT_TOPOLOGIQUE* ele=lst.get_premier(it);ele!=NULL;ele=lst.get_suivant(it))
171 francois 106 {
172 francois 222 if (ele->get_dimension()!=2) continue;
173 francois 106 char mess[255];
174 francois 262 sprintf(mess,"F %lu",ele->get_id());
175 francois 276 solution->change_legende(i,mess);
176     solution_ele->change_legende(i,mess);
177 francois 222 ++i;
178 francois 106 }
179 francois 281 TPL_MAP_ENTITE<MG_ARETE*>::ITERATEUR itare;
180     for (MG_ARETE* are=lstaretetan.get_premier(itare);are!=NULL;are=lstaretetan.get_suivant(itare))
181     {
182     char mess[255];
183     sprintf(mess,"A %lu",are->get_id());
184     solution->change_legende(i,mess);
185     solution_ele->change_legende(i,mess);
186     ++i;
187     }
188 francois 276
189 francois 281
190 francois 276 //if (compteur!=NULL) compteur->ajouter_etape("Traitement de base creation solution");
191 francois 104 double xmin=1e300,ymin=1e300,zmin=1e308;
192     double xmax=-1e300,ymax=-1e300,zmax=-1e308;
193 francois 222 TPL_MAP_ENTITE<FEM_NOEUD*> lst_noeud;
194     LISTE_FEM_NOEUD::iterator it2;
195     i=0;
196     for (FEM_NOEUD* noeud=mai->get_premier_noeud(it2);noeud!=NULL;noeud=mai->get_suivant_noeud(it2))
197 francois 104 {
198     double* xyz=noeud->get_coord();
199     if (xyz[0]<xmin) xmin=xyz[0];
200     if (xyz[1]<ymin) ymin=xyz[1];
201     if (xyz[2]<zmin) zmin=xyz[2];
202     if (xyz[0]>xmax) xmax=xyz[0];
203     if (xyz[1]>ymax) ymax=xyz[1];
204     if (xyz[2]>zmax) zmax=xyz[2];
205 francois 281 for (int j=0;j<nbvraiface+lstaretetan.get_nb();j++)
206 francois 106 solution->ecrire(i,j,1e300);
207 francois 104 lst_noeud.ajouter(noeud);
208 francois 222 i++;
209 francois 104 }
210 francois 276 //if (compteur!=NULL) compteur->ajouter_etape("Traitement de base recherche boite");
211 francois 104 octree.initialiser(&lst_noeud,1,xmin,ymin,zmin,xmax,ymax,zmax);
212 francois 276 //if (compteur!=NULL) compteur->ajouter_etape("Traitement de base ini octree");
213 francois 222 LISTE_FEM_TETRA::iterator it3;
214 francois 276 i=0;
215 francois 222 for (FEM_TETRA* tet=mai->get_premier_tetra(it3);tet!=NULL;tet=mai->get_suivant_tetra(it3))
216 francois 276 {
217     octree.inserer(tet);
218 francois 281 for (int j=0;j<nbvraiface+lstaretetan.get_nb();j++)
219 francois 276 solution_ele->ecrire(i,j,0);
220     i++;
221     }
222     if (compteur!=NULL) compteur->ajouter_etape("Traitement de base");
223 francois 106 for (int i=0;i<nbface;i++)
224     {
225 francois 281 MG_FACE* face=geo->get_mg_face(i);
226 francois 276 if (affichageactif)
227     {
228     char mess[300];
229 francois 281 sprintf(mess," Face %d numero %lu",i,face->get_id());
230 francois 276 affiche(mess);
231     }
232 francois 222 if (!lst.existe(face)) continue;
233 francois 106 vector<MG_FACE*> lstface;
234 francois 222 lstface.push_back(face);
235 francois 276 /// ici topologie virtuelle
236    
237    
238 francois 222 /*TPL_LISTE_ENTITE<double> lst;
239 francois 106 int type=face->get_surface()->get_type_geometrique(lst);
240     int idem=0;
241     for (int j=0;j<i;j++)
242     {
243     TPL_LISTE_ENTITE<double> lst2;
244     MG_FACE* face2=geo->get_mg_face(j);
245     int type2=face2->get_surface()->get_type_geometrique(lst2);
246     if (type==type2)
247     if (lst.get_nb()==lst2.get_nb())
248     {
249     int diff=0;
250     for (int i=0;i<lst.get_nb();i++)
251     if (fabs(lst.get(i)-lst2.get(i))>0.000001) diff=1;
252     if (diff==0) idem=1;
253     }
254     }
255     if (!idem) lstface.push_back(geo->get_mg_face(i));
256     for (int j=i+1;j<nbface;j++)
257     {
258     TPL_LISTE_ENTITE<double> lst2;
259     MG_FACE* face2=geo->get_mg_face(j);
260     int type2=face2->get_surface()->get_type_geometrique(lst2);
261     if (type==type2)
262     if (lst.get_nb()==lst2.get_nb())
263     {
264     int diff=0;
265     for (int i=0;i<lst.get_nb();i++)
266     if (fabs(lst.get(i)-lst2.get(i))>0.000001) diff=1;
267     if (diff==0) lstface.push_back(face2);
268     }
269 francois 222 }*/
270 francois 276 levelsetn(&lst,&lstface,solution,solution_ele,i);
271 francois 106 }
272 francois 281
273     TPL_MAP_ENTITE<MG_ARETE*>::ITERATEUR itare2;
274     i=0;
275     for (MG_ARETE* are=lstaretetan.get_premier(itare2);are!=NULL;are=lstaretetan.get_suivant(itare2))
276     {
277     if (affichageactif)
278     {
279     char mess[300];
280     sprintf(mess," Arete tangeante %d numero %lu",i,are->get_id());
281     affiche(mess);
282     }
283     traite_arete_tangeante(are,nbface+i,solution,solution_ele);
284     i++;
285     }
286    
287    
288 francois 276 affiche((char*)"Exportation IBREP");
289     IBrep brep=exporter_IBrep(nomfichieribrep,solution,solution_ele,mggt);
290     if (compteur!=NULL) compteur->ajouter_etape("Exportation IBREP");
291     return brep;
292 francois 106 }
293    
294 francois 281 void TOIBREP::traite_arete_tangeante(MG_ARETE* are,int numsol,FEM_SOLUTION* solution,FEM_SOLUTION* solution_ele)
295 francois 106 {
296 francois 281 //NPAS=150;
297     solution->active_solution(numsol);
298     solution_ele->active_solution(numsol);
299 francois 259 vector<TOIBREP_POINT*> lst;
300 francois 281 LISTE_FEM_TETRA::iterator ittetra;
301     for (FEM_TETRA* tet=mai->get_premier_tetra(ittetra);tet!=NULL;tet=mai->get_suivant_tetra(ittetra))
302     tet->change_etat(0);
303     LISTE_FEM_NOEUD::iterator itnoeud;
304     for (FEM_NOEUD* no=mai->get_premier_noeud(itnoeud);no!=NULL;no=mai->get_suivant_noeud(itnoeud))
305     no->change_etat(0);
306     double tmin=are->get_tmin();
307     double tmax=are->get_tmax();
308     double eps=1e-3*(tmax-tmin);
309     for (int i=0;i<NPAS+1;i++)
310     {
311     double t=tmin+i*1.0/NPAS*(tmax-tmin);
312     double xyz[3],xyzplus[3],xyzmoins[3];
313     are->evaluer(t,xyz);
314     TOIBREP_POINT *pt=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],t,1,NULL);
315     lst.push_back(pt);
316     if (t+eps<tmax)
317     {
318     are->evaluer(t+eps,xyzplus);
319     pt->ajoute_point_eps(xyzplus);
320     }
321     if (t-eps>tmin)
322     {
323     are->evaluer(t-eps,xyzmoins);
324     pt->ajoute_point_eps(xyzmoins);
325     }
326    
327     }
328     for (int i=0;i<lst.size();i++)
329     {
330     TOIBREP_POINT* pt=lst[i];
331     double xyz[3];
332     pt->get_coord3(xyz);
333     TPL_MAP_ENTITE<FEM_TETRA*> liste;
334     octree.rechercher(xyz[0],xyz[1],xyz[2],0.,liste);
335     TPL_MAP_ENTITE<FEM_TETRA*>::ITERATEUR it;
336     for (FEM_TETRA* tet=liste.get_premier(it);tet!=NULL;tet=liste.get_suivant(it))
337     {
338     if (tet->get_etat()==1) continue;
339     int etat=estdansletetra(tet,xyz[0],xyz[1],xyz[2]);
340     if ((compare_etat(etat,SUR_FACE)) && (pt->get_interieur()))
341 francois 104 {
342 francois 281 int nbeps=pt->get_nb_point_eps();
343     for (int k=0;k<nbeps;k++)
344     {
345     double xyztmp[3];
346     pt->get_point_eps(k,xyztmp);
347     int etattmp=estdansletetra(tet,xyztmp[0],xyztmp[1],xyztmp[2]);
348     if (compare_etat(etattmp,SUR_FACE)) {etat=STRICTINTERIEUR;break;}
349     if (compare_etat(etattmp,INTERIEUR)) {etat=STRICTINTERIEUR;break;}
350     if (compare_etat(etattmp,STRICTINTERIEUR)) {etat=STRICTINTERIEUR;break;}
351     }
352 francois 104 }
353 francois 281 if (compare_etat(etat,STRICTINTERIEUR))
354     {
355     for (int k=0;k<tet->get_nb_fem_noeud();k++)
356     {
357     double dist=calcul_distance_level_ortho(tet->get_fem_noeud(k),are,pt);
358     tet->get_fem_noeud(k)->change_solution(dist);
359     tet->get_fem_noeud(k)->change_numero(pt->get_id());
360     tet->change_etat(1); //temp
361     tet->get_fem_noeud(k)->change_etat(1); //temp
362     }
363     }
364     }
365     }
366     remplir_trou_tangeant(&lst,are,solution_ele);
367    
368    
369    
370     int i=0;
371     for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
372     {
373     if (noeud->get_etat()==1) solution->ecrire(i,numsol,noeud->get_solution());
374     else solution->ecrire(i,numsol,1e300);
375     ++i;
376 francois 106 }
377 francois 281 i=0;
378     for (FEM_TETRA* tet=mai->get_premier_tetra(ittetra);tet!=NULL;tet=mai->get_suivant_tetra(ittetra))
379     {
380     if (tet->get_etat()==1) solution_ele->ecrire(i,numsol,1.);
381     ++i;
382     }
383     int nbpt=lst.size();
384     for (int i=0;i<nbpt;i++) delete lst[i];
385     TOIBREP_POINT::remisecompteurid();
386 francois 106 }
387 francois 281
388    
389     void TOIBREP::echantillonne_sommets(std::vector<TOIBREP_POINT*> &lst,MG_FACE* face)
390 francois 106 {
391 francois 276 TPL_MAP_ENTITE<MG_SOMMET*> lstsom;
392     int nbbou=face->get_nb_mg_boucle();
393     for (int i=0;i<nbbou;i++)
394     {
395     MG_BOUCLE* boucle=face->get_mg_boucle(i);
396     int nb_arete=boucle->get_nb_mg_coarete();
397     for (int j=0;j<nb_arete;j++)
398     {
399     MG_ARETE* are=boucle->get_mg_coarete(j)->get_arete();
400     lstsom.ajouter(are->get_cosommet1()->get_sommet());
401     lstsom.ajouter(are->get_cosommet2()->get_sommet());
402     }
403     }
404     TPL_MAP_ENTITE<MG_SOMMET*>::ITERATEUR it;
405     for (MG_SOMMET* som=lstsom.get_premier(it);som!=NULL;som=lstsom.get_suivant(it))
406     {
407     double xyz[3];
408     som->get_point()->evaluer(xyz);
409     double uv[2];
410     face->inverser(uv,xyz);
411     int N=NPAS;
412     double rayon=1e-2;
413     for (int k=0;k<N+1;k++)
414     {
415     double uv2[2];
416     uv2[0]=uv[0]+rayon*cos(k*1.0/N*2.*M_PI);
417     uv2[1]=uv[1]+rayon*sin(k*1.0/N*2.*M_PI);
418     if ((face->valide_parametre_u(uv2[0])) && (face->valide_parametre_v(uv2[1])))
419     {
420     double distance=ot.calcule_distance_contour_face_uv(uv2,face);
421     if (distance>0.)
422     {
423     double xyz[3];
424     face->evaluer(uv2,xyz);
425     TOIBREP_POINT *pt=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],uv[0],uv[1],1,face);
426     lst.push_back(pt);
427     }
428     }
429     }
430    
431     }
432     }
433 francois 281 void TOIBREP::echantillonne_aretes(std::vector<TOIBREP_POINT*> &lst,MG_FACE* face)
434 francois 276 {
435 francois 281 echantillonne_sommets(lst,face);
436 francois 276 int nbbou=face->get_nb_mg_boucle();
437     for (int i=0;i<nbbou;i++)
438     {
439     MG_BOUCLE* boucle=face->get_mg_boucle(i);
440     int nb_arete=boucle->get_nb_mg_coarete();
441     for (int j=0;j<nb_arete;j++)
442     {
443     MG_ARETE* are=boucle->get_mg_coarete(j)->get_arete();
444     double tmin=are->get_tmin();
445     double tmax=are->get_tmax();
446     double N=NPAS;
447     for (int k=0;k<N+1;k++)
448     {
449     double t=tmin+k*1.0/N*(tmax-tmin);
450     double xyz[3];
451     are->evaluer(t,xyz);
452     TOIBREP_POINT *pt=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],t,1,face);
453     lst.push_back(pt);
454     // octree.inserer(pt);
455     }
456     /* double t=tmin+0.2/NPAS*(tmax-tmin);
457     double xyz[3];
458     are->evaluer(t,xyz);
459     TOIBREP_POINT *pt1=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],t,1,face);
460     lst.push_back(pt1);
461     t=tmax-0.2/NPAS*(tmax-tmin);
462     are->evaluer(t,xyz);
463     TOIBREP_POINT *pt2=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],t,1,face);
464     lst.push_back(pt2);*/
465    
466    
467    
468     }
469     }
470     }
471    
472     void TOIBREP::levelsetn(TPL_MAP_ENTITE<MG_ELEMENT_TOPOLOGIQUE*> *lsttopo,vector<MG_FACE*> *lstface,class FEM_SOLUTION* solution,FEM_SOLUTION* solution_ele,int numsol)
473     {
474     if (affichageactif)
475     {
476     char mess[300];
477     sprintf(mess," Echantillonnage");
478     affiche(mess);
479     }
480    
481     solution->active_solution(numsol);
482     solution_ele->active_solution(numsol);
483     int nbface=lstface->size();
484     if (nbface==0) return;
485     vector<TOIBREP_POINT*> lst;
486     BOITE_2D boite=ot.get_boite_2D((*lstface)[0]);
487 francois 281 echantillonne_aretes(lst,(*lstface)[0]);
488 francois 276 for (int iface=1;iface<nbface;iface++)
489     {
490     MG_FACE* face=(*lstface)[iface];
491     BOITE_2D boiteface=ot.get_boite_2D(face);
492     boite=boite+boiteface;
493 francois 281 echantillonne_aretes(lst,(*lstface)[iface]);
494 francois 276 }
495     MG_FACE* face=(*lstface)[0];
496     int trouve=0;
497     int orientation;
498     int j=0;
499     do
500     {
501     MG_COFACE* coface=face->get_mg_coface(j);
502     MG_VOLUME* vol=coface->get_coquille()->get_mg_volume();
503     if (lsttopo->existe(vol))
504 francois 104 {
505 francois 276 orientation=coface->get_orientation();
506     trouve=1;
507     }
508     j++;
509     }
510     while (trouve==0);
511     LISTE_FEM_TETRA::iterator ittetra;
512     for (FEM_TETRA* tet=mai->get_premier_tetra(ittetra);tet!=NULL;tet=mai->get_suivant_tetra(ittetra))
513     tet->change_etat(0);
514     LISTE_FEM_NOEUD::iterator itnoeud;
515     for (FEM_NOEUD* no=mai->get_premier_noeud(itnoeud);no!=NULL;no=mai->get_suivant_noeud(itnoeud))
516     no->change_etat(0);
517     double umin=boite.get_xmin();
518     double umax=boite.get_xmax();
519     double vmin=boite.get_ymin();
520     double vmax=boite.get_ymax();
521     if (face->get_surface()->est_periodique_u())
522     {
523     umin=0;
524     umax=face->get_surface()->get_periode_u();
525     }
526     if (face->get_surface()->est_periodique_v())
527     {
528     vmin=0;
529     vmax=face->get_surface()->get_periode_v();
530     }
531 francois 281 double epsu=1e-3*(umax-umin);
532     double epsv=1e-3*(vmax-vmin);
533     for (int i=0;i<NPAS;i++)
534     for (int j=0;j<NPAS;j++)
535 francois 276 {
536     double uv[2];
537 francois 281 uv[0]=umin+(i*1.0+0.5)/NPAS*(umax-umin);
538     uv[1]=vmin+(j*1.0+0.5)/NPAS*(vmax-vmin);
539 francois 276 double xyz[3];
540     if ((face->valide_parametre_u(uv[0])) && (face->valide_parametre_v(uv[1])))
541     {
542     double distance=ot.calcule_distance_contour_face_uv(uv,face);
543     int inte=0;
544     if (distance>0.) inte=1.; else continue;
545     face->evaluer(uv,xyz);
546     TOIBREP_POINT *pt=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],uv[0],uv[1],inte,face);
547     lst.push_back(pt);
548 francois 281 if (uv[0]+epsu<umax)
549     {
550     double uvtmp[2]={uv[0]+epsu,uv[1]};
551     double distance=ot.calcule_distance_contour_face_uv(uvtmp,face);
552     if (distance>1e-8)
553     {
554     face->evaluer(uvtmp,xyz);
555     pt->ajoute_point_eps(xyz);
556     }
557     }
558     if (uv[0]-epsu>umin)
559     {
560     double uvtmp[2]={uv[0]-epsu,uv[1]};
561     double distance=ot.calcule_distance_contour_face_uv(uvtmp,face);
562     if (distance>1e-8)
563     {
564     face->evaluer(uvtmp,xyz);
565     pt->ajoute_point_eps(xyz);
566     }
567     }
568     if (uv[1]+epsv<vmax)
569     {
570     double uvtmp[2]={uv[0],uv[1]+epsv};
571     double distance=ot.calcule_distance_contour_face_uv(uvtmp,face);
572     if (distance>1e-8)
573     {
574     face->evaluer(uvtmp,xyz);
575     pt->ajoute_point_eps(xyz);
576     }
577     }
578     if (uv[1]-epsv>vmin)
579     {
580     double uvtmp[2]={uv[0],uv[1]-epsv};
581     double distance=ot.calcule_distance_contour_face_uv(uvtmp,face);
582     if (distance>1e-8)
583     {
584     face->evaluer(uvtmp,xyz);
585     pt->ajoute_point_eps(xyz);
586     }
587     }
588 francois 276 // octree.inserer(pt);
589     }
590     }
591     // debut temp
592     /*
593     MG_GESTIONNAIRE gestemp;
594     MG_MAILLAGE *mai=new MG_MAILLAGE(NULL);
595     gestemp.ajouter_mg_maillage(mai);
596     for (int i=0;i<lst.size();i++)
597     {
598     double xyz[3];
599     lst[i]->get_coord3(xyz);
600     MG_NOEUD* no=new MG_NOEUD(NULL,xyz[0],xyz[1],xyz[2],TRIANGULATION);
601     mai->ajouter_mg_noeud(no);
602     if (i!=0) {MG_SEGMENT* seg=new MG_SEGMENT(NULL,no,mai->get_mg_noeud(mai->get_nb_mg_noeud()-2),TRIANGULATION);mai->ajouter_mg_segment(seg);}
603     }
604    
605     gestemp.enregistrer("debug.magic");
606     */
607     // fin temp
608     if (compteur!=NULL) compteur->ajouter_etape("Echantillonnage");
609     if (affichageactif)
610     {
611     char mess[300];
612     sprintf(mess," Preparation newton");
613     affiche(mess);
614     }
615     calcullevelsetpremierepasse(face,orientation,&lst,0,lst.size());
616     if (compteur!=NULL) compteur->ajouter_etape("Preparation newton");
617    
618     if (affichageactif)
619     {
620     char mess[300];
621     sprintf(mess," Newton");
622     affiche(mess);
623     }
624     calcullevelsetdeuxiemepasse(&lst);
625     if (compteur!=NULL) compteur->ajouter_etape("Newton");
626     if (affichageactif)
627     {
628     char mess[300];
629     sprintf(mess," Remplissage des trous");
630     affiche(mess);
631     }
632     remplir_trou(&lst,face,orientation);
633     if (compteur!=NULL) compteur->ajouter_etape("Remplissage des trous");
634     //etendrelevelset(solution,numsol);
635     int i=0;
636     for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
637     {
638 francois 280 if (noeud->get_etat()==1) solution->ecrire(i,numsol,noeud->get_solution());
639 francois 276 else solution->ecrire(i,numsol,1e300);
640     ++i;
641     }
642     i=0;
643     for (FEM_TETRA* tet=mai->get_premier_tetra(ittetra);tet!=NULL;tet=mai->get_suivant_tetra(ittetra))
644     {
645 francois 280 if (tet->get_etat()==1) solution_ele->ecrire(i,numsol,1.);
646 francois 276 ++i;
647     }
648     int nbpt=lst.size();
649     for (int i=0;i<nbpt;i++) delete lst[i];
650     TOIBREP_POINT::remisecompteurid();
651    
652    
653    
654     }
655 francois 281 void TOIBREP::remplir_trou_tangeant(std::vector<TOIBREP_POINT*> *lst,MG_ARETE* are,FEM_SOLUTION *solution_ele)
656     {
657     MG_FACE* face1=are->get_mg_coarete(0)->get_boucle()->get_mg_face();
658     MG_FACE* face2=are->get_mg_coarete(1)->get_boucle()->get_mg_face();
659     TPL_MAP_ENTITE<FEM_TETRA*> lst_tetra_concerne;
660     int num1,num2;
661     int nbchamp=solution_ele->get_nb_champ();
662     for (int i=0;i<nbchamp;i++)
663     {
664     std::string nom=solution_ele->get_legende(i);
665     char nom2[2];
666     unsigned long id;
667     sscanf(nom.c_str(),"%s %lu",nom2,&id);
668     if (id==face1->get_id()) num1=i;
669     if (id==face2->get_id()) num2=i;
670     }
671     LISTE_FEM_TETRA::iterator ittet;
672     int i=0;
673     for (FEM_TETRA* tet=mai->get_premier_tetra(ittet);tet!=NULL;tet=mai->get_suivant_tetra(ittet))
674     {
675     if (solution_ele->lire(i,num1)>0.000001)
676     lst_tetra_concerne.ajouter(tet);
677     if (solution_ele->lire(i,num2)>0.000001)
678     lst_tetra_concerne.ajouter(tet);
679     i++;
680     }
681 francois 276
682 francois 281
683     int couche_active;
684     int nb_couche=0;
685     do
686     {
687     nb_couche++;
688     TPL_MAP_ENTITE<FEM_TETRA*>::ITERATEUR ittetra;
689     std::vector<FEM_TETRA*> couche;
690     couche_active=0;
691     for (FEM_TETRA* tet=lst_tetra_concerne.get_premier(ittetra);tet!=NULL;tet=lst_tetra_concerne.get_suivant(ittetra))
692     {
693     if (tet->get_etat()!=0) continue;
694     FEM_NOEUD *no1=tet->get_fem_noeud(0);
695     FEM_NOEUD *no2=tet->get_fem_noeud(1);
696     FEM_NOEUD *no3=tet->get_fem_noeud(2);
697     FEM_NOEUD *no4=tet->get_fem_noeud(3);
698     int nbactif=0;
699     int nbpositif=0;
700     if ((no1->get_etat()==1) || (no1->get_etat()==-1))
701     {
702     nbactif++;
703     if (no1->get_solution()>0.) nbpositif++;
704     }
705     if ((no2->get_etat()==1) || (no2->get_etat()==-1))
706     {
707     nbactif++;
708     if (no2->get_solution()>0.) nbpositif++;
709     }
710     if ((no3->get_etat()==1) || (no3->get_etat()==-1))
711     {
712     nbactif++;
713     if (no3->get_solution()>0.) nbpositif++;
714     }
715     if ((no4->get_etat()==1) || (no4->get_etat()==-1))
716     {
717     nbactif++;
718     if (no4->get_solution()>0.) nbpositif++;
719     }
720     if ((nbactif==3) && (nbpositif<3) && (nbpositif>0))
721     {
722     couche.push_back(tet);
723     }
724     }
725     for (int i=0;i<couche.size();i++)
726     {
727     FEM_TETRA* tet=couche[i];
728     FEM_NOEUD *no1=tet->get_fem_noeud(0);
729     FEM_NOEUD *no2=tet->get_fem_noeud(1);
730     FEM_NOEUD *no3=tet->get_fem_noeud(2);
731     FEM_NOEUD *no4=tet->get_fem_noeud(3);
732     TOIBREP_POINT* pt;
733     FEM_NOEUD* noeudref;
734     if (no1->get_etat()==0) {noeudref=no1;pt=(*lst)[no2->get_numero()];}
735     if (no2->get_etat()==0) {noeudref=no2;pt=(*lst)[no1->get_numero()];}
736     if (no3->get_etat()==0) {noeudref=no3;pt=(*lst)[no1->get_numero()];}
737     if (no4->get_etat()==0) {noeudref=no4;pt=(*lst)[no1->get_numero()];}
738     MG_FACE* face=pt->get_mg_face();
739     double t,xyz[3];
740     double dist=calcul_distance_level_ortho(noeudref,are,pt,t,xyz);
741     noeudref->change_solution(dist);
742     noeudref->change_etat(2);
743     TOIBREP_POINT *nvpt=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],t,0.,1,NULL);
744     lst->push_back(nvpt);
745     noeudref->change_numero(nvpt->get_id());
746     }
747     for (FEM_TETRA* tet=lst_tetra_concerne.get_premier(ittetra);tet!=NULL;tet=lst_tetra_concerne.get_suivant(ittetra))
748     {
749     FEM_NOEUD *no1=tet->get_fem_noeud(0);
750     FEM_NOEUD *no2=tet->get_fem_noeud(1);
751     FEM_NOEUD *no3=tet->get_fem_noeud(2);
752     FEM_NOEUD *no4=tet->get_fem_noeud(3);
753     if (no1->get_etat()!=0)
754     if (no2->get_etat()!=0)
755     if (no3->get_etat()!=0)
756     if (no4->get_etat()!=0)
757     if (tet->get_etat()==0)
758     {
759     int reactive=0;
760     for (int i=0;i<tet->get_nb_fem_noeud();i++)
761     {
762     if (reactive) continue;
763     FEM_NOEUD* no=tet->get_fem_noeud(i);
764     TOIBREP_POINT *pt=(*lst)[no->get_numero()];
765     double t;
766     pt->get_coord1(t);
767     double eps=1e-4*(are->get_tmax()-are->get_tmin());
768     if ((t>=are->get_tmin()-eps) && (t<are->get_tmax()+eps))
769     {
770     tet->change_etat(1);
771     no1->change_etat(1);
772     no2->change_etat(1);
773     no3->change_etat(1);
774     no4->change_etat(1);
775     reactive=1;
776     couche_active=1;
777    
778     }
779    
780     }
781     if (!reactive)
782     {
783     if (no1->get_etat()==2) no1->change_etat(-1);
784     if (no2->get_etat()==2) no2->change_etat(-1);
785     if (no3->get_etat()==2) no3->change_etat(-1);
786     if (no4->get_etat()==2) no4->change_etat(-1);
787     tet->change_etat(-1);
788     }
789     }
790     }
791     }
792     while (couche_active==1);
793     TPL_MAP_ENTITE<FEM_TETRA*>::ITERATEUR ittetra;
794     for (FEM_TETRA* tet=lst_tetra_concerne.get_premier(ittetra);tet!=NULL;tet=lst_tetra_concerne.get_suivant(ittetra))
795     {
796     if (tet->get_etat()!=1) continue;
797     FEM_NOEUD *no1=tet->get_fem_noeud(0);
798     FEM_NOEUD *no2=tet->get_fem_noeud(1);
799     FEM_NOEUD *no3=tet->get_fem_noeud(2);
800     FEM_NOEUD *no4=tet->get_fem_noeud(3);
801     int nbpositif=0;
802     int nbnegatif=0;
803     double epsdist=1e-6*tet->get_boite_3D().get_rayon();
804     if (no1->get_solution()>epsdist) nbpositif++;
805     if (no1->get_solution()<-epsdist) nbnegatif++;
806     if (no2->get_solution()>epsdist) nbpositif++;
807     if (no2->get_solution()<-epsdist) nbnegatif++;
808     if (no3->get_solution()>epsdist) nbpositif++;
809     if (no3->get_solution()<-epsdist) nbnegatif++;
810     if (no4->get_solution()>epsdist) nbpositif++;
811     if (no4->get_solution()<-epsdist) nbnegatif++;
812     if (!(((nbnegatif>0) && (nbpositif>0)) ||(nbnegatif+nbpositif==1)))
813     tet->change_etat(0);
814     }
815     }
816    
817    
818 francois 276 void TOIBREP::remplir_trou(std::vector<TOIBREP_POINT*> *lst,MG_FACE* face,int sens)
819     {
820     int castot=0;
821     int cas=0;
822 francois 280 int couche_active;
823     int nb_couche=0;
824 francois 281 LISTE_FEM_TETRA::iterator ittetra;
825 francois 280 do
826     {
827     nb_couche++;
828 francois 281
829 francois 280 std::vector<FEM_TETRA*> couche;
830     couche_active=0;
831     for (FEM_TETRA* tet=mai->get_premier_tetra(ittetra);tet!=NULL;tet=mai->get_suivant_tetra(ittetra))
832 francois 276 {
833 francois 280 if (tet->get_etat()!=0) continue;
834 francois 276 FEM_NOEUD *no1=tet->get_fem_noeud(0);
835     FEM_NOEUD *no2=tet->get_fem_noeud(1);
836     FEM_NOEUD *no3=tet->get_fem_noeud(2);
837     FEM_NOEUD *no4=tet->get_fem_noeud(3);
838     int nbactif=0;
839     int nbpositif=0;
840 francois 280 if ((no1->get_etat()==1) || (no1->get_etat()==-1))
841 francois 276 {
842     nbactif++;
843     if (no1->get_solution()>0.) nbpositif++;
844     }
845 francois 280 if ((no2->get_etat()==1) || (no2->get_etat()==-1))
846 francois 276 {
847     nbactif++;
848     if (no2->get_solution()>0.) nbpositif++;
849     }
850 francois 280 if ((no3->get_etat()==1) || (no3->get_etat()==-1))
851 francois 276 {
852     nbactif++;
853     if (no3->get_solution()>0.) nbpositif++;
854     }
855 francois 280 if ((no4->get_etat()==1) || (no4->get_etat()==-1))
856 francois 276 {
857     nbactif++;
858     if (no4->get_solution()>0.) nbpositif++;
859     }
860     if ((nbactif==3) && (nbpositif<3) && (nbpositif>0))
861     {
862     couche.push_back(tet);
863     }
864     }
865     for (int i=0;i<couche.size();i++)
866     {
867     FEM_TETRA* tet=couche[i];
868     FEM_NOEUD *no1=tet->get_fem_noeud(0);
869     FEM_NOEUD *no2=tet->get_fem_noeud(1);
870     FEM_NOEUD *no3=tet->get_fem_noeud(2);
871     FEM_NOEUD *no4=tet->get_fem_noeud(3);
872     TOIBREP_POINT* pt;
873     FEM_NOEUD* noeudref;
874 francois 280 if (no1->get_etat()==0) {noeudref=no1;pt=(*lst)[no2->get_numero()];}
875     if (no2->get_etat()==0) {noeudref=no2;pt=(*lst)[no1->get_numero()];}
876     if (no3->get_etat()==0) {noeudref=no3;pt=(*lst)[no1->get_numero()];}
877     if (no4->get_etat()==0) {noeudref=no4;pt=(*lst)[no1->get_numero()];}
878 francois 281 MG_FACE* face=pt->get_mg_face();
879 francois 280 double uv[2];
880 francois 276 double xyz[3];
881 francois 280 double dist=calcul_distance(noeudref,face,pt,xyz,uv);
882     double normal[3];
883 francois 276 face->calcul_normale_unitaire(uv,normal);
884     normal[0]=normal[0]*sens*(-1.);
885     normal[1]=normal[1]*sens*(-1.);
886     normal[2]=normal[2]*sens*(-1.);
887     double dist2=calculdist(normal,xyz[0],xyz[1],xyz[2],noeudref);
888     if (dist2<0.) dist=dist*(-1);
889     noeudref->change_solution(dist);
890 francois 280 noeudref->change_etat(2);
891     TOIBREP_POINT *nvpt=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],uv[0],uv[1],1,face);
892     lst->push_back(nvpt);
893     noeudref->change_numero(nvpt->get_id());
894 francois 276
895     }
896     for (FEM_TETRA* tet=mai->get_premier_tetra(ittetra);tet!=NULL;tet=mai->get_suivant_tetra(ittetra))
897     {
898     FEM_NOEUD *no1=tet->get_fem_noeud(0);
899     FEM_NOEUD *no2=tet->get_fem_noeud(1);
900     FEM_NOEUD *no3=tet->get_fem_noeud(2);
901     FEM_NOEUD *no4=tet->get_fem_noeud(3);
902 francois 280 if (no1->get_etat()!=0)
903     if (no2->get_etat()!=0)
904     if (no3->get_etat()!=0)
905     if (no4->get_etat()!=0)
906     if (tet->get_etat()==0)
907 francois 276 {
908     castot++;
909 francois 280 double lstptdecoup[5*3];
910 francois 276 int nb=0;
911 francois 280 decoupe_tetra(tet,lstptdecoup,&nb);
912     int reactive=0;
913 francois 276 for (int i=0;i<nb;i++)
914     {
915 francois 280 if (reactive) continue;
916 francois 276 double uv[2];
917 francois 280 face->inverser(uv,lstptdecoup+3*i);
918 francois 276 if ((face->valide_parametre_u(uv[0])) && (face->valide_parametre_v(uv[1])))
919     {
920     double distance=ot.calcule_distance_contour_face_uv(uv,face);
921     if (distance>1e-6)
922     {
923     cas++;
924     tet->change_etat(1);
925 francois 280 no1->change_etat(1);
926     no2->change_etat(1);
927     no3->change_etat(1);
928     no4->change_etat(1);
929     reactive=1;
930     couche_active=1;
931 francois 276 }
932     }
933     }
934 francois 280 if (!reactive)
935     {
936     if (no1->get_etat()==2) no1->change_etat(-1);
937     if (no2->get_etat()==2) no2->change_etat(-1);
938     if (no3->get_etat()==2) no3->change_etat(-1);
939     if (no4->get_etat()==2) no4->change_etat(-1);
940     tet->change_etat(-1);
941     }
942 francois 276 }
943     }
944 francois 280 }
945     while (couche_active==1);
946 francois 281 for (FEM_TETRA* tet=mai->get_premier_tetra(ittetra);tet!=NULL;tet=mai->get_suivant_tetra(ittetra))
947     {
948     if (tet->get_etat()!=1) continue;
949     FEM_NOEUD *no1=tet->get_fem_noeud(0);
950     FEM_NOEUD *no2=tet->get_fem_noeud(1);
951     FEM_NOEUD *no3=tet->get_fem_noeud(2);
952     FEM_NOEUD *no4=tet->get_fem_noeud(3);
953     int nbpositif=0;
954     int nbnegatif=0;
955     double epsdist=1e-6*tet->get_boite_3D().get_rayon();
956     if (no1->get_solution()>epsdist) nbpositif++;
957     if (no1->get_solution()<-epsdist) nbnegatif++;
958     if (no2->get_solution()>epsdist) nbpositif++;
959     if (no2->get_solution()<-epsdist) nbnegatif++;
960     if (no3->get_solution()>epsdist) nbpositif++;
961     if (no3->get_solution()<-epsdist) nbnegatif++;
962     if (no4->get_solution()>epsdist) nbpositif++;
963     if (no4->get_solution()<-epsdist) nbnegatif++;
964     if (!(((nbnegatif>0) && (nbpositif>0)) ||(nbnegatif+nbpositif==1)))
965     tet->change_etat(0);
966     }
967     double res=cas*100.0/castot;
968 francois 276 char mess[255];
969 francois 280 sprintf(mess," %lf%% en %d couches",res,nb_couche);
970 francois 276 affiche(mess);
971     }
972    
973     void TOIBREP::decoupe_tetra(FEM_TETRA* tet,double* lst,int *nb)
974     {
975     FEM_NOEUD* no1=tet->get_fem_noeud(0);
976     FEM_NOEUD* no2=tet->get_fem_noeud(1);
977     FEM_NOEUD* no3=tet->get_fem_noeud(2);
978     FEM_NOEUD* no4=tet->get_fem_noeud(3);
979     if (no1->get_solution()*no2->get_solution()<-0.00000001)
980     {
981     double t=no1->get_solution()/(no1->get_solution()-no2->get_solution());
982     double x=no1->get_x()+t*(no2->get_x()-no1->get_x());
983     double y=no1->get_y()+t*(no2->get_y()-no1->get_y());
984     double z=no1->get_z()+t*(no2->get_z()-no1->get_z());
985     lst[3*(*nb)]=x;
986     lst[3*(*nb)+1]=y;
987     lst[3*(*nb)+2]=z;
988     (*nb)++;
989     }
990     if (no1->get_solution()*no3->get_solution()<-0.00000001)
991     {
992     double t=no1->get_solution()/(no1->get_solution()-no3->get_solution());
993     double x=no1->get_x()+t*(no3->get_x()-no1->get_x());
994     double y=no1->get_y()+t*(no3->get_y()-no1->get_y());
995     double z=no1->get_z()+t*(no3->get_z()-no1->get_z());
996     lst[3*(*nb)]=x;
997     lst[3*(*nb)+1]=y;
998     lst[3*(*nb)+2]=z;
999     (*nb)++;
1000     }
1001     if (no1->get_solution()*no4->get_solution()<-0.00000001)
1002     {
1003     double t=no1->get_solution()/(no1->get_solution()-no4->get_solution());
1004     double x=no1->get_x()+t*(no4->get_x()-no1->get_x());
1005     double y=no1->get_y()+t*(no4->get_y()-no1->get_y());
1006     double z=no1->get_z()+t*(no4->get_z()-no1->get_z());
1007     lst[3*(*nb)]=x;
1008     lst[3*(*nb)+1]=y;
1009     lst[3*(*nb)+2]=z;
1010     (*nb)++;
1011     }
1012     if (no2->get_solution()*no3->get_solution()<-0.00000001)
1013     {
1014     double t=no2->get_solution()/(no2->get_solution()-no3->get_solution());
1015     double x=no2->get_x()+t*(no3->get_x()-no2->get_x());
1016     double y=no2->get_y()+t*(no3->get_y()-no2->get_y());
1017     double z=no2->get_z()+t*(no3->get_z()-no2->get_z());
1018     lst[3*(*nb)]=x;
1019     lst[3*(*nb)+1]=y;
1020     lst[3*(*nb)+2]=z;
1021     (*nb)++;
1022     }
1023     if (no2->get_solution()*no4->get_solution()<-0.00000001)
1024     {
1025     double t=no2->get_solution()/(no2->get_solution()-no4->get_solution());
1026     double x=no2->get_x()+t*(no4->get_x()-no2->get_x());
1027     double y=no2->get_y()+t*(no4->get_y()-no2->get_y());
1028     double z=no2->get_z()+t*(no4->get_z()-no2->get_z());
1029     lst[3*(*nb)]=x;
1030     lst[3*(*nb)+1]=y;
1031     lst[3*(*nb)+2]=z;
1032     (*nb)++;
1033     }
1034     if (no3->get_solution()*no4->get_solution()<-0.00000001)
1035     {
1036     double t=no3->get_solution()/(no3->get_solution()-no4->get_solution());
1037     double x=no3->get_x()+t*(no4->get_x()-no3->get_x());
1038     double y=no3->get_y()+t*(no4->get_y()-no3->get_y());
1039     double z=no3->get_z()+t*(no4->get_z()-no3->get_z());
1040     lst[3*(*nb)]=x;
1041     lst[3*(*nb)+1]=y;
1042     lst[3*(*nb)+2]=z;
1043     (*nb)++;
1044     }
1045     }
1046    
1047     void TOIBREP::calcullevelsetpremierepasse(MG_FACE* face,int sens,vector<TOIBREP_POINT*> *lst,int n1,int n2)
1048     {
1049     /*LISTE_FEM_TETRA::iterator it3;
1050     for (FEM_TETRA* tet=mai->get_premier_tetra(it3);tet!=NULL;tet=mai->get_suivant_tetra(it3))
1051     {
1052     double *xyz1,*xyz2,*xyz3,*xyz4;
1053     if (tet->get_nb_fem_noeud()==4)
1054     {
1055     xyz1=tet->get_fem_noeud(0)->get_coord();
1056     xyz2=tet->get_fem_noeud(1)->get_coord();
1057     xyz3=tet->get_fem_noeud(2)->get_coord();
1058     xyz4=tet->get_fem_noeud(3)->get_coord();
1059     }
1060     if (tet->get_nb_fem_noeud()==10)
1061     {
1062     xyz1=tet->get_fem_noeud(0)->get_coord();
1063     xyz2=tet->get_fem_noeud(2)->get_coord();
1064     xyz3=tet->get_fem_noeud(4)->get_coord();
1065     xyz4=tet->get_fem_noeud(9)->get_coord();
1066     }
1067     double xcentre=0.25*(xyz1[0]+xyz2[0]+xyz3[0]+xyz4[0]);
1068     double ycentre=0.25*(xyz1[1]+xyz2[1]+xyz3[1]+xyz4[1]);
1069     double zcentre=0.25*(xyz1[2]+xyz2[2]+xyz3[2]+xyz4[2]);
1070     double rayon1=(xyz1[0]-xcentre)*(xyz1[0]-xcentre)+(xyz1[1]-ycentre)*(xyz1[1]-ycentre)+(xyz1[2]-zcentre)*(xyz1[2]-zcentre);
1071     double rayon2=(xyz2[0]-xcentre)*(xyz2[0]-xcentre)+(xyz2[1]-ycentre)*(xyz2[1]-ycentre)+(xyz2[2]-zcentre)*(xyz2[2]-zcentre);
1072     double rayon3=(xyz3[0]-xcentre)*(xyz3[0]-xcentre)+(xyz3[1]-ycentre)*(xyz3[1]-ycentre)+(xyz3[2]-zcentre)*(xyz3[2]-zcentre);
1073     double rayon4=(xyz4[0]-xcentre)*(xyz4[0]-xcentre)+(xyz4[1]-ycentre)*(xyz4[1]-ycentre)+(xyz4[2]-zcentre)*(xyz4[2]-zcentre);
1074     double rayon=std::max(rayonETRA_ACTIF1,std::max(rayon2,std::max(rayon3,rayon4)));
1075     rayon=sqrt(rayon);
1076     TPL_MAP_ENTITE<TOIBREP_POINT*> liste;
1077     octree.rechercher(xcentre,ycentre,zcentre,rayon,liste);
1078     TPL_MAP_ENTITE<TOIBREP_POINT*>::ITERATEUR it;
1079     for (TOIBREP_POINT* pt=liste.get_premier(it);pt!=NULL;pt=liste.get_suivant(it))
1080     {
1081     double xyzpt[3];
1082     pt->get_coord3(xyzpt);
1083     int etat=estdansletetra(tet,xyzpt[0],xyzpt[1],xyzpt[2]);
1084     if (compare_etat(etat,INTERIEUR))
1085     {
1086     for (int k=0;k<tet->get_nb_fem_noeud();k++)
1087     {
1088     double normal[3];
1089     double uv[2];
1090     face->inverser(uv,xyzpt);
1091     face->calcul_normale_unitaire(uv,normal);
1092     normal[0]=normal[0]*sens*(-1.);
1093     normal[1]=normal[1]*sens*(-1.);
1094     normal[2]=normal[2]*sens*(-1.);
1095     double dist=calculdist(normal,xyzpt[0],xyzpt[1],xyzpt[2],tet->get_fem_noeud(k));
1096     if (fabs(dist)<fabs(tet->get_fem_noeud(k)->get_solution()))
1097     {
1098     tet->get_fem_noeud(k)->change_solution(dist);
1099     tet->get_fem_noeud(k)->change_numero(pt->get_id());
1100     pt->change_coord2(uv);
1101     }
1102     }
1103     }
1104     if ((compare_etat(etat,STRICTINTERIEUR)) && (pt->get_interieur()))
1105     {
1106     tet->change_etat(1);
1107     for (int k=0;k<tet->get_nb_fem_noeud();k++)
1108     tet->get_fem_noeud(k)->change_etat(1);
1109     }
1110     if (tet->get_etat()==1) break;
1111     }
1112    
1113     }
1114     octree.vide();
1115 francois 281 it}*/
1116 francois 276 /*LISTE_FEM_TETRA::iterator it3;
1117     for (FEM_TETRA* tet=mai->get_premier_tetra(it3);tet!=NULL;tet=mai->get_suivant_tetra(it3))
1118     octree.inserer(tet);*/
1119     for (int i=n1;i<n2;i++)
1120     {
1121 francois 259 TOIBREP_POINT* pt=(*lst)[i];
1122 francois 104 double uv[2];
1123 francois 106 double xyz[3];
1124     pt->get_coord3(xyz);
1125 francois 222 double normal[3];
1126 francois 104 face->inverser(uv,xyz);
1127     face->calcul_normale_unitaire(uv,normal);
1128 francois 222 normal[0]=normal[0]*sens*(-1.);
1129     normal[1]=normal[1]*sens*(-1.);
1130     normal[2]=normal[2]*sens*(-1.);
1131     TPL_MAP_ENTITE<FEM_TETRA*> liste;
1132 francois 259 octree.rechercher(xyz[0],xyz[1],xyz[2],0.,liste);
1133 francois 222 TPL_MAP_ENTITE<FEM_TETRA*>::ITERATEUR it;
1134     for (FEM_TETRA* tet=liste.get_premier(it);tet!=NULL;tet=liste.get_suivant(it))
1135 francois 104 {
1136 francois 276 if (tet->get_etat()==1) continue;
1137     int etat=estdansletetra(tet,xyz[0],xyz[1],xyz[2]);
1138 francois 281 if ((compare_etat(etat,SUR_FACE)) && (pt->get_interieur()))
1139     {
1140     int nbeps=pt->get_nb_point_eps();
1141     for (int k=0;k<nbeps;k++)
1142     {
1143     double xyztmp[3];
1144     pt->get_point_eps(k,xyztmp);
1145     int etattmp=estdansletetra(tet,xyztmp[0],xyztmp[1],xyztmp[2]);
1146     if (compare_etat(etattmp,SUR_FACE)) {etat=STRICTINTERIEUR;break;}
1147     if (compare_etat(etattmp,INTERIEUR)) {etat=STRICTINTERIEUR;break;}
1148     if (compare_etat(etattmp,STRICTINTERIEUR)) {etat=STRICTINTERIEUR;break;}
1149     }
1150     }
1151 francois 276 if (compare_etat(etat,INTERIEUR))
1152 francois 104 {
1153 francois 222 for (int k=0;k<tet->get_nb_fem_noeud();k++)
1154 francois 106 {
1155 francois 222 double dist=calculdist(normal,xyz[0],xyz[1],xyz[2],tet->get_fem_noeud(k));
1156     if (fabs(dist)<fabs(tet->get_fem_noeud(k)->get_solution()))
1157     {
1158     tet->get_fem_noeud(k)->change_solution(dist);
1159     tet->get_fem_noeud(k)->change_numero(pt->get_id());
1160     pt->change_coord2(uv);
1161     }
1162 francois 106 }
1163 francois 104 }
1164 francois 276 if ((compare_etat(etat,STRICTINTERIEUR)) && (pt->get_interieur()))
1165     {
1166     tet->change_etat(1);
1167     for (int k=0;k<tet->get_nb_fem_noeud();k++)
1168     {
1169     tet->get_fem_noeud(k)->change_etat(1);
1170     //octree.supprimer(tet);
1171     }
1172     }
1173 francois 104 }
1174     }
1175 francois 276 //octree.vide();
1176    
1177    
1178    
1179    
1180 francois 106 }
1181    
1182 francois 276 void TOIBREP::calcullevelsetdeuxiemepasse(vector<TOIBREP_POINT*> *lst)
1183 francois 106 {
1184 francois 276 LISTE_FEM_NOEUD::iterator itno;
1185     for (FEM_NOEUD* no=mai->get_premier_noeud(itno);no!=NULL;no=mai->get_suivant_noeud(itno))
1186     if (no->get_solution()<1e250)
1187 francois 106 {
1188 francois 276 TOIBREP_POINT* pt=(*lst)[no->get_numero()];
1189 francois 281 MG_FACE* face=pt->get_mg_face();
1190     double xyz[3],uv[2];
1191     double dist=calcul_distance(no,face,pt,xyz,uv);
1192     int signe=1;
1193     if (no->get_solution()<0) signe=-1;
1194     no->change_solution(signe*dist);
1195 francois 106 }
1196 francois 104
1197 francois 276
1198    
1199    
1200 francois 106 }
1201    
1202 francois 281
1203    
1204     double TOIBREP::calcul_distance(FEM_NOEUD* noeud,MG_ARETE* are,TOIBREP_POINT* pt,double &tii,double *xyz,double precision)
1205 francois 106 {
1206 francois 281 double eps;
1207 francois 106 are->inverser(tii,noeud->get_coord());
1208     int compteur=0;
1209     OT_VECTEUR_3D Pt(noeud->get_x(),noeud->get_y(),noeud->get_z());
1210     do
1211     {
1212     compteur++;
1213     double ti=tii;
1214     double xyz[3],dxyz[3],ddxyz[3];
1215     are->deriver_seconde(ti,ddxyz,dxyz,xyz);
1216     OT_VECTEUR_3D Ct(xyz[0],xyz[1],xyz[2]);
1217     OT_VECTEUR_3D Ct_deriver(dxyz[0],dxyz[1],dxyz[2]);
1218     OT_VECTEUR_3D Ct_deriver_seconde(ddxyz[0],ddxyz[1],ddxyz[2]);
1219     OT_VECTEUR_3D Distance = Ct-Pt;
1220     tii=ti-Ct_deriver*Distance/(Ct_deriver_seconde*Distance+Ct_deriver.get_longueur2());
1221     eps=fabs(tii-ti);
1222     if (compteur>500) return 1e300;
1223     if (tii<are->get_tmin())
1224     {
1225     tii=are->get_tmin();
1226     eps=0.;
1227     }
1228     if (tii>are->get_tmax())
1229     {
1230     tii=are->get_tmax();
1231     eps=0.;
1232     }
1233     }
1234     while (eps>precision);
1235     are->evaluer(tii,xyz);
1236     OT_VECTEUR_3D Ct(xyz[0],xyz[1],xyz[2]);
1237     double distance=(Ct-Pt).get_longueur();
1238 francois 281 return distance;
1239 francois 106 }
1240    
1241 francois 281
1242     double TOIBREP::calcul_distance_level_ortho(FEM_NOEUD* no,MG_ARETE* are,TOIBREP_POINT* pt,double precision)
1243     {
1244     double t;
1245     double xyz[3];
1246     return calcul_distance_level_ortho(no,are,pt,t,xyz,precision);
1247     }
1248    
1249     double TOIBREP::calcul_distance_level_ortho(FEM_NOEUD* no,MG_ARETE* are,TOIBREP_POINT* pt,double &t,double *xyz,double precision)
1250     {
1251     calcul_distance(no,are,pt,t,xyz,precision);
1252     double dir[3];
1253     are->deriver(t,dir);
1254     double uv[2];
1255     MG_FACE* face=are->get_mg_coarete(0)->get_boucle()->get_mg_face();
1256     face->inverser(uv,xyz);
1257     double nor[3];
1258     face->calcul_normale_unitaire(uv,nor);
1259     OT_VECTEUR_3D dirv(dir);
1260     OT_VECTEUR_3D norv(nor);
1261     OT_VECTEUR_3D sensv=norv&dirv;
1262     double d=-(sensv.get_x()*xyz[0]+sensv.get_y()*xyz[1],sensv.get_z()*xyz[2]);
1263     double dist=fabs(sensv.get_x()*no->get_x()+sensv.get_y()*no->get_y()+sensv.get_z()*no->get_z()+d);
1264     OT_VECTEUR_3D distv(no->get_x()-xyz[0],no->get_y()-xyz[1],no->get_z()-xyz[2]);
1265     if (sensv*distv<0.) dist=-dist;
1266     return dist;
1267     }
1268    
1269    
1270 francois 280 double TOIBREP::calcul_distance(FEM_NOEUD* noeud,MG_FACE* face,TOIBREP_POINT* pt,double *xyz,double *uv,double precision)
1271 francois 106 {
1272     double uvii[2],eps;
1273     pt->get_coord2(uvii);
1274     int compteur=0;
1275     OT_VECTEUR_3D Pt(noeud->get_x(),noeud->get_y(),noeud->get_z());
1276     double delta_u,delta_v;
1277     do
1278     {
1279     compteur++;
1280     double uvi[2];
1281     uvi[0]=uvii[0];
1282     uvi[1]=uvii[1];
1283     double xyzduu[3],xyzdvv[3],xyzduv[3],xyzdu[3],xyzdv[3],xyz[3];
1284     face->deriver_seconde(uvi,xyzduu,xyzduv,xyzdvv,xyz,xyzdu,xyzdv);
1285     OT_VECTEUR_3D S(xyz[0],xyz[1],xyz[2]);
1286     OT_VECTEUR_3D Su(xyzdu[0],xyzdu[1],xyzdu[2]);
1287     OT_VECTEUR_3D Sv(xyzdv[0],xyzdv[1],xyzdv[2]);
1288     OT_VECTEUR_3D Suu(xyzduu[0],xyzduu[1],xyzduu[2]);
1289     OT_VECTEUR_3D Suv(xyzduv[0],xyzduv[1],xyzduv[2]);
1290     OT_VECTEUR_3D Svv(xyzdvv[0],xyzdvv[1],xyzdvv[2]);
1291     OT_VECTEUR_3D Distance = S-Pt;
1292     double a[4],b[2];
1293     a[0]=Su.get_longueur2()+Distance*Suu;
1294     a[1]=Su*Sv+Distance*Suv;
1295     a[2]=Su*Sv+Distance*Suv;
1296     a[3]=Sv.get_longueur2()+Distance*Svv;
1297     b[0]=Distance*Su;b[0]=-b[0];
1298     b[1]=Distance*Sv;b[1]=-b[1];
1299     double deltau,deltav;
1300     double denominateur_delta=(a[0]*a[3]-a[2]*a[1]);
1301     if (a[0]<1E-12)
1302     deltau=0;
1303     else delta_u=(b[0]*a[3]-b[1]*a[1])/denominateur_delta;
1304     if (a[3]<1E-12)
1305     deltav=0;
1306     else delta_v=(a[0]*b[1]-a[2]*b[0])/denominateur_delta;
1307     /*if (fabs(denominateur_delta) < ( (fabs(a[0])+fabs(a[1])+fabs(a[2])+fabs(a[3]))*1e-12 ) )
1308     return 1e300;*/
1309     uvii[0]=uvi[0]+delta_u;
1310     uvii[1]=uvi[1]+delta_v;
1311     if (face->get_surface()->est_periodique_u()==1)
1312     {
1313     if(uvii[0]<0.) uvii[0]=face->get_surface()->get_periode_u()-uvii[0];
1314     if(uvii[0]>face->get_surface()->get_periode_u()) uvii[0]=uvii[0]-face->get_surface()->get_periode_u();
1315     }
1316     if (face->get_surface()->est_periodique_v()==1)
1317     {
1318     if(uvii[1]<0.) uvii[0]=face->get_surface()->get_periode_v()-uvii[1];
1319     if(uvii[1]>face->get_surface()->get_periode_v()) uvii[1]=uvii[1]-face->get_surface()->get_periode_v();
1320     }
1321     delta_u=uvii[0]-uvi[0];
1322     delta_v=uvii[1]-uvi[1];
1323     if (compteur>500) return 1e300;
1324     }
1325    
1326     while ((fabs(delta_u)>precision)||(fabs(delta_v)>precision));
1327     face->evaluer(uvii,xyz);
1328     OT_VECTEUR_3D S(xyz[0],xyz[1],xyz[2]);
1329     double distance=(S-Pt).get_longueur();
1330 francois 280 uv[0]=uvii[0];
1331     uv[1]=uvii[1];
1332 francois 106 return distance;
1333     }
1334    
1335    
1336 francois 276
1337 francois 259 void TOIBREP::etendrelevelset(FEM_SOLUTION* sol,int numsol)
1338 francois 222 {
1339     sol->active_solution(numsol);
1340    
1341    
1342     LISTE_FM know;
1343     LISTE_FM trial;
1344     LISTE_FM far;
1345     LISTE_FM exterieur;
1346     LISTE_FM_TRI trialtri;
1347     LISTE_FM_TRI_ID trialtriid;
1348    
1349    
1350     LISTE_FEM_TETRA::iterator ittet;
1351     for (FEM_TETRA* tet=mai->get_premier_tetra(ittet);tet!=NULL;tet=mai->get_suivant_tetra(ittet))
1352     {
1353     tet->change_solution(0.);
1354     int numsol=0;
1355     if (tet->get_fem_noeud(0)->get_solution()<1e200) {numsol++;tet->get_fem_noeud(0)->change_numero(1);} else tet->get_fem_noeud(0)->change_numero(0);
1356     if (tet->get_fem_noeud(1)->get_solution()<1e200) {numsol++;tet->get_fem_noeud(1)->change_numero(1);} else tet->get_fem_noeud(1)->change_numero(0);
1357     if (tet->get_fem_noeud(2)->get_solution()<1e200) {numsol++;tet->get_fem_noeud(2)->change_numero(1);} else tet->get_fem_noeud(2)->change_numero(0);
1358     if (tet->get_fem_noeud(3)->get_solution()<1e200) {numsol++;tet->get_fem_noeud(3)->change_numero(1);} else tet->get_fem_noeud(3)->change_numero(0);
1359     if (numsol==4)
1360     ajouter_liste(know,tet);
1361    
1362     else if (numsol==3)
1363     {
1364     if (tet->get_fem_noeud(0)->get_numero()==0) tet->change_numero(0);
1365     else if (tet->get_fem_noeud(1)->get_numero()==0) tet->change_numero(1);
1366     else if (tet->get_fem_noeud(2)->get_numero()==0) tet->change_numero(2);
1367     else tet->change_numero(3);
1368     ajouter_liste(trial,tet);
1369     }
1370     else
1371     ajouter_liste(far,tet);
1372    
1373     }
1374     for (LISTE_FM::iterator i=trial.begin();i!=trial.end();i++)
1375     {
1376     FEM_TETRA* tet=*i;
1377     int signe;
1378     double sol=resoudgradT(tet,&signe);
1379     if (fabs(sol)>0.00000001)
1380     {
1381     if (fabs(sol)<fabs(tet->get_fem_noeud(tet->get_numero())->get_solution()))
1382     {
1383     tet->get_fem_noeud(tet->get_numero())->change_solution(sol);
1384     ajouter_liste(trialtri,trialtriid,tet,fabs(tet->get_fem_noeud(tet->get_numero())->get_solution()));
1385     }
1386     }
1387     else
1388     {
1389     ajouter_liste(exterieur,tet);
1390     tet->change_solution(1e300);
1391     }
1392     }
1393     int fin=0;
1394     LISTE_FM_TRI::iterator itfin=trialtri.end();
1395     itfin--;
1396     double longref=(*itfin).first;
1397     do
1398     {
1399     LISTE_FM_TRI::iterator it=trialtri.begin();
1400     FEM_TETRA* tet=(*it).second;
1401     double longcourant=(*it).first;
1402     supprimer_liste(trialtri,trialtriid,tet);
1403     ajouter_liste(know,tet);
1404     FEM_NOEUD* noeud=tet->get_fem_noeud(tet->get_numero());
1405     noeud->change_numero(1);
1406     if (noeud->get_solution()>20000)
1407     cout << "BUGGGGGGG" <<endl;
1408     int nbtetra=noeud->get_lien_tetra()->get_nb();
1409     for (int i=0;i<nbtetra;i++)
1410     {
1411     FEM_TETRA* tet2=noeud->get_lien_tetra()->get(i);
1412     if (tet2==tet) continue;
1413     LISTE_FM_TRI_ID::iterator it=trialtriid.find(tet2->get_id());
1414     if (it!=trialtriid.end())
1415     {
1416     int signe;
1417     double sol=resoudgradT(tet2,&signe);
1418     double solution=tet2->get_fem_noeud(tet2->get_numero())->get_solution();
1419     if (fabs(sol)>0.00000001)
1420     if (!((solution<1e200)&&(sol*solution<0)))
1421     if (fabs(sol)<fabs(solution))
1422     {
1423     supprimer_liste(trialtri,trialtriid,tet2);
1424     ajouter_liste(trialtri,trialtriid,tet2,fabs(sol));
1425     tet2->get_fem_noeud(tet2->get_numero())->change_solution(sol);
1426     }
1427     }
1428     LISTE_FM::iterator it2=find(far.begin(),far.end(),tet2);
1429     if (it2!=far.end())
1430     {
1431     int numsol=0;
1432     if (tet2->get_fem_noeud(0)->get_numero()==1) numsol++;
1433     if (tet2->get_fem_noeud(1)->get_numero()==1) numsol++;
1434     if (tet2->get_fem_noeud(2)->get_numero()==1) numsol++;
1435     if (tet2->get_fem_noeud(3)->get_numero()==1) numsol++;
1436     //if (numsol==4)
1437     //cout << " BUG " <<endl;
1438     if (numsol==3)
1439     {
1440     if (tet2->get_fem_noeud(0)->get_numero()==0) tet2->change_numero(0);
1441     else if (tet2->get_fem_noeud(1)->get_numero()==0) tet2->change_numero(1);
1442     else if (tet2->get_fem_noeud(2)->get_numero()==0) tet2->change_numero(2);
1443     else tet2->change_numero(3);
1444     int signe;
1445     double sol=resoudgradT(tet2,&signe);
1446     double ancsol=tet2->get_fem_noeud(tet2->get_numero())->get_solution();
1447     if (fabs(sol)>0.00000001)
1448     {
1449     if (!((ancsol<1e200) && (ancsol*sol<0.) ))
1450     {
1451     tet2->get_fem_noeud(tet2->get_numero())->change_solution(sol);
1452     supprimer_liste(far,tet2);
1453     ajouter_liste(trialtri,trialtriid,tet2,fabs(sol));
1454     }
1455     }
1456     else
1457     {
1458     tet2->change_solution(1e300);
1459     ajouter_liste(exterieur,tet2);
1460     }
1461     }
1462     }
1463     }
1464     if (trialtri.size()==0) fin=1;
1465     if (exterieur.size()>0)
1466     if (fin==0)
1467     if (longcourant>longref)
1468     {
1469     int nombre=exterieur.size();
1470     for (int i=0;i<nombre;i++)
1471     {
1472     FEM_TETRA* tet2=(*(exterieur.begin()));
1473     supprimer_liste(exterieur,tet2);
1474     ajouter_liste(know,tet2);
1475     for (int nd=0;nd<4;nd++)
1476     {
1477     FEM_NOEUD* noeud=tet2->get_fem_noeud(nd);
1478     int nbtetra=noeud->get_lien_tetra()->get_nb();
1479     for (int i=0;i<nbtetra;i++)
1480     {
1481     FEM_TETRA* tet3=noeud->get_lien_tetra()->get(i);
1482     if (tet2==tet3) continue;
1483     LISTE_FM::iterator it2=find(far.begin(),far.end(),tet3);
1484     if (it2!=far.end())
1485     {
1486     supprimer_liste(far,tet3);
1487     ajouter_liste(exterieur,tet3);
1488     tet3->change_solution(1e300);
1489     }
1490     }
1491     }
1492     }
1493     LISTE_FM_TRI::iterator itfin=trialtri.end();
1494     itfin--;
1495     longref=(*itfin).first;
1496     }
1497     }
1498     while (fin==0);
1499     LISTE_FEM_NOEUD::iterator itnoeud;
1500     for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
1501     noeud->change_numero(0);
1502     for (FEM_TETRA* tet=mai->get_premier_tetra(ittet);tet!=NULL;tet=mai->get_suivant_tetra(ittet))
1503     {
1504     if (tet->get_solution()>1e200) continue;
1505     tet->get_fem_noeud(0)->change_numero(1);
1506     tet->get_fem_noeud(1)->change_numero(1);
1507     tet->get_fem_noeud(2)->change_numero(1);
1508     tet->get_fem_noeud(3)->change_numero(1);
1509     }
1510     int i=0;
1511     for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
1512     {
1513     if (noeud->get_numero()==1) sol->ecrire(i,numsol,noeud->get_solution()); else sol->ecrire(i,numsol,1e300);
1514     ++i;
1515     }
1516     }
1517 francois 276 IBrep TOIBREP::exporter_IBrep(string chemin,FEM_SOLUTION* solution,FEM_SOLUTION *solution_ele,MG_GROUPE_TOPOLOGIQUE* mggt)
1518 francois 259 {
1519     TPL_MAP_ENTITE<MG_VOLUME*> lst;
1520     if (mggt==NULL)
1521     {
1522     int nbvol=geo->get_nb_mg_volume();
1523     for (int i=0;i<nbvol;i++)
1524     lst.ajouter(geo->get_mg_volume(i));
1525     }
1526     else
1527     {
1528     int nbmggt=mggt->get_nb();
1529     for (int i=0;i<nbmggt;i++)
1530     if (mggt->get(i)->get_dimension()==3)
1531     lst.ajouter((MG_VOLUME*)mggt->get(i));
1532     }
1533     IBrep brep(100);
1534     int nbvolexp=lst.get_nb();
1535     for (int i=0;i<nbvolexp;i++)
1536     {
1537     MG_VOLUME* vol=lst.get(i);
1538     int nbcoq=vol->get_nb_mg_coquille();
1539     IVolumeN ivoltmp(vol->get_id());
1540 francois 263 pair<IVolume*,bool> pair_ivol=brep.AddVolume(ivoltmp);
1541 francois 282 if (vol->get_idoriginal()!="") brep.SetName(pair_ivol.first,vol->get_idoriginal());
1542 francois 263 IVolume* ivol=pair_ivol.first;
1543 francois 259 for (int j=0;j<nbcoq;j++)
1544     {
1545     MG_COQUILLE* coq=vol->get_mg_coquille(j);
1546     int nbface=coq->get_nb_mg_coface();
1547     IShell ishell(nbface);
1548     for (int k=0;k<nbface;k++)
1549     {
1550     MG_COFACE* coface=coq->get_mg_coface(k);
1551     ishell[k]=coface->get_id();
1552     MG_FACE* face=coface->get_face();
1553     int sens=coface->get_orientation();
1554     ICoFaceN icoface(coface->get_id(),face->get_id(),sens);
1555     brep.AddCoFace(icoface);
1556     IFace* iface=brep.GetFace(face->get_id());
1557     if (iface==NULL)
1558     {
1559     IFaceN ifacenew(face->get_id());
1560 francois 263 pair<IFace*,bool> pair_iface=brep.AddFace(ifacenew);
1561 francois 282 if (face->get_idoriginal()!="") brep.SetName(pair_iface.first,face->get_idoriginal());
1562 francois 263 iface=pair_iface.first;
1563 francois 259 int nbbou=face->get_nb_mg_boucle();
1564     for (int l=0;l<nbbou;l++)
1565     {
1566     MG_BOUCLE* bou=face->get_mg_boucle(l);
1567     int nbare=bou->get_nb_mg_coarete();
1568     ILoop iloop(nbare);
1569     for (int m=0;m<nbare;m++)
1570     {
1571     MG_COARETE* coare=bou->get_mg_coarete(m);
1572     iloop[m]=coare->get_id();
1573     MG_ARETE* are=coare->get_arete();
1574     int sens=coare->get_orientation();
1575     ICoEdgeN icoedge(coare->get_id(),are->get_id(),sens,face->get_id());
1576     brep.AddCoEdge(icoedge);
1577     IEdge* iedge=brep.GetEdge(are->get_id());
1578     IVertex *ivertex1,*ivertex2;
1579     ICoVertex *icover1,*icover2;
1580     if (iedge==NULL)
1581     {
1582     MG_COSOMMET* cover1=are->get_cosommet1();
1583     MG_COSOMMET* cover2=are->get_cosommet2();
1584     MG_SOMMET* ver1=cover1->get_sommet();
1585     MG_SOMMET* ver2=cover2->get_sommet();
1586     ICoVertexN icovertmp1(cover1->get_id(),are->get_id(),ver1->get_id(),cover1->get_t());
1587     ICoVertexN icovertmp2(cover2->get_id(),are->get_id(),ver2->get_id(),cover2->get_t());
1588 francois 263 pair<ICoVertex*,bool> pair_icover1=brep.AddCoVertex(icovertmp1);
1589     pair<ICoVertex*,bool> pair_icover2=brep.AddCoVertex(icovertmp2);
1590     icover1=pair_icover1.first;
1591     icover2=pair_icover2.first;
1592 francois 259 IEdgeN iedgetmp(are->get_id(),cover1->get_id(),cover2->get_id());
1593     ivertex1=brep.GetVertex(ver1->get_id());
1594     ivertex2=brep.GetVertex(ver2->get_id());
1595     if (ivertex1==NULL)
1596     {
1597     MG_POINT* pt=ver1->get_point();
1598     double xyz[3];
1599     pt->evaluer(xyz);
1600     IVertexN ivertex(ver1->get_id(),xyz);
1601 francois 263 pair<IVertex*,bool> pair_ivertex1=brep.AddVertex(ivertex);
1602 francois 282 if (ver1->get_idoriginal()!="") brep.SetName(pair_ivertex1.first,ver1->get_idoriginal());
1603 francois 263 ivertex1=pair_ivertex1.first;
1604 francois 259 }
1605     if (ivertex2==NULL)
1606     {
1607     MG_POINT* pt=ver2->get_point();
1608     double xyz[3];
1609     pt->evaluer(xyz);
1610     IVertexN ivertex(ver2->get_id(),xyz);
1611 francois 263 pair<IVertex*,bool> pair_ivertex2=brep.AddVertex(ivertex);
1612 francois 282 if (ver2->get_idoriginal()!="") brep.SetName(pair_ivertex2.first,ver2->get_idoriginal());
1613 francois 263 ivertex2=pair_ivertex2.first;
1614 francois 259 }
1615     ivertex1->AddCoVertex(cover1->get_id());
1616     ivertex2->AddCoVertex(cover2->get_id());
1617 francois 263 pair<IEdge*,bool> pair_iedge=brep.AddEdge(iedgetmp);
1618 francois 282 if (are->get_idoriginal()!="") brep.SetName(pair_iedge.first,are->get_idoriginal());
1619 francois 263 iedge=pair_iedge.first;
1620 francois 259 }
1621     iedge->AddCoEdge(coare->get_id(),brep);
1622     if (sens==1)
1623     {
1624     icover1=brep.GetCoVertex(iedge->FromCoVertex());
1625     ivertex1=brep.GetVertex(icover1->Vertex());
1626     ivertex1->AddFace(face->get_id());
1627     }
1628     else
1629     {
1630     icover2=brep.GetCoVertex(iedge->ToCoVertex());
1631     ivertex2=brep.GetVertex(icover2->Vertex());
1632     ivertex2->AddFace(face->get_id());
1633     }
1634     }
1635     iface->AddLoop(iloop);
1636     }
1637     }
1638     iface->AddCoFace(coface->get_id());
1639     }
1640     ivol->AddShell(ishell);
1641     }
1642     }
1643     int nbsol=solution->get_nb_champ();
1644 francois 281 //unsigned long *correspondface=new unsigned long[nbsol];
1645 francois 262 for (int i=0;i<nbsol;i++)
1646     {
1647     std::string nom=solution->get_legende(i);
1648     char nom2[2];
1649     unsigned long id;
1650 francois 272 sscanf(nom.c_str(),"%s %lu",nom2,&id);
1651 francois 282 std::pair<IField *,bool> fld=brep.AddField(id);
1652     if (nom2[0]!='F')
1653     {
1654     IField *f=fld.first;
1655     f->info.tag=1;
1656     }
1657 francois 262 }
1658 francois 259 LISTE_FEM_NOEUD::iterator itnoeud;
1659     int i=0;
1660     for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
1661     {
1662     int nbsolnoeud=0;
1663     for (int j=0;j<nbsol;j++)
1664     {
1665     if (solution->lire(i,j)<1e200) nbsolnoeud++;
1666     }
1667     double *xyz=noeud->get_coord();
1668     INodeN inoeudtmp(noeud->get_id(),xyz[0],xyz[1],xyz[2],nbsolnoeud);
1669 francois 263 pair<INode*,bool> pair_inoeud=brep.AddNode(inoeudtmp);
1670     INode* inoeud=pair_inoeud.first;
1671 francois 259 int num=0;
1672 francois 281 IBrep::iterator_fields itf=brep.begin_fields();
1673 francois 259 for (int j=0;j<nbsol;j++)
1674     {
1675     if (solution->lire(i,j)<1e200)
1676     {
1677 francois 281 inoeud->Fields()[num]=(*itf).num;
1678 francois 259 inoeud->Values()[num]=solution->lire(i,j);
1679     num++;
1680 francois 281 }
1681     itf++;
1682 francois 259 }
1683     i++;
1684     }
1685     LISTE_FEM_TETRA::iterator ittet;
1686     int num=0;
1687 francois 276 i=0;
1688 francois 259 for (FEM_TETRA* tet=mai->get_premier_tetra(ittet);tet!=NULL;tet=mai->get_suivant_tetra(ittet))
1689     {
1690 francois 276 int nbsolele=0;
1691     for (int j=0;j<nbsol;j++)
1692     {
1693     if (fabs(solution_ele->lire(i,j)-1.)<0.0000000001) nbsolele++;
1694     }
1695     IElementN xfemele(IElement::TETRAHEDRON,nbsolele);
1696 francois 259 num++;
1697     xfemele.num=num;
1698     xfemele.GetNode(0)=tet->get_fem_noeud(0)->get_id();
1699     xfemele.GetNode(1)=tet->get_fem_noeud(1)->get_id();
1700     xfemele.GetNode(2)=tet->get_fem_noeud(2)->get_id();
1701     xfemele.GetNode(3)=tet->get_fem_noeud(3)->get_id();
1702 francois 276 int num=0;
1703 francois 281 IBrep::iterator_fields itf=brep.begin_fields();
1704 francois 276 for (int j=0;j<nbsol;j++)
1705     {
1706     if (fabs(solution_ele->lire(i,j)-1.)<0.0000000001)
1707     {
1708 francois 281 xfemele.Fields()[num]=(*itf).num;
1709 francois 276 num++;
1710     }
1711 francois 281 itf++;
1712 francois 276 }
1713 francois 259 brep.AddElement(xfemele);
1714 francois 276 i++;
1715 francois 259 }
1716 francois 222
1717 francois 259
1718    
1719    
1720     std::ofstream output(chemin.c_str());
1721     output << brep << std::endl;
1722     output.close();
1723    
1724 francois 262
1725    
1726    
1727 francois 276 return brep;
1728 francois 259 }
1729    
1730    
1731    
1732     void TOIBREP::ajouter_liste(LISTE_FM_TRI &lst,LISTE_FM_TRI_ID &lstid,FEM_TETRA* tet,double val)
1733 francois 222 {
1734     pair<double,FEM_TETRA*> p(val,tet);
1735     LISTE_FM_TRI::iterator it=lst.insert(p);
1736     lstid[tet->get_id()]=it;
1737     }
1738    
1739 francois 259 void TOIBREP::supprimer_liste(LISTE_FM_TRI &lst,LISTE_FM_TRI_ID &lstid,FEM_TETRA* tet)
1740 francois 222 {
1741     LISTE_FM_TRI::iterator it2=lstid[tet->get_id()];
1742     LISTE_FM_TRI_ID::iterator it3=lstid.find(tet->get_id());
1743     lstid.erase(it3);
1744     lst.erase(it2);
1745     }
1746    
1747 francois 259 void TOIBREP::ajouter_liste(LISTE_FM& lst,FEM_TETRA* tet)
1748 francois 222 {
1749     lst.push_back(tet);
1750     }
1751    
1752 francois 259 void TOIBREP::supprimer_liste(LISTE_FM& lst,FEM_TETRA* tet)
1753 francois 222 {
1754     LISTE_FM::iterator it=find(lst.begin(),lst.end(),tet);
1755     if (it!=lst.end()) lst.erase(it);
1756     }
1757    
1758    
1759    
1760 francois 259 double TOIBREP::resoudgradT(FEM_TETRA* tet,int *signe)
1761 francois 222 {
1762     double j[9];
1763     double N[12];
1764     double jN[12]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
1765     double T[4];
1766     double uv[2]={0.25,0.25};
1767    
1768    
1769     tet->get_inverse_jacob(j,uv);
1770     for (int i=0;i<3;i++)
1771     for (int k=0;k<4;k++)
1772     N[i*4+k]=tet->get_fonction_derive_interpolation(k+1,i+1,uv);
1773     int premier=0;
1774     double tmin=1e300;
1775     double tmax=-1e300;
1776     for (int i=0;i<4;i++)
1777     {
1778     if (i==tet->get_numero()) continue;
1779     T[i]=tet->get_fem_noeud(i)->get_solution();
1780     if (fabs(T[i])>0.000001)
1781     {
1782     if (premier==0)
1783     if (T[i]>0) (*signe)=1; else (*signe)=-1;
1784     else if (T[i]*(*signe)<0) (*signe)=0;
1785     }
1786     T[i]=fabs(T[i]);
1787     if (tet->get_numero()!=i)
1788     {
1789     if (T[i]<tmin) tmin=T[i];
1790     if (T[i]>tmax) tmax=T[i];
1791     }
1792     premier=1;
1793     }
1794     for (int i=0;i<3;i++)
1795     for (int k=0;k<4;k++)
1796     for (int l=0;l<3;l++)
1797     jN[i*4+k]=jN[i*4+k]+j[i*3+l]*N[l*4+k];
1798     double a=0.,b=0.,c=-1.;
1799     for (int i=0;i<3;i++)
1800     {
1801     double coef=0.;
1802     double coefinc=0.;
1803     for (int l=0;l<4;l++)
1804     {
1805     if (tet->get_numero()!=l) coef=coef+jN[i*4+l]*T[l];
1806     else coefinc=coefinc+jN[i*4+l];
1807     }
1808     c=c+coef*coef;
1809     a=a+coefinc*coefinc;
1810     b=b+2*coef*coefinc;
1811     }
1812     /*if (*signe==0)
1813     cout << "attention " <<endl;*/
1814     double det=b*b-4.*a*c;
1815     if (det<0.) det=0.; else det=sqrt(det);
1816     double sol1=(-b-det)/2./a;
1817     double sol2=(-b+det)/2./a;
1818     double sol=sol1;
1819     if (sol2>sol1) sol=sol2;
1820     if (sol<tmin*0.99)
1821     sol=0.;
1822     sol=sol*(*signe);
1823     return sol;
1824     }