ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/mailleur/src/mailleur2d_optimisation.cpp
Revision: 696
Committed: Fri Jul 24 20:30:52 2015 UTC (9 years, 9 months ago) by francois
Original Path: magic/lib/mailleur_auto/src/mailleur2d_optimisation.cpp
File size: 19972 byte(s)
Log Message:
amélioration de l'optimisation 2D avec ajout de l'inverse de diagoanale et le parametrege complet de la methode

File Contents

# User Rev Content
1 francois 447 #include "mailleur2d_optimisation.h"
2     #include "m3d_triangle.h"
3     #include "mg_gestionnaire.h"
4     #include "ot_decalage_parametre.h"
5     #include <math.h>
6 francois 696 #include <string.h>
7 francois 447
8    
9 francois 494 MAILLEUR2D_OPTIMISATION::MAILLEUR2D_OPTIMISATION(MG_MAILLAGE* mgmai,int niv):MAILLEUR(false),mg_maillage(mgmai),niveau_optimisation(niv)
10 francois 447 {
11     }
12    
13     MAILLEUR2D_OPTIMISATION::~MAILLEUR2D_OPTIMISATION()
14     {
15     }
16    
17     void MAILLEUR2D_OPTIMISATION::change_niveau_optimisation(int num)
18     {
19     niveau_optimisation=num;
20     }
21    
22     int MAILLEUR2D_OPTIMISATION::get_niveau_optimisation(void)
23     {
24     return niveau_optimisation;
25     }
26    
27 francois 448 void MAILLEUR2D_OPTIMISATION::optimise(MG_VOLUME* mgvolume)
28     {
29     LISTE_MG_TRIANGLE::iterator ittr;
30     TPL_MAP_ENTITE<M3D_TRIANGLE*> lsttrim3d;
31     for (MG_TRIANGLE* tri=mg_maillage->get_premier_triangle(ittr);tri!=NULL;tri=mg_maillage->get_suivant_triangle(ittr))
32     {
33     M3D_TRIANGLE* nvtri=new M3D_TRIANGLE(tri->get_id(),tri->get_lien_topologie(),tri->get_noeud1(),tri->get_noeud2(),tri->get_noeud3(),tri->get_segment1(),tri->get_segment2(),tri->get_segment3(),tri->get_origine());
34     lsttrim3d.ajouter(nvtri);
35     }
36 francois 447
37 francois 448 TPL_MAP_ENTITE<M3D_TRIANGLE*>::ITERATEUR it2;
38 francois 454 TPL_MAP_ENTITE<MG_NOEUD*> liste_noeud;
39 francois 448
40 francois 454
41 francois 448 for (M3D_TRIANGLE* tri=lsttrim3d.get_premier(it2);tri!=NULL;tri=lsttrim3d.get_suivant(it2))
42     {
43     mg_maillage->supprimer_mg_triangleid(tri->get_id());
44 francois 454 mg_maillage->ajouter_mg_triangle(tri);
45     liste_noeud.ajouter(tri->get_noeud1());
46     liste_noeud.ajouter(tri->get_noeud2());
47     liste_noeud.ajouter(tri->get_noeud3());
48 francois 448 }
49    
50     int nbcoquille=mgvolume->get_nb_mg_coquille();
51     for (int i=0;i<nbcoquille;i++)
52     {
53     MG_COQUILLE* coq=mgvolume->get_mg_coquille(i);
54     int nbface=coq->get_nb_mg_coface();
55     for (int j=0;j<nbface;j++)
56     {
57     MG_FACE* face=coq->get_mg_coface(j)->get_face();
58 francois 454 optimise_avec_calcul_uv(face);
59 francois 448 }
60     }
61    
62     }
63    
64 francois 573
65     void MAILLEUR2D_OPTIMISATION::optimise(MG_COQUE* mgcoque)
66     {
67     LISTE_MG_TRIANGLE::iterator ittr;
68     TPL_MAP_ENTITE<M3D_TRIANGLE*> lsttrim3d;
69     for (MG_TRIANGLE* tri=mg_maillage->get_premier_triangle(ittr);tri!=NULL;tri=mg_maillage->get_suivant_triangle(ittr))
70     {
71     M3D_TRIANGLE* nvtri=new M3D_TRIANGLE(tri->get_id(),tri->get_lien_topologie(),tri->get_noeud1(),tri->get_noeud2(),tri->get_noeud3(),tri->get_segment1(),tri->get_segment2(),tri->get_segment3(),tri->get_origine());
72     lsttrim3d.ajouter(nvtri);
73     }
74    
75     TPL_MAP_ENTITE<M3D_TRIANGLE*>::ITERATEUR it2;
76     TPL_MAP_ENTITE<MG_NOEUD*> liste_noeud;
77    
78    
79     for (M3D_TRIANGLE* tri=lsttrim3d.get_premier(it2);tri!=NULL;tri=lsttrim3d.get_suivant(it2))
80     {
81     mg_maillage->supprimer_mg_triangleid(tri->get_id());
82     mg_maillage->ajouter_mg_triangle(tri);
83     liste_noeud.ajouter(tri->get_noeud1());
84     liste_noeud.ajouter(tri->get_noeud2());
85     liste_noeud.ajouter(tri->get_noeud3());
86     }
87    
88     int nbcoquille=mgcoque->get_nb_mg_coquille();
89     for (int i=0;i<nbcoquille;i++)
90     {
91     MG_COQUILLE* coq=mgcoque->get_mg_coquille(i);
92     int nbface=coq->get_nb_mg_coface();
93     for (int j=0;j<nbface;j++)
94     {
95     MG_FACE* face=coq->get_mg_coface(j)->get_face();
96     optimise_avec_calcul_uv(face);
97     }
98     }
99    
100     }
101 francois 454 void MAILLEUR2D_OPTIMISATION::optimise_avec_calcul_uv(MG_FACE* mgface)
102     {
103     TPL_MAP_ENTITE<MG_NOEUD*> liste_noeud;
104     TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it;
105     for (MG_TRIANGLE *mgtri=(MG_TRIANGLE*)mgface->get_lien_maillage()->get_premier(it);mgtri!=NULL;mgtri=(MG_TRIANGLE*)mgface->get_lien_maillage()->get_suivant(it))
106     {
107     if (mg_maillage->get_mg_triangleid(mgtri->get_id())!=mgtri) continue;
108     liste_noeud.ajouter(mgtri->get_noeud1());
109     liste_noeud.ajouter(mgtri->get_noeud2());
110     liste_noeud.ajouter(mgtri->get_noeud3());
111     }
112     TPL_MAP_ENTITE<MG_NOEUD*>::ITERATEUR it2;
113     for (MG_NOEUD* no=liste_noeud.get_premier(it2);no!=NULL;no=liste_noeud.get_suivant(it2))
114     {
115     double uv[2];
116     double *xyz=no->get_coord();
117     mgface->inverser(uv,xyz);
118     no->change_u(uv[0]);
119     no->change_v(uv[1]);
120     }
121 sattarpa 644 reinit();
122     optimise(mgface);
123 francois 454 }
124    
125    
126    
127 sattarpa 644 void MAILLEUR2D_OPTIMISATION::reinit(void)
128     {
129 francois 696 lst_tri[0].clear();
130     lst_tri[1].clear();
131     lst_triid[0].clear();
132     lst_triid[1].clear();
133 sattarpa 644 }
134 francois 454
135    
136 francois 696 void MAILLEUR2D_OPTIMISATION::ajouter_ordre_tri(M3D_TRIANGLE* tri,int num)
137     {
138     double val;
139     if (num==0) val=tri->get_qualite();
140     if (num==1) val=1./tri->get_qualite();
141     std::pair<double,M3D_TRIANGLE*> tmp(val,tri);
142     ORDRE_TRIANGLE::iterator p=lst_tri[num].insert(tmp);
143     lst_triid[num][tri->get_id()]=p;
144     }
145 francois 454
146    
147 francois 696 void MAILLEUR2D_OPTIMISATION::supprimer_ordre_tri(M3D_TRIANGLE* tri)
148     {
149     int num=0;
150     ORDRE_TRIANGLE_PARID::iterator it=lst_triid[num].find(tri->get_id());
151     if (it==lst_triid[num].end())
152     {
153     num=1;
154     it=lst_triid[num].find(tri->get_id());
155     }
156     if (it==lst_triid[num].end()) return;
157     lst_tri[num].erase(it->second);
158     lst_triid[num].erase(it);
159     }
160    
161    
162 francois 447 void MAILLEUR2D_OPTIMISATION::optimise(MG_FACE* mgface)
163     {
164 francois 696 periode_u=mgface->get_surface()->get_periode_u();
165     periode_v=mgface->get_surface()->get_periode_v();
166     decalage=new OT_DECALAGE_PARAMETRE(periode_u,periode_v);
167     std::vector<int> strategie;
168     char* code=(char*)param.get_nom("Optimisation_2D").c_str();
169     for (int i=0;i<strlen(code);i++)
170     {
171     if (code[i]=='1') strategie.push_back(1);
172     if (code[i]=='2') strategie.push_back(2);
173     if (code[i]=='3') strategie.push_back(3);
174     if (code[i]=='4') strategie.push_back(4);
175     }
176    
177     int nb_level=strategie.size();
178     std::string info=" stratégie d'optimisation ";
179     for (int level=0;level<nb_level;level++)
180     {
181     char chaine[10];
182     sprintf(chaine,"%d",strategie[level]);
183     info = info + chaine;
184     reinit();
185 francois 447 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it;
186     for (MG_TRIANGLE *mgtri=(MG_TRIANGLE*)mgface->get_lien_maillage()->get_premier(it);mgtri!=NULL;mgtri=(MG_TRIANGLE*)mgface->get_lien_maillage()->get_suivant(it))
187     {
188 francois 448 if (mg_maillage->get_mg_triangleid(mgtri->get_id())!=mgtri) continue;
189 francois 447 M3D_TRIANGLE* mtri=(M3D_TRIANGLE*)mgtri;
190     double qual=OPERATEUR::qualite_triangle(mtri->get_noeud1()->get_coord(),mtri->get_noeud2()->get_coord(),mtri->get_noeud3()->get_coord());
191     mtri->change_qualite(qual);
192     if (mtri->get_qualite()<0.1*niveau_optimisation)
193 francois 696 ajouter_ordre_tri(mtri,0);
194 francois 447 }
195 francois 696
196 francois 447 for (int phase=0;phase<2;phase++)
197     {
198     int ok=0;
199     do
200     {
201 francois 696 ORDRE_TRIANGLE::iterator i=lst_tri[phase].begin();
202     if (i==lst_tri[phase].end())
203 francois 447 {
204     ok=1;
205     continue;
206     }
207     M3D_TRIANGLE* tri=(*i).second;
208 francois 696 supprimer_ordre_tri(tri);
209     switch (strategie[level])
210     {
211     case 1: operateur_bouge_de_point(phase,mgface,tri);
212     break;
213     case 2: operateur_inverse_diagonale(phase,mgface,&tri);
214     break;
215     case 3: operateur_bouge_de_point(phase,mgface,tri);
216     operateur_inverse_diagonale(phase,mgface,&tri);
217     break;
218     case 4: operateur_inverse_diagonale(phase,mgface,&tri);
219     if (tri!=NULL) operateur_bouge_de_point(phase,mgface,tri);
220     break;
221     }
222     if (tri!=NULL)
223 francois 447 if ((tri->get_qualite()<0.1*niveau_optimisation) && (phase==0))
224 francois 696 ajouter_ordre_tri(tri,1);
225 francois 447 }
226     while (ok==0);
227     }
228 francois 696 }
229     affiche((char*)info.c_str());
230 francois 447 delete decalage;
231     }
232    
233 francois 696 int MAILLEUR2D_OPTIMISATION::inverse_diagonale(MG_FACE* face,int num,M3D_TRIANGLE* tri,M3D_TRIANGLE** autretri,double &crit,MG_NOEUD** tabnoeudres)
234     {
235     MG_SEGMENT* seg;
236     MG_NOEUD* no1;
237     MG_NOEUD* no2;
238     MG_NOEUD* no3;
239     if (tri->get_origine()==IMPOSE) return 0;
240     if (num==0)
241     {
242     seg=tri->get_segment1();
243     no1=tri->get_noeud1();
244     no2=tri->get_noeud2();
245     no3=tri->get_noeud3();
246     }
247     else if (num==1)
248     {
249     seg=tri->get_segment2();
250     no1=tri->get_noeud2();
251     no2=tri->get_noeud3();
252     no3=tri->get_noeud1();
253     }
254     else if (num==2)
255     {
256     seg=tri->get_segment3();
257     no1=tri->get_noeud3();
258     no2=tri->get_noeud1();
259     no3=tri->get_noeud2();
260     }
261     else return 0;
262     if (seg->get_lien_topologie()!=face) return 0;
263 francois 447
264    
265 francois 696 *autretri=NULL;
266     for (int i=0;i<no1->get_lien_triangle()->get_nb();i++)
267     for (int j=0;j<no2->get_lien_triangle()->get_nb();j++)
268     {
269     MG_TRIANGLE* tri1=no1->get_lien_triangle()->get(i);
270     MG_TRIANGLE* tri2=no2->get_lien_triangle()->get(j);
271     if (tri1==tri2)
272     if (tri1!=tri) *autretri=(M3D_TRIANGLE*)tri1;
273     }
274     if ((*autretri)==NULL) return 0;
275     if ((*autretri)->get_origine()==IMPOSE) return 0;
276     MG_NOEUD* no4;
277     if (((*autretri)->get_noeud1()!=no1) && ((*autretri)->get_noeud1()!=no2)) no4=(*autretri)->get_noeud1();
278     if (((*autretri)->get_noeud2()!=no1) && ((*autretri)->get_noeud2()!=no2)) no4=(*autretri)->get_noeud2();
279     if (((*autretri)->get_noeud3()!=no1) && ((*autretri)->get_noeud3()!=no2)) no4=(*autretri)->get_noeud3();
280     double qual1=tri->get_qualite();
281     double qual2=(*autretri)->get_qualite();
282     double qualmin=std::min(qual1,qual2);
283     double nqual1=OPERATEUR::qualite_triangle(no1->get_coord(),no4->get_coord(),no3->get_coord());
284     double nqual2=OPERATEUR::qualite_triangle(no2->get_coord(),no3->get_coord(),no4->get_coord());
285     OT_VECTEUR_3D n1n3(no1->get_coord(),no3->get_coord());
286     OT_VECTEUR_3D n1n4(no1->get_coord(),no4->get_coord());
287     double xyznormal[3];
288     double uv[2]={no1->get_u(),no1->get_v()};
289     face->calcul_normale_unitaire(uv,xyznormal);
290     OT_VECTEUR_3D normalface(xyznormal);
291     OT_VECTEUR_3D normal=normalface&n1n3;
292     normal.norme();
293     n1n4.norme();
294     if (normal*n1n4<0.0001) nqual1=0.;
295     OT_VECTEUR_3D n2n4(no2->get_coord(),no4->get_coord());
296     OT_VECTEUR_3D n2n3(no2->get_coord(),no3->get_coord());
297     double uv2[2]={no2->get_u(),no2->get_v()};
298     face->calcul_normale_unitaire(uv2,xyznormal);
299     OT_VECTEUR_3D normalface2(xyznormal);
300     OT_VECTEUR_3D normal2=normalface&n2n4;
301     normal2.norme();
302     n2n3.norme();
303     if (normal2*n2n3<0.0001) nqual2=0.;
304     double nqualmin=std::min(nqual1,nqual2);
305     if (nqualmin>qualmin)
306     {
307     crit=nqualmin;
308     tabnoeudres[0]=no1;
309     tabnoeudres[1]=no4;
310     tabnoeudres[2]=no3;
311     tabnoeudres[3]=no2;
312     tabnoeudres[4]=no3;
313     tabnoeudres[5]=no4;
314     return 1;
315     }
316     return 0;
317     }
318    
319 francois 447 int MAILLEUR2D_OPTIMISATION::bouge_point(MG_FACE* mgface,MG_NOEUD* mg_noeud,double& crit,double &u,double& v,double& x,double& y, double& z)
320     {
321     if (mg_noeud->get_lien_topologie()!=mgface) return 0;
322     if (mg_noeud->get_origine()==IMPOSE) return 0;
323     double du=decalage->calcul_decalage_parametre_u(mg_noeud->get_u());
324     double dv=decalage->calcul_decalage_parametre_v(mg_noeud->get_v());
325     double u1=decalage->decalage_parametre_u(mg_noeud->get_u(),du);
326     double v1=decalage->decalage_parametre_v(mg_noeud->get_v(),dv);
327     double uopt=0.;
328     double vopt=0.;
329     double qual_dep=1.;
330     int nb_tri=mg_noeud->get_lien_triangle()->get_nb();
331     for (int i=0;i<nb_tri;i++)
332     {
333     M3D_TRIANGLE* tri=(M3D_TRIANGLE*)mg_noeud->get_lien_triangle()->get(i);
334     qual_dep=std::min(qual_dep,tri->get_qualite());
335     MG_NOEUD* no1=tri->get_noeud1();
336     MG_NOEUD* no2=tri->get_noeud2();
337     MG_NOEUD* no3=tri->get_noeud3();
338     MG_NOEUD *noeud1,*noeud2;
339     if (no1==mg_noeud)
340     {
341     noeud1=no2;
342     noeud2=no3;
343     }
344     if (no2==mg_noeud)
345     {
346     noeud1=no1;
347     noeud2=no3;
348     }
349     if (no3==mg_noeud)
350     {
351     noeud1=no1;
352     noeud2=no2;
353     }
354     double u2=noeud1->get_u()+du;
355     double v2=noeud1->get_v()+dv;
356     uopt=uopt+u2;
357     vopt=vopt+v2;
358     u2=noeud2->get_u()+du;
359     v2=noeud2->get_v()+dv;
360     uopt=uopt+u2;
361     vopt=vopt+v2;
362     }
363     uopt=uopt/2./nb_tri;
364     vopt=vopt/2./nb_tri;
365    
366     double ddeb=sqrt((u1-uopt)*(u1-uopt)+(v1-vopt)*(v1-vopt));
367     double alpha=0.5;
368     double d=alpha*ddeb;
369     double qual=qual_dep;
370     double testu[8]={1.,-1.,0.,0.,0.707106781,-0.707106781,-0.707106781,0.707106781};
371     double testv[8]={0.,0.,1.,-1.,0.707106781,0.707106781,-0.707106781,-0.707106781};
372     double uu=u1;
373     double vv=v1;
374     while (alpha>0.09)
375     {
376     double qualcoq=0.;
377     for (int nb_essai=0;nb_essai<8;nb_essai++)
378     {
379     double uv[2];
380     double xyz[3];
381     uv[0]=uu+d*testu[nb_essai]-du;
382     uv[1]=vv+d*testv[nb_essai]-dv;
383     int valide1=mgface->valide_parametre_u(uv[0]);
384     int valide2=mgface->valide_parametre_v(uv[1]);
385     if (!((valide1) && (valide2) )) break;
386     mgface->evaluer(uv,xyz);
387     double qual1=1.;
388     for (int i=0;i<nb_tri;i++)
389     {
390     M3D_TRIANGLE* tri=(M3D_TRIANGLE*)mg_noeud->get_lien_triangle()->get(i);
391     MG_NOEUD* no1=tri->get_noeud1();
392     MG_NOEUD* no2=tri->get_noeud2();
393     MG_NOEUD* no3=tri->get_noeud3();
394     double *xyz1=no1->get_coord();
395     double *xyz2=no2->get_coord();
396     double *xyz3=no3->get_coord();
397     if (no1==mg_noeud) xyz1=xyz;
398     if (no2==mg_noeud) xyz2=xyz;
399     if (no3==mg_noeud) xyz3=xyz;
400     double qualtmp=OPERATEUR::qualite_triangle(xyz1,xyz2,xyz3);
401     OT_VECTEUR_3D n1n3(xyz1,xyz3);
402     OT_VECTEUR_3D n1n2(xyz1,xyz2);
403     double xyznormal[3];
404     mgface->calcul_normale_unitaire(uv,xyznormal);
405     OT_VECTEUR_3D normalface(xyznormal);
406     OT_VECTEUR_3D normal=normalface&n1n3;
407     normal.norme();
408     n1n2.norme();
409     if (normal*n1n2<0.0001) qualtmp=0.;
410     if (qualtmp<qual1) qual1=qualtmp;
411     }
412     if (qual1>qualcoq)
413     {
414     qualcoq=qual1;
415     crit=qualcoq;
416     u=uv[0]+du;
417     v=uv[1]+dv;
418     }
419     }
420    
421     if (qualcoq<qual+0.0001) alpha=alpha-0.1;
422     else
423     {
424     qual=qualcoq;
425     uu=u;
426     vv=v;
427     }
428     d=ddeb*alpha;
429    
430     }
431     if (qual>qual_dep)
432     {
433     u=decalage->decalage_parametre_u(u,-du);
434     v=decalage->decalage_parametre_v(v,-dv);
435     double uv[2];
436     uv[0]=u;
437     uv[1]=v;
438     double xyz[3];
439     mgface->evaluer(uv,xyz);
440     x=xyz[0];
441     y=xyz[1];
442     z=xyz[2];
443     return 1;
444     }
445     return 0;
446     }
447 francois 696
448     class M3D_TRIANGLE* MAILLEUR2D_OPTIMISATION::insere_triangle(class MG_FACE* mgface,MG_NOEUD* noeud1,MG_NOEUD* noeud2,MG_NOEUD* noeud3,int origine)
449     {
450     MG_SEGMENT* segment1=mg_maillage->get_mg_segment(noeud1->get_id(),noeud2->get_id());
451     MG_SEGMENT* segment2=mg_maillage->get_mg_segment(noeud1->get_id(),noeud3->get_id());
452     MG_SEGMENT* segment3=mg_maillage->get_mg_segment(noeud2->get_id(),noeud3->get_id());
453     if (segment1==NULL) segment1=cree_segment(mgface,noeud1,noeud2,origine);
454     if (segment2==NULL) segment2=cree_segment(mgface,noeud1,noeud3,origine);
455     if (segment3==NULL) segment3=cree_segment(mgface,noeud2,noeud3,origine);
456     M3D_TRIANGLE* tri=cree_triangle(mgface,noeud1,noeud2,noeud3,segment1,segment2,segment3,origine);
457     double qual=OPERATEUR::qualite_triangle(noeud1->get_coord(),noeud2->get_coord(),noeud3->get_coord());
458     tri->change_qualite(qual);
459     return tri;
460     }
461    
462    
463    
464    
465     void MAILLEUR2D_OPTIMISATION::operateur_bouge_de_point(int phase,MG_FACE* mgface,M3D_TRIANGLE* tri)
466     {
467     if (tri->get_qualite()<0.1*niveau_optimisation)
468     {
469     MG_NOEUD* no[3];
470     no[0]=tri->get_noeud1();
471     no[1]=tri->get_noeud2();
472     no[2]=tri->get_noeud3();
473     double crit[3],u[3],v[3],x[3],y[3],z[3];
474     int ierr=bouge_point(mgface,no[0],crit[0],u[0],v[0],x[0],y[0],z[0]);
475     if (ierr==0) crit[0]=0.;
476     ierr=bouge_point(mgface,no[1],crit[1],u[1],v[1],x[1],y[1],z[1]);
477     if (ierr==0) crit[1]=0.;
478     ierr=bouge_point(mgface,no[2],crit[2],u[2],v[2],x[2],y[2],z[2]);
479     if (ierr==0) crit[2]=0.;
480     double critopt=std::max(crit[0],crit[1]);
481     critopt=std::max(critopt,crit[2]);
482     int num=-1;
483     if (critopt>tri->get_qualite())
484     {
485     if (critopt==crit[0]) num=0;
486     if (critopt==crit[1]) num=1;
487     if (critopt==crit[2]) num=2;
488     }
489     if (num!=-1)
490     {
491     no[num]->change_u(u[num]);
492     no[num]->change_v(v[num]);
493     no[num]->change_x(x[num]);
494     no[num]->change_y(y[num]);
495     no[num]->change_z(z[num]);
496     int nb_tri=no[num]->get_lien_triangle()->get_nb();
497     for (int i=0;i<nb_tri;i++)
498     {
499     M3D_TRIANGLE* mtri=(M3D_TRIANGLE*)no[num]->get_lien_triangle()->get(i);
500     double qual=OPERATEUR::qualite_triangle(mtri->get_noeud1()->get_coord(),mtri->get_noeud2()->get_coord(),mtri->get_noeud3()->get_coord());
501     mtri->change_qualite(qual);
502     if (mtri!=tri)
503     {
504     supprimer_ordre_tri(mtri);
505     if (mtri->get_qualite()<0.1*niveau_optimisation) ajouter_ordre_tri(mtri,phase);
506     }
507    
508     }
509     }
510     }
511     }
512    
513    
514     void MAILLEUR2D_OPTIMISATION::operateur_inverse_diagonale(int phase,MG_FACE* mgface,M3D_TRIANGLE** tri)
515     {
516     if ((*tri)->get_qualite()<0.1*niveau_optimisation)
517     {
518     MG_NOEUD* tab1[6];
519     MG_NOEUD* tab2[6];
520     MG_NOEUD* tab3[6];
521     double crit1,crit2,crit3;
522     M3D_TRIANGLE* autretri1;
523     M3D_TRIANGLE* autretri2;
524     M3D_TRIANGLE* autretri3;
525     int ierr1=inverse_diagonale(mgface,0,*tri,&autretri1,crit1,tab1);
526     int ierr2=inverse_diagonale(mgface,1,*tri,&autretri2,crit2,tab2);
527     int ierr3=inverse_diagonale(mgface,2,*tri,&autretri3,crit3,tab3);
528     double maxcrit=std::max(ierr1*crit1,ierr2*crit2);
529     maxcrit=std::max(maxcrit,ierr3*crit3);
530     MG_NOEUD** tab;
531     M3D_TRIANGLE *autretri;
532     if (maxcrit>(*tri)->get_qualite())
533     {
534     if (maxcrit==ierr1*crit1) {tab=tab1;autretri=autretri1;}
535     if (maxcrit==ierr2*crit2) {tab=tab2;autretri=autretri2;}
536     if (maxcrit==ierr3*crit3) {tab=tab3;autretri=autretri3;}
537     M3D_TRIANGLE* nvtri1=insere_triangle(mgface,tab[0],tab[1],tab[2],MAILLEUR_AUTO);
538     M3D_TRIANGLE* nvtri2=insere_triangle(mgface,tab[3],tab[4],tab[5],MAILLEUR_AUTO);
539     if (nvtri1->get_qualite()<0.1*niveau_optimisation) ajouter_ordre_tri(nvtri1,phase);
540     if (nvtri2->get_qualite()<0.1*niveau_optimisation) ajouter_ordre_tri(nvtri2,phase);
541     supprimer_ordre_tri(autretri);
542     mg_maillage->supprimer_mg_triangleid((*tri)->get_id());(*tri)=NULL;
543     mg_maillage->supprimer_mg_triangleid(autretri->get_id());
544     }
545     }
546     }
547     M3D_TRIANGLE* MAILLEUR2D_OPTIMISATION::cree_triangle(class MG_FACE* mgface,MG_NOEUD* noeud1,MG_NOEUD* noeud2,MG_NOEUD* noeud3,MG_SEGMENT* segment1,MG_SEGMENT* segment2,MG_SEGMENT* segment3,int origine)
548     {
549     M3D_TRIANGLE* tri=new M3D_TRIANGLE(mgface,noeud1,noeud2,noeud3,segment1,segment2,segment3,origine);
550     mg_maillage->ajouter_mg_triangle(tri);
551     return tri;
552     }
553    
554    
555    
556     MG_SEGMENT* MAILLEUR2D_OPTIMISATION::cree_segment(class MG_FACE* mgface,MG_NOEUD* noeud1,MG_NOEUD* noeud2,int origine)
557     {
558     MG_SEGMENT* seg=mg_maillage->ajouter_mg_segment(mgface,noeud1,noeud2,origine);
559     seg->change_dimension_topo_null(3);
560     return seg;
561     }