ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/mailleur/src/mailleur3d_optimisation.cpp
Revision: 1137
Committed: Tue Feb 27 18:41:29 2024 UTC (14 months, 2 weeks ago) by francois
Original Path: magic/lib/mailleur_auto/src/mailleur3d_optimisation.cpp
File size: 25461 byte(s)
Log Message:
transformation de l'optimisateur 3D pour fonctionner avec des données ne provenant pas du mailleur frontal

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