ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/mailleur/src/mailleur3d_optimisation.cpp
Revision: 287
Committed: Wed Oct 19 20:55:30 2011 UTC (13 years, 6 months ago) by francois
File size: 22436 byte(s)
Log Message:
Dissociation du mailleur 3D et de l'optimisateur 3D

File Contents

# User Rev Content
1 francois 283 //------------------------------------------------------------
2     //------------------------------------------------------------
3     // MAGiC
4     // Jean Christophe Cuilli�e et Vincent FRANCOIS
5     // D�artement de G�ie M�anique - UQTR
6     //------------------------------------------------------------
7     // Le projet MAGIC est un projet de recherche du d�artement
8     // de g�ie m�anique de l'Universit�du Qu�ec �
9     // Trois Rivi�es
10     // Les librairies ne peuvent �re utilis�s sans l'accord
11     // des auteurs (contact : francois@uqtr.ca)
12     //------------------------------------------------------------
13     //------------------------------------------------------------
14     //
15     // mailleur3d.cpp
16     //
17     //------------------------------------------------------------
18     //------------------------------------------------------------
19     // COPYRIGHT 2000
20     // Version du 02/03/2006 �11H23
21     //------------------------------------------------------------
22     //------------------------------------------------------------
23    
24    
25     #include "gestionversion.h"
26 francois 287 #include "mailleur3d_optimisation.h"
27 francois 283 #include "ot_mathematique.h"
28     #include "m3d_tetra.h"
29 francois 287 #include "m3d_triangle.h"
30 francois 283 #include "m3d_noeud.h"
31 francois 287 #include "mg_maillage.h"
32 francois 283 //#include "mg_gestionnaire.h"
33     #include <math.h>
34    
35     //---------------------------------------------------------------------------
36    
37     //#pragma package(smart_init)
38    
39 francois 287
40     MAILLEUR3D_OPTIMISATION::MAILLEUR3D_OPTIMISATION(MG_MAILLAGE* mgmai,int niv):mg_maillage(mgmai),niveau_optimisation(niv),affichageactif(0)
41 francois 283 {
42 francois 287 o3d_data();
43     o3d_data2();
44     }
45    
46     MAILLEUR3D_OPTIMISATION::~MAILLEUR3D_OPTIMISATION()
47     {
48     }
49    
50    
51    
52     double MAILLEUR3D_OPTIMISATION::get_volume(MG_TETRA* tet)
53     {
54 francois 283 double *xyz1=tet->get_noeud1()->get_coord();
55     double *xyz2=tet->get_noeud2()->get_coord();
56     double *xyz3=tet->get_noeud3()->get_coord();
57     double *xyz4=tet->get_noeud4()->get_coord();
58     OT_VECTEUR_3D ab(xyz1,xyz2);
59     OT_VECTEUR_3D ac(xyz1,xyz3);
60     OT_VECTEUR_3D ad(xyz1,xyz4);
61     double vol=(ab&ac)*ad;
62     vol=vol/6.;
63     return vol;
64     }
65    
66 francois 287 double MAILLEUR3D_OPTIMISATION::get_volume(double *xyz1,double *xyz2,double *xyz3,double *xyz4)
67 francois 283 {
68     OT_VECTEUR_3D ab(xyz1,xyz2);
69     OT_VECTEUR_3D ac(xyz1,xyz3);
70     OT_VECTEUR_3D ad(xyz1,xyz4);
71     double vol=(ab&ac)*ad;
72     vol=vol/6.;
73     return vol;
74     }
75    
76 francois 287 void MAILLEUR3D_OPTIMISATION::optimise(MG_VOLUME* mgvol,int& nbmauvais)
77 francois 283 {
78     static int passe=0;
79     passe++;
80     //preparation
81     TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it;
82     int nbtet=0;
83     for (MG_TETRA* tet=(MG_TETRA*)mgvol->get_lien_maillage()->get_premier(it);tet;tet=(MG_TETRA*)mgvol->get_lien_maillage()->get_suivant(it))
84     {
85     if (mg_maillage->get_mg_tetraid(tet->get_id())==NULL) continue;
86     M3D_TETRA* mtet=(M3D_TETRA*)tet;
87     double qual=OPERATEUR::qualite_tetra(mtet->get_noeud1()->get_coord(),mtet->get_noeud2()->get_coord(),mtet->get_noeud3()->get_coord(),mtet->get_noeud4()->get_coord());
88     mtet->change_qualite(qual);
89     if (qual<0.1*niveau_optimisation) nbtet++;
90     ajouter_ordre_tetra(mtet,0);
91     }
92 francois 287
93 francois 283 //on commence
94    
95     for (int phase=0;phase<2;phase++)
96     {
97     char mess[255];
98     if (phase==0) sprintf(mess," Phase %d : %d a optimiser",2*passe-1+phase,nbtet);
99     if (phase==1) sprintf(mess," Phase %d",2*passe-1+phase);
100     if (affichageactif==1) affiche(mess);
101     while (lst_tetra[phase].size()>0)
102     {
103     ORDRE_TETRA::iterator i=lst_tetra[phase].begin();
104     M3D_TETRA* tet=(*i).second;
105     supprimer_ordre_tetra(tet);
106     double crit_avant=tet->get_qualite();
107     if (crit_avant<0.5)
108     {
109     double crit[4]={-1.,-1.,-1.,-1.};
110     M3D_NOEUD* no[4];
111     no[0]=(M3D_NOEUD*)tet->get_noeud1();
112     no[1]=(M3D_NOEUD*)tet->get_noeud2();
113     no[2]=(M3D_NOEUD*)tet->get_noeud3();
114     no[3]=(M3D_NOEUD*)tet->get_noeud4();
115     double x[4],y[4],z[4];
116     bouge_point(mgvol,no[0],crit[0],x[0],y[0],z[0]);
117     bouge_point(mgvol,no[1],crit[1],x[1],y[1],z[1]);
118     bouge_point(mgvol,no[2],crit[2],x[2],y[2],z[2]);
119     bouge_point(mgvol,no[3],crit[3],x[3],y[3],z[3]);
120     std::vector<double> vecteur_crit(crit,crit+4);
121     std::vector<double>::iterator it1 = max_element(vecteur_crit.begin(), vecteur_crit.end());
122     double crit_opt=*it1;
123     if (crit_opt>crit_avant)
124     {
125     int num=it1-vecteur_crit.begin();
126     no[num]->change_x(x[num]);
127     no[num]->change_y(y[num]);
128     no[num]->change_z(z[num]);
129     int nb=no[num]->get_lien_tetra()->get_nb();
130     for (int j=0;j<nb;j++)
131     {
132     M3D_TETRA* mtet=(M3D_TETRA*)no[num]->get_lien_tetra()->get(j);
133     double qual=OPERATEUR::qualite_tetra(mtet->get_noeud1()->get_coord(),mtet->get_noeud2()->get_coord(),mtet->get_noeud3()->get_coord(),mtet->get_noeud4()->get_coord());
134     mtet->change_qualite(qual);
135     }
136     crit_avant=crit_opt;
137     }
138     }
139     int coquille_non_optimise=1;
140     if (crit_avant<0.5)
141     {
142     COQUILLE coque[6];
143     double crit[6]={-1,-1,-1,-1,-1,-1};
144     remaille_coquille(tet->get_noeud1(),tet->get_noeud2(),crit[0],coque[0]);
145     remaille_coquille(tet->get_noeud1(),tet->get_noeud3(),crit[1],coque[1]);
146     remaille_coquille(tet->get_noeud1(),tet->get_noeud4(),crit[2],coque[2]);
147     remaille_coquille(tet->get_noeud2(),tet->get_noeud3(),crit[3],coque[3]);
148     remaille_coquille(tet->get_noeud2(),tet->get_noeud3(),crit[4],coque[4]);
149     remaille_coquille(tet->get_noeud3(),tet->get_noeud4(),crit[5],coque[5]);
150     std::vector<double> vecteur_crit(crit,crit+6);
151     std::vector<double>::iterator it1 = max_element(vecteur_crit.begin(), vecteur_crit.end());
152     double crit_opt=*it1;
153     if (crit_opt>crit_avant)
154     {
155     coquille_non_optimise=0;
156     int num=it1-vecteur_crit.begin();
157     for (int i=0;i<coque[num].taille;i++)
158     {
159     M3D_TETRA *tettmp=(M3D_TETRA*)coque[num].tet[i];
160     if (tet!=tettmp) supprimer_ordre_tetra(tettmp);
161     mg_maillage->supprimer_mg_tetraid(coque[num].tet[i]->get_id());
162     }
163     for (int i=0;i<2*coque[num].taille-4;i++)
164     {
165     MG_NOEUD* noeud1=coque[num].new_tetra[4*i];
166     MG_NOEUD* noeud2=coque[num].new_tetra[4*i+1];
167     MG_NOEUD* noeud3=coque[num].new_tetra[4*i+2];
168     MG_NOEUD* noeud4=coque[num].new_tetra[4*i+3];
169     MG_TRIANGLE* triangle1=mg_maillage->get_mg_triangle(noeud1->get_id(),noeud3->get_id(),noeud2->get_id());
170     MG_TRIANGLE* triangle2=mg_maillage->get_mg_triangle(noeud1->get_id(),noeud2->get_id(),noeud4->get_id());
171     MG_TRIANGLE* triangle3=mg_maillage->get_mg_triangle(noeud2->get_id(),noeud3->get_id(),noeud4->get_id());
172     MG_TRIANGLE* triangle4=mg_maillage->get_mg_triangle(noeud1->get_id(),noeud4->get_id(),noeud3->get_id());
173     if (triangle1==NULL) triangle1=insere_triangle(mgvol,noeud1,noeud3,noeud2,MAILLEUR_AUTO);
174     if (triangle2==NULL) triangle2=insere_triangle(mgvol,noeud1,noeud2,noeud4,MAILLEUR_AUTO);
175     if (triangle3==NULL) triangle3=insere_triangle(mgvol,noeud2,noeud3,noeud4,MAILLEUR_AUTO);
176     if (triangle4==NULL) triangle4=insere_triangle(mgvol,noeud1,noeud4,noeud3,MAILLEUR_AUTO);
177     M3D_TETRA* mtet=new M3D_TETRA(mgvol,noeud1,noeud2,noeud3,noeud4,triangle1,triangle2,triangle3,triangle4,MAILLEUR_AUTO);
178     mg_maillage->ajouter_mg_tetra(mtet);
179     double qual=OPERATEUR::qualite_tetra(mtet->get_noeud1()->get_coord(),mtet->get_noeud2()->get_coord(),mtet->get_noeud3()->get_coord(),mtet->get_noeud4()->get_coord());
180     mtet->change_qualite(qual);
181     if (phase==0)
182     ajouter_ordre_tetra(mtet,1);
183     }
184    
185    
186     }
187    
188     }
189     if ((phase==0) && (coquille_non_optimise==1))
190     ajouter_ordre_tetra(tet,1);
191     }
192    
193     }
194     int nb=0;
195     for (MG_TETRA* tet=(MG_TETRA*)mgvol->get_lien_maillage()->get_premier(it);tet;tet=(MG_TETRA*)mgvol->get_lien_maillage()->get_suivant(it))
196     {
197     if (mg_maillage->get_mg_tetraid(tet->get_id())==NULL) continue;
198     M3D_TETRA* mtet=(M3D_TETRA*)tet;
199     if (mtet->get_qualite()<0.1*niveau_optimisation) nb++;
200     }
201    
202     nbmauvais=nb;
203    
204     }
205    
206    
207    
208    
209    
210 francois 287 int MAILLEUR3D_OPTIMISATION::bouge_point(MG_VOLUME* mgvol,M3D_NOEUD* noeud,double& crit,double& x,double& y, double& z)
211 francois 283 {
212     if (noeud->get_lien_topologie()!=mgvol) return 0;
213     if (noeud->get_origine()!=MAILLEUR_AUTO) return 0;
214    
215     double xopt=0.;
216     double yopt=0.;
217     double zopt=0.;
218     double qual_dep=1.;
219     int nb_tet=noeud->get_lien_tetra()->get_nb();
220     double tab_coord[3000];
221     double gamma=0;
222     for (int i=0;i<nb_tet;i++)
223     {
224     M3D_TETRA* tet=(M3D_TETRA*)noeud->get_lien_tetra()->get(i);
225     qual_dep=std::min(qual_dep,tet->get_qualite());
226     MG_NOEUD* no1=tet->get_noeud1();
227     MG_NOEUD* no2=tet->get_noeud2();
228     MG_NOEUD* no3=tet->get_noeud3();
229     MG_NOEUD* no4=tet->get_noeud4();
230     MG_NOEUD *noeud1,*noeud2,*noeud3;
231     if (no1==noeud)
232     {
233     noeud1=no2;
234     noeud2=no4;
235     noeud3=no3;
236     }
237     if (no2==noeud)
238     {
239     noeud1=no1;
240     noeud2=no3;
241     noeud3=no4;
242     }
243     if (no3==noeud)
244     {
245     noeud1=no1;
246     noeud2=no4;
247     noeud3=no2;
248     }
249     if (no4==noeud)
250     {
251     noeud1=no1;
252     noeud2=no2;
253     noeud3=no3;
254     }
255     double xyzi[3];
256     double *xyz1=noeud1->get_coord();
257     double *xyz2=noeud2->get_coord();
258     double *xyz3=noeud3->get_coord();
259     xyzi[0]=(xyz1[0]+xyz2[0]+xyz3[0])/3.;
260     xyzi[1]=(xyz1[1]+xyz2[1]+xyz3[1])/3.;
261     xyzi[2]=(xyz1[2]+xyz2[2]+xyz3[2])/3.;
262     OT_VECTEUR_3D v12(xyz1,xyz2);
263     OT_VECTEUR_3D v13(xyz1,xyz3);
264     OT_VECTEUR_3D v23(xyz2,xyz3);
265     OT_VECTEUR_3D normal=v12&v13;
266     double perimetre=v12.get_longueur()+v13.get_longueur()+v23.get_longueur();
267     double hauteur = (perimetre/3.) * 0.8 ;
268     normal.norme();
269     tab_coord[3*i]=xyzi[0]+normal.get_x()*hauteur;
270     tab_coord[3*i+1]=xyzi[1]+normal.get_y()*hauteur;
271     tab_coord[3*i+2]=xyzi[2]+normal.get_z()*hauteur;
272     if (tet->get_qualite()> 1e-10) gamma=gamma+1./tet->get_qualite()/tet->get_qualite();
273     }
274     gamma=1./gamma;
275     for (int i=0;i<nb_tet;i++)
276     {
277     M3D_TETRA* tet=(M3D_TETRA*)noeud->get_lien_tetra()->get(i);
278     if (tet->get_qualite()> 1e-10)
279     {
280     double alpha=gamma/tet->get_qualite()/tet->get_qualite();
281     xopt=xopt+alpha*tab_coord[3*i];
282     yopt=yopt+alpha*tab_coord[3*i+1];
283     zopt=zopt+alpha*tab_coord[3*i+2];
284     }
285    
286     }
287     double delta[3]={xopt-noeud->get_x(),yopt-noeud->get_y(),zopt-noeud->get_z()};
288     double bmin=0.,bmax=1.;
289     double vieuxx=noeud->get_x();
290     double vieuxy=noeud->get_y();
291     double vieuxz=noeud->get_z();
292     double qualini=0.;
293     for (int iteration=0;iteration<5;iteration++)
294     {
295     double alpha=(bmin+bmax)*0.5;
296     noeud->change_x(vieuxx+alpha*delta[0]);
297     noeud->change_y(vieuxy+alpha*delta[1]);
298     noeud->change_z(vieuxz+alpha*delta[2]);
299     double qualcour=1.;
300     for (int i=0;i<nb_tet;i++)
301     {
302     M3D_TETRA* mtet=(M3D_TETRA*)noeud->get_lien_tetra()->get(i);
303     double qual=OPERATEUR::qualite_tetra(mtet->get_noeud1()->get_coord(),mtet->get_noeud2()->get_coord(),mtet->get_noeud3()->get_coord(),mtet->get_noeud4()->get_coord());
304     qualcour=std::min(qualcour,qual);
305     }
306     double alpha_eps=(bmin+bmax)*0.5-(bmax-bmin)/50.;
307     noeud->change_x(vieuxx+alpha_eps*delta[0]);
308     noeud->change_y(vieuxy+alpha_eps*delta[1]);
309     noeud->change_z(vieuxz+alpha_eps*delta[2]);
310     double qualcour_eps=1.;
311     for (int i=0;i<nb_tet;i++)
312     {
313     M3D_TETRA* mtet=(M3D_TETRA*)noeud->get_lien_tetra()->get(i);
314     double qual=OPERATEUR::qualite_tetra(mtet->get_noeud1()->get_coord(),mtet->get_noeud2()->get_coord(),mtet->get_noeud3()->get_coord(),mtet->get_noeud4()->get_coord());
315     qualcour_eps=std::min(qualcour_eps,qual);
316     }
317     if (qualcour>qualcour_eps) bmin =alpha;
318     else bmax=alpha;
319     qualini=std::max(qualini,qualcour);
320     }
321     noeud->change_x(vieuxx);
322     noeud->change_y(vieuxy);
323     noeud->change_z(vieuxz);
324     if (qualini>qual_dep)
325     {
326     x=vieuxx+(bmin+bmax)*0.5*delta[0];
327     y=vieuxy+(bmin+bmax)*0.5*delta[1];
328     z=vieuxz+(bmin+bmax)*0.5*delta[2];
329     crit=qualini;
330     return 1;
331     }
332     return 0;
333     }
334    
335    
336    
337 francois 287 void MAILLEUR3D_OPTIMISATION::remaille_coquille(MG_NOEUD* noeud1,MG_NOEUD* noeud2, double& crit, COQUILLE& coque)
338 francois 283 {
339     //recherche du segment a supprimer
340     MG_NOEUD* noeud;
341     if (noeud1->get_id()>noeud2->get_id()) noeud=noeud2;
342     else noeud=noeud1;
343     int nb=noeud->get_lien_petit_segment()->get_nb();
344     for (int i=0;i<nb;i++)
345     {
346     MG_SEGMENT* seg=noeud->get_lien_petit_segment()->get(i);
347     if ( ((seg->get_noeud1()==noeud1) && (seg->get_noeud2()==noeud2)) || ((seg->get_noeud1()==noeud2) && (seg->get_noeud2()==noeud1)))
348     if ((seg->get_lien_topologie()->get_dimension()!=3) || (seg->get_origine()!=MAILLEUR_AUTO))
349     {
350     coque.taille=0;
351     crit=0.;
352     return;
353     }
354     }
355     //recherche des tetra qui s enroule autour du segment
356     int nb1=noeud1->get_lien_tetra()->get_nb();
357     int nb2=noeud2->get_lien_tetra()->get_nb();
358     MG_TETRA* coq[100];
359     int nb_coq=0;
360     for (int i=0;i<nb1;i++)
361     for (int j=0;j<nb2;j++)
362     if (noeud1->get_lien_tetra()->get(i)==noeud2->get_lien_tetra()->get(j))
363     {
364     coq[nb_coq]=noeud1->get_lien_tetra()->get(i);
365     nb_coq++;
366     }
367     if ((nb_coq<4) || (nb_coq>10))
368     {
369     coque.taille=0;
370     crit=0.;
371     return;
372     }
373     //recherche des noeuds qui compose la coquille
374     MG_NOEUD* tet_noeud[50];
375     int nb_tet_noeud=0;
376     coque.taille=nb_coq;
377     for (int i=0;i<nb_coq;i++)
378     {
379     coque.tet[i]=coq[i];
380     if ((coq[i]->get_noeud1()!=noeud1) && (coq[i]->get_noeud1()!=noeud2)) tet_noeud[nb_tet_noeud++]=coq[i]->get_noeud1();
381     if ((coq[i]->get_noeud2()!=noeud1) && (coq[i]->get_noeud2()!=noeud2)) tet_noeud[nb_tet_noeud++]=coq[i]->get_noeud2();
382     if ((coq[i]->get_noeud3()!=noeud1) && (coq[i]->get_noeud3()!=noeud2)) tet_noeud[nb_tet_noeud++]=coq[i]->get_noeud3();
383     if ((coq[i]->get_noeud4()!=noeud1) && (coq[i]->get_noeud4()!=noeud2)) tet_noeud[nb_tet_noeud++]=coq[i]->get_noeud4();
384     coque.volume=coque.volume+fabs(get_volume(coq[i]));
385     }
386     //ordonnancement des noeuds qui compose la coquille en polygone
387     MG_NOEUD* polygone[20];
388     int nb_poly=2;
389     polygone[0]=tet_noeud[0];
390     tet_noeud[0]=NULL;
391     polygone[1]=tet_noeud[1];
392     tet_noeud[1]=NULL;
393     while (nb_poly!=nb_coq+1)
394     {
395     for (int j=0;j<nb_coq;j++)
396     {
397     if (tet_noeud[2*j]==polygone[nb_poly-1])
398     {
399     polygone[nb_poly++]=tet_noeud[2*j+1];
400     tet_noeud[2*j]=NULL;
401     tet_noeud[2*j+1]=NULL;
402     }
403     if (tet_noeud[2*j+1]==polygone[nb_poly-1])
404     {
405     polygone[nb_poly++]=tet_noeud[2*j];
406     tet_noeud[2*j]=NULL;
407     tet_noeud[2*j+1]=NULL;
408     }
409    
410     }
411     }
412     //etude du positionnement du polygone
413     double vol1=get_volume(polygone[0]->get_coord(),polygone[1]->get_coord(),polygone[nb_poly-1]->get_coord(),noeud1->get_coord());
414     double vol2=get_volume(polygone[0]->get_coord(),polygone[nb_poly-1]->get_coord(),polygone[1]->get_coord(),noeud2->get_coord());
415     if (vol1*vol2<0.)
416     {
417     crit=0.;
418     coque.taille=0;
419     return;
420     }
421     MG_NOEUD *noeuda=noeud1;
422     MG_NOEUD *noeudb=noeud2;
423     if (vol1<0.)
424     {
425     noeuda=noeud2;
426     noeudb=noeud1;
427     }
428     //Examen des solutions
429     int nb_solution,nb_triangle;
430     if (nb_coq==4) {
431     nb_solution=2;
432     nb_triangle=4;
433     }
434     if (nb_coq==5) {
435     nb_solution=5;
436     nb_triangle=10;
437     }
438     if (nb_coq==6) {
439     nb_solution=14;
440     nb_triangle=20;
441     }
442     if (nb_coq==7) {
443     nb_solution=42;
444     nb_triangle=35;
445     }
446     if (nb_coq==8) {
447     nb_solution=132;
448     nb_triangle=56;
449     }
450     if (nb_coq==9) {
451     nb_solution=429;
452     nb_triangle=84;
453     }
454     if (nb_coq==10) {
455     nb_solution=1430;
456     nb_triangle=120;
457     }
458     double crit_triangle[120];
459     for (int i=0;i<nb_triangle;i++)
460     {
461     double crit1=OPERATEUR::qualite_tetra(polygone[tab_face[nb_coq-4][i][0]]->get_coord(),polygone[tab_face[nb_coq-4][i][1]]->get_coord(),polygone[tab_face[nb_coq-4][i][2]]->get_coord(),noeuda->get_coord());
462     double crit2=OPERATEUR::qualite_tetra(polygone[tab_face[nb_coq-4][i][0]]->get_coord(),polygone[tab_face[nb_coq-4][i][2]]->get_coord(),polygone[tab_face[nb_coq-4][i][1]]->get_coord(),noeudb->get_coord());
463     crit_triangle[i]=std::min(crit1,crit2);
464     }
465     /* examen de chaque solution */
466     double crit_opt=0.;
467     int numero_solution= -1;
468     double crit_solution[1430];
469     for (int i=0;i<nb_solution;i++)
470     {
471     double volume=0.;
472     for (int j=0;j<nb_coq-2;j++)
473     {
474     MG_NOEUD* noa=polygone[tab_face[nb_coq-4][tab_solution[nb_coq-4][i][j]][0]];
475     MG_NOEUD* nob=polygone[tab_face[nb_coq-4][tab_solution[nb_coq-4][i][j]][1]];
476     MG_NOEUD* noc=polygone[tab_face[nb_coq-4][tab_solution[nb_coq-4][i][j]][2]];
477     MG_NOEUD* nod=noeuda;
478     volume=volume+fabs(get_volume(noa->get_coord(),nob->get_coord(),noc->get_coord(),nod->get_coord()));
479     nod=noeudb;
480     volume=volume+fabs(get_volume(noa->get_coord(),nob->get_coord(),noc->get_coord(),nod->get_coord()));
481     }
482     double eps=0.0018*pow(volume,0.666666666);
483     if (OPERATEUR::egal(volume,coque.volume,eps))
484     {
485     crit_solution[i]=1.;
486     for (int j=0;j<nb_coq-2;j++)
487     crit_solution[i]=std::min(crit_solution[i],crit_triangle[tab_solution[nb_coq-4][i][j]]);
488     }
489     else crit_solution[i]=0.;
490     if (crit_opt<crit_solution[i])
491     {
492     crit_opt=crit_solution[i];
493     numero_solution=i;
494     }
495    
496     }
497     if (numero_solution==(-1))
498     {
499     crit=0.;
500     coque.taille=0;
501     return;
502     }
503     crit=crit_opt;
504     for (int j=0;j<nb_coq-2;j++)
505     {
506     MG_NOEUD* noa=polygone[tab_face[nb_coq-4][tab_solution[nb_coq-4][numero_solution][j]][0]];
507     MG_NOEUD* nob=polygone[tab_face[nb_coq-4][tab_solution[nb_coq-4][numero_solution][j]][1]];
508     MG_NOEUD* noc=polygone[tab_face[nb_coq-4][tab_solution[nb_coq-4][numero_solution][j]][2]];
509     coque.new_tetra[8*j]=noa;
510     coque.new_tetra[8*j+1]=nob;
511     coque.new_tetra[8*j+2]=noc;
512     coque.new_tetra[8*j+3]=noeuda;
513     coque.new_tetra[8*j+4]=noa;
514     coque.new_tetra[8*j+5]=noc;
515     coque.new_tetra[8*j+6]=nob;
516     coque.new_tetra[8*j+7]=noeudb;
517     }
518     }
519    
520    
521 francois 287 void MAILLEUR3D_OPTIMISATION::ajouter_ordre_tetra(M3D_TETRA* tet,int num)
522 francois 283 {
523     std::pair<double,M3D_TETRA*> tmp(pow(tet->get_qualite(),1-2*num),tet);
524     ORDRE_TETRA::iterator p=lst_tetra[num].insert(tmp);
525     lst_tetraid[num][tet->get_id()]=p;
526     }
527    
528 francois 287 void MAILLEUR3D_OPTIMISATION::supprimer_ordre_tetra(M3D_TETRA* tet)
529 francois 283 {
530     int num=0;
531     ORDRE_TETRA_PARID::iterator it=lst_tetraid[num].find(tet->get_id());
532     if (it==lst_tetraid[num].end())
533     {
534     num=1;
535     it=lst_tetraid[num].find(tet->get_id());
536     }
537     if (it==lst_tetraid[num].end()) return;
538     lst_tetra[num].erase(it->second);
539     lst_tetraid[num].erase(it);
540     }
541    
542    
543 francois 287 void MAILLEUR3D_OPTIMISATION::change_niveau_optimisation(int num)
544 francois 283 {
545     niveau_optimisation=num;
546     }
547    
548 francois 287 int MAILLEUR3D_OPTIMISATION::get_niveau_optimisation(void)
549 francois 283 {
550     return niveau_optimisation;
551     }
552    
553 francois 287 void MAILLEUR3D_OPTIMISATION::active_affichage(void (*fonc)(char*))
554     {
555     affiche=fonc;
556     affichageactif=1;
557     }
558    
559    
560    
561    
562     class MG_TRIANGLE* MAILLEUR3D_OPTIMISATION::insere_triangle(class MG_VOLUME* mgvol,MG_NOEUD* noeud1,MG_NOEUD* noeud2,MG_NOEUD* noeud3,int origine)
563     {
564     MG_TRIANGLE* triangle=mg_maillage->get_mg_triangle(noeud1->get_id(),noeud3->get_id(),noeud2->get_id());
565     if (triangle!=NULL) return NULL;
566     // insertion du triangle
567     MG_SEGMENT* segment1=mg_maillage->get_mg_segment(noeud1->get_id(),noeud2->get_id());
568     MG_SEGMENT* segment2=mg_maillage->get_mg_segment(noeud1->get_id(),noeud3->get_id());
569     MG_SEGMENT* segment3=mg_maillage->get_mg_segment(noeud2->get_id(),noeud3->get_id());
570     if (segment1==NULL) segment1=cree_segment(mgvol,noeud1,noeud2,origine);
571     if (segment2==NULL) segment2=cree_segment(mgvol,noeud1,noeud3,origine);
572     if (segment3==NULL) segment3=cree_segment(mgvol,noeud2,noeud3,origine);
573     MG_TRIANGLE* tri=cree_triangle(mgvol,noeud1,noeud2,noeud3,segment1,segment2,segment3,origine);
574     return tri;
575     }
576    
577    
578    
579    
580    
581    
582     MG_TRIANGLE* MAILLEUR3D_OPTIMISATION::cree_triangle(class MG_VOLUME* mgvol,MG_NOEUD* noeud1,MG_NOEUD* noeud2,MG_NOEUD* noeud3,MG_SEGMENT* segment1,MG_SEGMENT* segment2,MG_SEGMENT* segment3,int origine)
583     {
584     M3D_TRIANGLE* tri=new M3D_TRIANGLE(mgvol,noeud1,noeud2,noeud3,segment1,segment2,segment3,origine);
585     mg_maillage->ajouter_mg_triangle(tri);
586     return tri;
587     }
588    
589    
590    
591     MG_SEGMENT* MAILLEUR3D_OPTIMISATION::cree_segment(class MG_VOLUME* mgvol,MG_NOEUD* noeud1,MG_NOEUD* noeud2,int origine)
592     {
593     MG_SEGMENT* seg=mg_maillage->ajouter_mg_segment(mgvol,noeud1,noeud2,origine);
594     return seg;
595     }