ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/mailleur/src/mailleur3d_optimisation.cpp
Revision: 791
Committed: Fri Mar 18 21:23:00 2016 UTC (9 years, 1 month ago) by francois
Original Path: magic/lib/mailleur_auto/src/mailleur3d_optimisation.cpp
File size: 24696 byte(s)
Log Message:
Transferts de la definition des origines dans le namespace MAGiC

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