ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/aster/src/mgopt_posttraitement.cpp
Revision: 805
Committed: Mon Jun 20 16:37:35 2016 UTC (8 years, 10 months ago) by francois
File size: 102368 byte(s)
Log Message:
Optimisation de la méthode de lissage McKenzie2016 suppression de la méthode inconnue nan2015 dans le posttraitement des optimisation topologique

File Contents

# User Rev Content
1 francois 222 #include "gestionversion.h"
2 francois 460 #include "mgopt_posttraitement.h"
3 francois 222 #include "fem_solution.h"
4     #include "fem_maillage.h"
5     #include "mg_maillage.h"
6     #include "mg_gestionnaire.h"
7     #include "mg_triangle_peau.h"
8 francois 335 #include "mg_geometrie_outils.h"
9 francois 412 #include "fem_maillage_outils.h"
10 francois 388 #include "tpl_fonctions_generiques.h"
11 cuillier 438 #include "ot_algorithme_geometrique.h"
12 francois 805 #include "mg_maillage_outils.h"
13     #include "mailleur_analyse.h"
14 francois 793 #include "mg_face_element.h"
15 francois 343 #include "mg_export.h"
16 francois 222 #include <stdio.h>
17 picher 230 #include <stdlib.h>
18     #include <time.h>
19 francois 222 #include <string.h>
20 francois 224 #include <math.h>
21 nana 629 #include <complex>
22 mckenzie 798 //ajout pour pouvoir utiliser les fonction venat de mailleur_analyse.cpp
23     #include "mailleur_analyse.h"
24     #include "m3d_triangle.h"
25     #include "fct_taille.h"
26     #include "mg_segment.h"
27 francois 222 //---------------------------------------------------------------------------
28    
29    
30 francois 224
31 francois 460 MGOPT_POSTTRAITEMENT::MGOPT_POSTTRAITEMENT():affichageactif(0)
32 francois 222 {
33 francois 224 for (int i=0;i<9;i++) etat[i]=0;
34 francois 457 params.ajouter("decoupage",0.,OT_PARAMETRES::DOUBLE,"0. découpage en conservant les mailles entieres 1. découpage par isodensite");
35 nana 629 params.ajouter("seuil",0.5,OT_PARAMETRES::DOUBLE,"Valeur du seuil de densité pour les 2 découpages");
36 francois 457 params.ajouter("nomdensextra","densiteextra.sol",OT_PARAMETRES::STRING,"Nom du fichier comportant la solution de la densité extrapolé au noeud");
37     params.ajouter("consimpose",1.,OT_PARAMETRES::DOUBLE,"0. Maillage non design non inclus dans le decoupage par mailles entieres 1. Maillage design inclus");
38     params.ajouter("consoptimise",1.,OT_PARAMETRES::DOUBLE,"0. Maillage optimise non inclus dans le decoupage par mailles entieres 1. Maillage optimise inclus");
39     params.ajouter("consnooptimise",0.,OT_PARAMETRES::DOUBLE,"0. Maillage non optimise non inclus dans le decoupage par mailles entieres 1. Maillage non optimise inclus");
40     params.ajouter("reactivation",1.,OT_PARAMETRES::DOUBLE,"1. Reactivation de mailles isolées sur le long des aretes 0. non reactivation");
41 nana 629 params.ajouter("chen2005_debut",0.,OT_PARAMETRES::DOUBLE,"Numero d'itération du debut d'application du lissage de chen2005 0. méthode non utilisee");
42     params.ajouter("chen2005_itermax",10.,OT_PARAMETRES::DOUBLE,"Nombre d'itérations maximales du lissage de chen2005");
43 francois 457 params.ajouter("chen2005_epsilon",0.01,OT_PARAMETRES::DOUBLE,"Critere de convergence du lissage de chen2005");
44 francois 458 params.ajouter("chen2005_sigma",0.1,OT_PARAMETRES::DOUBLE,"Écart type du filtre de lissage de chen2005");
45     params.ajouter("chen2005_filtre",1.,OT_PARAMETRES::DOUBLE,"Choix du filtre de lissage de chen2005 1. Gaussian 2.Laplacien 3.elfallahford");
46 francois 457 params.ajouter("chen2008_debut",0.,OT_PARAMETRES::DOUBLE,"Numero d'itération du debut d'application deu lissage de chen2008 0. méthode non utilisee");
47 nana 629 params.ajouter("chen2008_itermax",10.,OT_PARAMETRES::DOUBLE,"Nombre d'itérations maximales du lissage de chen2008");
48 francois 457 params.ajouter("chen2008_epsilon",0.01,OT_PARAMETRES::DOUBLE,"Critere de convergence du lissage de chen2008");
49 francois 458 params.ajouter("chen2008_sigma",0.1,OT_PARAMETRES::DOUBLE,"Écart type du filtre de lissage de chen2008");
50 francois 457 params.ajouter("chen2008_gamma",1.,OT_PARAMETRES::DOUBLE,"Vitesse d'avancement de déplacement du lissage de chen2008");
51 francois 458 params.ajouter("chen2008_filtre",1.,OT_PARAMETRES::DOUBLE,"Choix du filtre de lissage de chen2008 1. Gaussian 2.Laplacien 3.elfallahford");
52 francois 457 params.ajouter("jiao2012_debut",0.,OT_PARAMETRES::DOUBLE,"Numero d'itération du debut d'application deu lissage de jiao2012 0. méthode non utilisee");
53 nana 629 params.ajouter("jiao2012_itermax",10.,OT_PARAMETRES::DOUBLE,"Nombre d'itérations maximales du lissage de jioa2012");
54 mckenzie 804 params.ajouter("McKenzie2016_debut",0.,OT_PARAMETRES::DOUBLE,"Numero d'itération du debut d'application du lissage de McKenzie2016 0. méthode non utilisee");
55     params.ajouter("McKenzie2016_lambda",0.33,OT_PARAMETRES::DOUBLE,"Paramète lambda, la valeur doit être positive");
56     params.ajouter("McKenzie2016_nu",-0.34,OT_PARAMETRES::DOUBLE,"Paramète nu, la valeur doit être negative et respecter 0<lambda<(-nu)");
57     params.ajouter("McKenzie2016_epsilon", 0.01000, OT_PARAMETRES::DOUBLE,"Critere de convergence du lissage de chen2008");
58     params.ajouter("McKenzie2016_sigma", 0.10000, OT_PARAMETRES::DOUBLE,"Écart type du filtre de lissage de chen2008");
59     params.ajouter("McKenzie2016_gamma_", 1.0, OT_PARAMETRES::DOUBLE,"Vitesse d'avancement de déplacement du lissage de chen2008");
60     params.ajouter("McKenzie2016_filtre", 1.0, OT_PARAMETRES::DOUBLE,"Choix du filtre de lissage de chen2008 1. Gaussian 2.Laplacien 3.elfallahford");
61     params.ajouter("McKenzie2016_itertaubmax",100.,OT_PARAMETRES::DOUBLE,"Nombre d'itérations maximales de la partie taubin du lissage de McKenzie2016");
62     params.ajouter("McKenzie2016_itermax",100.,OT_PARAMETRES::DOUBLE,"Nombre d'itérations maximales de la partie chen 2008 du lissage de McKenzie2016");
63     params.ajouter("Taubin1995_debut",0.,OT_PARAMETRES::DOUBLE,"Numero d'itération du debut d'application du lissage de Taubin1995 0. méthode non utilisee");
64     params.ajouter("Taubin1995_lambda",0.33,OT_PARAMETRES::DOUBLE,"Paramète lambda, la valeur doit être positive et moins de 1");
65     params.ajouter("Taubin1995_nu",-0.34,OT_PARAMETRES::DOUBLE,"Paramète nu, la valeur doit être negative et respecter 0<lambda<(-nu)");
66     params.ajouter("Taubin1995_itermax",100.,OT_PARAMETRES::DOUBLE,"Nombre d'itérations maximales du lissage Taubin1995");
67 francois 222 }
68    
69    
70 francois 460 MGOPT_POSTTRAITEMENT::~MGOPT_POSTTRAITEMENT()
71 francois 222 {
72 francois 224 for (int i=0;i<lst_peau.size();i++)
73     delete lst_peau[i];
74 francois 222 }
75 picher 233
76 francois 460 void MGOPT_POSTTRAITEMENT::active_affichage(void (*fonc)(char*))
77 francois 232 {
78     affiche=fonc;
79     affichageactif=1;
80     }
81 francois 222
82 picher 233
83 francois 457
84 francois 461 void MGOPT_POSTTRAITEMENT::posttraite(char *fichier)
85 francois 457 {
86     affiche((char*)"");
87     affiche((char*)"***********************************************************");
88     affiche((char*)"Post-traitement d'un calcul d'optimisation de topologie");
89     affiche((char*)"***********************************************************");
90     affiche((char*)"");
91     affiche((char*)"");
92     affiche((char*)"");
93     affiche((char*)"Écriture d'un fichier de parametres par défaut");
94     params.enregistrer(fichier);
95     }
96    
97    
98    
99 francois 460 void MGOPT_POSTTRAITEMENT::conserve(int origine)
100 francois 224 {
101     etat[(origine-1000)/10]=1;
102     }
103    
104 picher 233
105 francois 460 void MGOPT_POSTTRAITEMENT::copieorigine(FEM_MAILLAGE* mai)
106 picher 231 {
107 francois 309 LISTE_FEM_ELEMENT3::iterator it_tetra;
108     for (FEM_ELEMENT3* tet=mai->get_premier_element3(it_tetra);tet!=NULL;tet=mai->get_suivant_element3(it_tetra))
109 picher 233 {
110     MG_TETRA* mgtet=(MG_TETRA*)tet->get_mg_element_maillage();
111     mgtet->change_origine(mgtet->get_origine());
112     }
113     }
114 francois 457
115    
116 francois 460 void MGOPT_POSTTRAITEMENT::gain_poids(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2)
117 picher 233 {
118     LISTE_MG_TETRA::iterator it_tetra;
119     double volume_initial = 0.;
120     double volume_final = 0.;
121     for (MG_TETRA* mgtet=mg_mai->get_premier_tetra(it_tetra);mgtet!=NULL;mgtet=mg_mai->get_suivant_tetra(it_tetra))
122     {
123     int originetet=mgtet->get_origine();
124     MG_NOEUD* noeud1 = mgtet->get_noeud1();
125     double x1 = noeud1->get_x();
126     double y1 = noeud1->get_y();
127     double z1 = noeud1->get_z();
128     MG_NOEUD* noeud2 = mgtet->get_noeud2();
129     double x2 = noeud2->get_x();
130     double y2 = noeud2->get_y();
131     double z2 = noeud2->get_z();
132     MG_NOEUD* noeud3 = mgtet->get_noeud3();
133     double x3 = noeud3->get_x();
134     double y3 = noeud3->get_y();
135     double z3 = noeud3->get_z();
136     MG_NOEUD* noeud4 = mgtet->get_noeud4();
137     double x4 = noeud4->get_x();
138     double y4 = noeud4->get_y();
139     double z4 = noeud4->get_z();
140     double volume_tet = (x2-x1)*((y3-y1)*(z4-z1)-(z3-z1)*(y4-y1))-(y2-y1)*((x3-x1)*(z4-z1)-(z3-z1)*(x4-x1)) + (z2-z1)*((x3-x1)*(y4-y1)-(y3-y1)*(x4-x1));
141     volume_tet = volume_tet/6.;
142     volume_initial = volume_initial + volume_tet;
143 francois 791 if (originetet != MAGIC::ORIGINE::MAILLEUR_AUTO)
144 picher 233 {
145     volume_final = volume_final + volume_tet;
146     }
147     }
148     }
149 francois 457
150 francois 460 void MGOPT_POSTTRAITEMENT::reactivation(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2)
151 picher 233 {
152 francois 457 cout << " Reactivation d'elements manquants sur aretes vives et faces planes" << endl;
153 picher 233 LISTE_MG_TETRA::iterator it_tetra;
154     for (MG_TETRA* mgtet=mg_mai->get_premier_tetra(it_tetra);mgtet!=NULL;mgtet=mg_mai->get_suivant_tetra(it_tetra))
155     {
156     int originetet=mgtet->get_origine();
157     int compteur = 0;
158 francois 791 if (originetet == MAGIC::ORIGINE::MAILLEUR_AUTO)
159 picher 233 {
160     MG_TRIANGLE* tri1 = mgtet->get_triangle1();
161     MG_TRIANGLE* tri2 = mgtet->get_triangle2();
162     MG_TRIANGLE* tri3 = mgtet->get_triangle3();
163     MG_TRIANGLE* tri4 = mgtet->get_triangle4();
164     int nb_tet1 = tri1->get_lien_tetra()->get_nb();
165     for (int k = 0;k<nb_tet1;k++)
166     {
167     MG_TETRA* tet1 = tri1->get_lien_tetra()->get(k);
168     int ori1 = tet1->get_origine();
169 francois 791 if ((tet1 != mgtet) && (ori1 == MAGIC::ORIGINE::MAILLEUR_AUTO)) compteur++;
170 picher 233 }
171     int nb_tet2 = tri2->get_lien_tetra()->get_nb();
172     for (int k = 0;k<nb_tet2;k++)
173     {
174     MG_TETRA* tet2 = tri2->get_lien_tetra()->get(k);
175     int ori2 = tet2->get_origine();
176 francois 791 if ((tet2 != mgtet) && (ori2 == MAGIC::ORIGINE::MAILLEUR_AUTO)) compteur++;
177 picher 233 }
178     int nb_tet3 = tri3->get_lien_tetra()->get_nb();
179     for (int k = 0;k<nb_tet3;k++)
180     {
181     MG_TETRA* tet3 = tri3->get_lien_tetra()->get(k);
182     int ori3 = tet3->get_origine();
183 francois 791 if ((tet3 != mgtet) && (ori3 == MAGIC::ORIGINE::MAILLEUR_AUTO)) compteur++;
184 picher 233 }
185     int nb_tet4 = tri4->get_lien_tetra()->get_nb();
186     for (int k = 0;k<nb_tet4;k++)
187     {
188     MG_TETRA* tet4 = tri4->get_lien_tetra()->get(k);
189     int ori4 = tet4->get_origine();
190 francois 791 if ((tet4 != mgtet) && (ori4 == MAGIC::ORIGINE::MAILLEUR_AUTO)) compteur++;
191 picher 233 }
192 francois 791 if (compteur == 0) mgtet->change_origine(MAGIC::ORIGINE::OPTIMISE);
193 picher 233 }
194     }
195     }
196    
197    
198 francois 343
199    
200 francois 460 MG_MAILLAGE* MGOPT_POSTTRAITEMENT::extract_skin_par_decoupage(FEM_SOLUTION* sol,double limit,MG_GESTIONNAIRE& gest2,std::string nom)
201 francois 343 {
202     affiche((char*)"Extraction de l'enveloppe par découpage");
203     sol->active_solution(0);
204     FEM_MAILLAGE* mai=sol->get_maillage();
205     affiche((char*)" Extrapolation de la densité aux noeuds");
206     LISTE_FEM_NOEUD::iterator it;
207     for (FEM_NOEUD* no=mai->get_premier_noeud(it);no!=NULL;no=mai->get_suivant_noeud(it))
208     {
209     double nume=0.;
210     double deno=0.;
211     int nb=no->get_lien_element3()->get_nb();
212     int passe=0;
213     for (int i=0;i<nb;i++)
214     {
215     FEM_ELEMENT3* tet=no->get_lien_element3()->get(i);
216 francois 791 if (tet->get_mg_element_maillage()->get_origine()!=MAGIC::ORIGINE::IMPOSE)
217 francois 343 {
218     double jac[9];
219     int col,ligne;
220     double volume=tet->get_jacobien(jac,jac,ligne,col,1.);
221     passe=1;
222     nume=nume+tet->get_solution()*volume;
223     deno=deno+volume;
224     }
225     }
226 nana 629 if (passe==1) no->change_solution(nume/deno); else no->change_solution(1.);
227 francois 343 }
228     if (nom!="")
229     {
230     affiche((char*)" Enregistrement de la densité aux noeuds");
231     MG_GESTIONNAIRE *gest=mai->get_mg_maillage()->get_gestionnaire();
232     std::string chemin=nom+".sol";
233 francois 383 FEM_SOLUTION* femdens=new FEM_SOLUTION(mai,1,(char*)chemin.c_str(),mai->get_nb_fem_element3(),"Extrapolation aux noeuds",MAGIC::ENTITE_SOLUTION::ENTITE_ELEMENT3_NOEUD,MAGIC::TYPE_SOLUTION::SCALAIRE);
234 francois 343 gest->ajouter_fem_solution(femdens);
235     femdens->change_legende(0,"Densite");
236     LISTE_FEM_ELEMENT3::iterator it3;
237     int i=0;
238     for (FEM_ELEMENT3* tet=mai->get_premier_element3(it3);tet!=NULL;tet=mai->get_suivant_element3(it3))
239     {
240     MG_TETRA* tet2=(MG_TETRA*)tet->get_mg_element_maillage();
241 francois 791 if (tet2->get_origine()==MAGIC::ORIGINE::IMPOSE)
242 francois 343 {
243 francois 375 femdens->ecrire(1.,i,0,0);
244     femdens->ecrire(1.,i,0,1);
245     femdens->ecrire(1.,i,0,2);
246     femdens->ecrire(1.,i,0,3);
247 francois 343 }
248     else
249     {
250 francois 375 femdens->ecrire(tet->get_fem_noeud(0)->get_solution(),i,0,0);
251     femdens->ecrire(tet->get_fem_noeud(1)->get_solution(),i,0,1);
252     femdens->ecrire(tet->get_fem_noeud(2)->get_solution(),i,0,2);
253     femdens->ecrire(tet->get_fem_noeud(3)->get_solution(),i,0,3);
254 francois 343 }
255     i++;
256     }
257     MG_EXPORT exp;
258     exp.gmsh(mai,nom);
259     gest->supprimer_fem_solution(gest->get_nb_fem_solution()-1);
260     }
261 francois 793 gest2.vide();
262     MG_GEOMETRIE* geo=new MG_GEOMETRIE((char*)"VIRTUEL",(char*)"VIRTUEL");
263     geo->change_valeur_unite(mai->get_mg_geometrie()->get_valeur_unite());
264     gest2.ajouter_mg_geometrie(geo);
265     MG_FACE_ELEMENT* face=new MG_FACE_ELEMENT();
266     geo->ajouter_mg_face(face);
267     MG_MAILLAGE* mgmai=new MG_MAILLAGE(geo);
268 francois 343 gest2.ajouter_mg_maillage(mgmai);
269    
270     MG_MAILLAGE* mgfem=mai->get_mg_maillage();
271     LISTE_MG_TRIANGLE::iterator itmg;
272     for (MG_TRIANGLE* tri=mgfem->get_premier_triangle(itmg);tri!=NULL;tri=mgfem->get_suivant_triangle(itmg))
273     tri->change_nouveau_numero(0);
274     affiche((char*)" Decoupage des tetra optimises");
275     LISTE_FEM_ELEMENT3::iterator it3;
276     for (FEM_ELEMENT3* tet=mai->get_premier_element3(it3);tet!=NULL;tet=mai->get_suivant_element3(it3))
277     {
278     MG_TETRA* tet2=(MG_TETRA*)tet->get_mg_element_maillage();
279 francois 791 if (tet2->get_origine()==MAGIC::ORIGINE::IMPOSE)
280 francois 343 {
281 francois 791 tet2->get_triangle1()->change_origine(MAGIC::ORIGINE::IMPOSE);
282     tet2->get_triangle2()->change_origine(MAGIC::ORIGINE::IMPOSE);
283     tet2->get_triangle3()->change_origine(MAGIC::ORIGINE::IMPOSE);
284     tet2->get_triangle4()->change_origine(MAGIC::ORIGINE::IMPOSE);
285 francois 343 tet2->get_noeud1()->change_solution(tet->get_fem_noeud(0)->get_solution());
286     tet2->get_noeud2()->change_solution(tet->get_fem_noeud(1)->get_solution());
287     tet2->get_noeud3()->change_solution(tet->get_fem_noeud(2)->get_solution());
288     tet2->get_noeud4()->change_solution(tet->get_fem_noeud(3)->get_solution());
289     tet2->get_noeud1()->change_nouveau_numero(tet->get_fem_noeud(0)->get_id());
290     tet2->get_noeud2()->change_nouveau_numero(tet->get_fem_noeud(1)->get_id());
291     tet2->get_noeud3()->change_nouveau_numero(tet->get_fem_noeud(2)->get_id());
292     tet2->get_noeud4()->change_nouveau_numero(tet->get_fem_noeud(3)->get_id());
293     if (tet2->get_triangle1()->get_nouveau_numero()==0)
294     tet2->get_triangle1()->change_nouveau_numero(tet2->get_noeud4()->get_id());
295     else
296     tet2->get_triangle1()->change_nouveau_numero(-1);
297     if (tet2->get_triangle2()->get_nouveau_numero()==0)
298     tet2->get_triangle2()->change_nouveau_numero(tet2->get_noeud3()->get_id());
299     else
300     tet2->get_triangle2()->change_nouveau_numero(-1);
301     if (tet2->get_triangle3()->get_nouveau_numero()==0)
302     tet2->get_triangle3()->change_nouveau_numero(tet2->get_noeud1()->get_id());
303     else
304     tet2->get_triangle3()->change_nouveau_numero(-1);
305     if (tet2->get_triangle4()->get_nouveau_numero()==0)
306     tet2->get_triangle4()->change_nouveau_numero(tet2->get_noeud2()->get_id());
307     else
308     tet2->get_triangle4()->change_nouveau_numero(-1);
309     }
310     }
311    
312     TPL_LISTE_ENTITE<MG_TRIANGLE*> tri_impose_interne;
313     for (MG_TRIANGLE* tri=mgfem->get_premier_triangle(itmg);tri!=NULL;tri=mgfem->get_suivant_triangle(itmg))
314     {
315 francois 791 if (tri->get_origine()==MAGIC::ORIGINE::IMPOSE)
316 francois 343 if (tri->get_lien_topologie()->get_dimension()==3)
317     if (tri->get_nouveau_numero()>0)
318     tri_impose_interne.ajouter(tri);
319     }
320     for (FEM_ELEMENT3* tet=mai->get_premier_element3(it3);tet!=NULL;tet=mai->get_suivant_element3(it3))
321     {
322 francois 791 if (tet->get_mg_element_maillage()->get_origine()!=MAGIC::ORIGINE::IMPOSE)
323 francois 343 {
324     FEM_NOEUD* no1=tet->get_fem_noeud(0);
325     FEM_NOEUD* no2=tet->get_fem_noeud(1);
326     FEM_NOEUD* no3=tet->get_fem_noeud(2);
327     FEM_NOEUD* no4=tet->get_fem_noeud(3);
328     std::vector<MG_NOEUD*> tab;
329 francois 792 interpole_segment(mai,no1,no2,&tab,limit,mgmai);
330     interpole_segment(mai,no1,no3,&tab,limit,mgmai);
331     interpole_segment(mai,no1,no4,&tab,limit,mgmai);
332     interpole_segment(mai,no2,no3,&tab,limit,mgmai);
333     interpole_segment(mai,no2,no4,&tab,limit,mgmai);
334     interpole_segment(mai,no3,no4,&tab,limit,mgmai);
335 francois 343 int nb=tab.size();
336     FEM_NOEUD* noext;
337     if (nb>0)
338     {
339     if (no1->get_solution()<limit) noext=no1;
340     if (no2->get_solution()<limit) noext=no2;
341     if (no3->get_solution()<limit) noext=no3;
342     if (no4->get_solution()<limit) noext=no4;
343     }
344     if (nb==3)
345     {
346 francois 791 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[1],tab[2],mgmai,MAGIC::ORIGINE::TRIANGULATION);
347 francois 343 oriente_tri(tri,noext->get_coord());
348     }
349     if (nb==4)
350     {
351     if (test_du_point_milieu(tab[0],tab[1],tet)==1)
352     {
353 francois 791 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[1],tab[2],mgmai,MAGIC::ORIGINE::TRIANGULATION);
354     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[0],tab[1],tab[3],mgmai,MAGIC::ORIGINE::TRIANGULATION);
355 francois 343 oriente_tri(tri,noext->get_coord());
356     oriente_tri(tri2,noext->get_coord());
357     }
358     else if (test_du_point_milieu(tab[0],tab[2],tet)==1)
359     {
360 francois 791 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[2],tab[1],mgmai,MAGIC::ORIGINE::TRIANGULATION);
361     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[0],tab[2],tab[3],mgmai,MAGIC::ORIGINE::TRIANGULATION);
362 francois 343 oriente_tri(tri,noext->get_coord());
363     oriente_tri(tri2,noext->get_coord());}
364     else if (test_du_point_milieu(tab[0],tab[3],tet)==1)
365     {
366 francois 791 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[3],tab[1],mgmai,MAGIC::ORIGINE::TRIANGULATION);
367     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[0],tab[3],tab[2],mgmai,MAGIC::ORIGINE::TRIANGULATION);
368 francois 343 oriente_tri(tri,noext->get_coord());
369     oriente_tri(tri2,noext->get_coord());}
370     else if (test_du_point_milieu(tab[1],tab[2],tet)==1)
371     {
372 francois 791 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[1],tab[2],tab[0],mgmai,MAGIC::ORIGINE::TRIANGULATION);
373     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[1],tab[2],tab[3],mgmai,MAGIC::ORIGINE::TRIANGULATION);
374 francois 343 oriente_tri(tri,noext->get_coord());
375     oriente_tri(tri2,noext->get_coord());
376     }
377     else if (test_du_point_milieu(tab[1],tab[3],tet)==1)
378     {
379 francois 791 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[1],tab[3],tab[0],mgmai,MAGIC::ORIGINE::TRIANGULATION);
380     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[1],tab[3],tab[2],mgmai,MAGIC::ORIGINE::TRIANGULATION);
381 francois 343 oriente_tri(tri,noext->get_coord());
382     oriente_tri(tri2,noext->get_coord());}
383     else
384     {
385 francois 791 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[2],tab[3],tab[0],mgmai,MAGIC::ORIGINE::TRIANGULATION);
386     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[2],tab[3],tab[1],mgmai,MAGIC::ORIGINE::TRIANGULATION);
387 francois 343 oriente_tri(tri,noext->get_coord());
388     oriente_tri(tri2,noext->get_coord());
389     }
390    
391     }
392     }
393     }
394     affiche((char*)" Decoupage des triangles non design interne au volume");
395     for (int i=0;i<tri_impose_interne.get_nb();i++)
396     {
397     MG_TRIANGLE* tri=tri_impose_interne.get(i);
398     MG_NOEUD* no1=tri->get_noeud1();
399     MG_NOEUD* no2=tri->get_noeud2();
400     MG_NOEUD* no3=tri->get_noeud3();
401     std::vector<MG_NOEUD*> tab;
402     int num1=-1;
403     int num2=-1;
404     int num3=-1;
405     if (no1->get_solution()<limit)
406     {
407     MG_NOEUD* no=get_noeud_peau(mai->get_fem_noeudid(no1->get_nouveau_numero()),mgmai);
408     tab.push_back(no);
409     num1=1;
410     }
411     if (no2->get_solution()<limit)
412     {
413     MG_NOEUD* no=get_noeud_peau(mai->get_fem_noeudid(no2->get_nouveau_numero()),mgmai);
414     tab.push_back(no);
415     num2=1;
416     }
417     if (no3->get_solution()<limit)
418     {
419     MG_NOEUD* no=get_noeud_peau(mai->get_fem_noeudid(no3->get_nouveau_numero()),mgmai);
420     tab.push_back(no);
421     num3=1;
422     }
423 francois 792 if (num1*num2<0) interpole_segment(mai,mai->get_fem_noeudid(no1->get_nouveau_numero()),mai->get_fem_noeudid(no2->get_nouveau_numero()),&tab,limit,mgmai);
424     if (num1*num3<0) interpole_segment(mai,mai->get_fem_noeudid(no1->get_nouveau_numero()),mai->get_fem_noeudid(no3->get_nouveau_numero()),&tab,limit,mgmai);
425     if (num2*num3<0) interpole_segment(mai,mai->get_fem_noeudid(no2->get_nouveau_numero()),mai->get_fem_noeudid(no3->get_nouveau_numero()),&tab,limit,mgmai);
426 francois 343 MG_NOEUD* noint=mgfem->get_mg_noeudid(tri->get_nouveau_numero());
427     int nb=tab.size();
428     if (nb==3)
429     {
430 francois 791 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[1],tab[2],mgmai,MAGIC::ORIGINE::IMPOSE);
431 francois 343 oriente_tri(tri,noint->get_coord());
432     tri->inverse_sens();
433     }
434     if (nb==4)
435     {
436 francois 791 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[1],tab[2],mgmai,MAGIC::ORIGINE::IMPOSE);
437     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[1],tab[2],tab[3],mgmai,MAGIC::ORIGINE::IMPOSE);
438 francois 343 oriente_tri(tri,noint->get_coord());
439     tri->inverse_sens();
440     oriente_tri(tri2,noint->get_coord());
441     tri2->inverse_sens();
442     }
443     }
444 francois 793 affiche((char*)" Decoupage des triangles sur la frontiere du volume");
445 francois 343 LISTE_FEM_ELEMENT2::iterator it2;
446     for (FEM_ELEMENT2* tri=mai->get_premier_element2(it2);tri!=NULL;tri=mai->get_suivant_element2(it2))
447     {
448     std::vector<MG_NOEUD*> tab;
449     FEM_NOEUD *no1=tri->get_fem_noeud(0);
450     FEM_NOEUD *no2=tri->get_fem_noeud(1);
451     FEM_NOEUD *no3=tri->get_fem_noeud(2);
452     int ori=((MG_FACE*)tri->get_lien_topologie())->get_mg_coface(0)->get_orientation();
453     OT_VECTEUR_3D n1n2(no1->get_coord(),no2->get_coord());
454     OT_VECTEUR_3D n1n3(no1->get_coord(),no3->get_coord());
455     OT_VECTEUR_3D nor=n1n3&n1n2;
456     double xyzext[3];
457     xyzext[0]=no1->get_x()+nor.get_x()*ori;
458     xyzext[1]=no1->get_y()+nor.get_y()*ori;
459     xyzext[2]=no1->get_z()+nor.get_z()*ori;
460 francois 791 if (tri->get_mg_element_maillage()->get_origine()==MAGIC::ORIGINE::IMPOSE)
461 francois 343 {
462     MG_NOEUD *mgno1=get_noeud_peau(no1,mgmai);
463     MG_NOEUD *mgno2=get_noeud_peau(no2,mgmai);
464     MG_NOEUD *mgno3=get_noeud_peau(no3,mgmai);
465 francois 792 int num1=interpole_segment(mai,no1,no2,&tab,limit,mgmai,0);
466     int num2=interpole_segment(mai,no1,no3,&tab,limit,mgmai,0);
467     int num3=interpole_segment(mai,no2,no3,&tab,limit,mgmai,0);
468 francois 343 int nb=tab.size();
469     if (nb==0)
470     {
471 francois 793 MG_TRIANGLE_PEAU* tri=insere_triangle(face,mgno1,mgno2,mgno3,mgmai,MAGIC::ORIGINE::IMPOSE);
472 francois 343 oriente_tri(tri,xyzext);
473     }
474     if (nb==1)
475     {
476     if (num1==1)
477     {
478 francois 793 MG_TRIANGLE_PEAU* tri=insere_triangle(face,mgno1,mgno3,tab[0],mgmai,MAGIC::ORIGINE::IMPOSE);
479     MG_TRIANGLE_PEAU* tri2=insere_triangle(face,mgno2,mgno3,tab[0],mgmai,MAGIC::ORIGINE::IMPOSE);
480 francois 343 oriente_tri(tri,xyzext);
481     oriente_tri(tri2,xyzext);
482     }
483     if (num2==1)
484     {
485 francois 793 MG_TRIANGLE_PEAU* tri=insere_triangle(face,mgno1,mgno2,tab[0],mgmai,MAGIC::ORIGINE::IMPOSE);
486     MG_TRIANGLE_PEAU* tri2=insere_triangle(face,mgno2,mgno3,tab[0],mgmai,MAGIC::ORIGINE::IMPOSE);
487 francois 343 oriente_tri(tri,xyzext);
488     oriente_tri(tri2,xyzext);
489     }
490     if (num3==1)
491     {
492 francois 793 MG_TRIANGLE_PEAU* tri=insere_triangle(face,mgno1,mgno2,tab[0],mgmai,MAGIC::ORIGINE::IMPOSE);
493     MG_TRIANGLE_PEAU* tri2=insere_triangle(face,mgno1,mgno3,tab[0],mgmai,MAGIC::ORIGINE::IMPOSE);
494 francois 343 oriente_tri(tri,xyzext);
495     oriente_tri(tri2,xyzext);
496     }
497     }
498     if (nb==2)
499     {
500     if (num1==0)
501     {
502 francois 793 MG_TRIANGLE_PEAU* tri=insere_triangle(face,mgno1,mgno2,tab[0],mgmai,MAGIC::ORIGINE::IMPOSE);
503     MG_TRIANGLE_PEAU* tri2=insere_triangle(face,mgno2,tab[0],tab[1],mgmai,MAGIC::ORIGINE::IMPOSE);
504     MG_TRIANGLE_PEAU* tri3=insere_triangle(face,mgno3,tab[0],tab[1],mgmai,MAGIC::ORIGINE::IMPOSE);
505 francois 343 oriente_tri(tri,xyzext);
506     oriente_tri(tri2,xyzext);
507     oriente_tri(tri3,xyzext);
508     }
509     if (num2==0)
510     {
511 francois 793 MG_TRIANGLE_PEAU* tri=insere_triangle(face,mgno1,mgno3,tab[0],mgmai,MAGIC::ORIGINE::IMPOSE);
512     MG_TRIANGLE_PEAU* tri2=insere_triangle(face,mgno3,tab[0],tab[1],mgmai,MAGIC::ORIGINE::IMPOSE);
513     MG_TRIANGLE_PEAU* tri3=insere_triangle(face,mgno2,tab[0],tab[1],mgmai,MAGIC::ORIGINE::IMPOSE);
514 francois 343 oriente_tri(tri,xyzext);
515     oriente_tri(tri2,xyzext);
516     oriente_tri(tri3,xyzext);
517     }
518     if (num2==0)
519     {
520 francois 793 MG_TRIANGLE_PEAU* tri=insere_triangle(face,mgno2,mgno3,tab[0],mgmai,MAGIC::ORIGINE::IMPOSE);
521     MG_TRIANGLE_PEAU* tri2=insere_triangle(face,mgno3,tab[0],tab[1],mgmai,MAGIC::ORIGINE::IMPOSE);
522     MG_TRIANGLE_PEAU* tri3=insere_triangle(face,mgno1,tab[0],tab[1],mgmai,MAGIC::ORIGINE::IMPOSE);
523 francois 343 oriente_tri(tri,xyzext);
524     oriente_tri(tri2,xyzext);
525     oriente_tri(tri3,xyzext);
526     }
527     }
528     }
529     else if ((no1->get_solution()>=limit) && (no2->get_solution()>=limit) && (no3->get_solution()>=limit))
530     {
531     MG_NOEUD *mgno1=get_noeud_peau(no1,mgmai);
532     MG_NOEUD *mgno2=get_noeud_peau(no2,mgmai);
533     MG_NOEUD *mgno3=get_noeud_peau(no3,mgmai);
534 francois 793 MG_TRIANGLE_PEAU* tri=insere_triangle(face,mgno1,mgno2,mgno3,mgmai,MAGIC::ORIGINE::TRIANGULATION);
535 francois 343 oriente_tri(tri,xyzext);
536     }
537     else if (!((no1->get_solution()<limit) && (no2->get_solution()<limit) && (no3->get_solution()<limit)))
538     {
539     std::vector<MG_NOEUD*> tab;
540     int num1=-1;
541     int num2=-1;
542     int num3=-1;
543     if (no1->get_solution()>=limit)
544     {
545     MG_NOEUD* no=get_noeud_peau(no1,mgmai);
546     tab.push_back(no);
547     num1=1;
548     }
549     if (no2->get_solution()>=limit)
550     {
551     MG_NOEUD* no=get_noeud_peau(no2,mgmai);
552     tab.push_back(no);
553     num2=1;
554     }
555     if (no3->get_solution()>=limit)
556     {
557     MG_NOEUD* no=get_noeud_peau(no3,mgmai);
558     tab.push_back(no);
559     num3=1;
560     }
561 francois 792 if (num1*num2<0) interpole_segment(mai,no1,no2,&tab,limit,mgmai);
562     if (num1*num3<0) interpole_segment(mai,no1,no3,&tab,limit,mgmai);
563     if (num2*num3<0) interpole_segment(mai,no2,no3,&tab,limit,mgmai);
564 francois 343 int nb=tab.size();
565     if (nb==3)
566     {
567 francois 793 MG_TRIANGLE_PEAU* tri=insere_triangle(face,tab[0],tab[1],tab[2],mgmai,MAGIC::ORIGINE::TRIANGULATION);
568 francois 343 oriente_tri(tri,xyzext);
569     }
570     if (nb==4)
571     {
572 francois 793 MG_TRIANGLE_PEAU* tri=insere_triangle(face,tab[0],tab[1],tab[2],mgmai,MAGIC::ORIGINE::TRIANGULATION);
573     MG_TRIANGLE_PEAU* tri2=insere_triangle(face,tab[1],tab[2],tab[3],mgmai,MAGIC::ORIGINE::TRIANGULATION);
574 francois 343 oriente_tri(tri,xyzext);
575     oriente_tri(tri2,xyzext);
576     }
577     }
578     }
579     LISTE_MG_TRIANGLE::iterator it_tri;
580     for (MG_TRIANGLE* mgtri=mgmai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mgmai->get_suivant_triangle(it_tri))
581     {
582     MG_TRIANGLE_PEAU* tripeau=(MG_TRIANGLE_PEAU*)mgtri;
583     MG_TRIANGLE_PEAU* voisin1=recherche_voisin(tripeau->get_noeud1(),tripeau->get_noeud2(),tripeau);
584     MG_TRIANGLE_PEAU* voisin2=recherche_voisin(tripeau->get_noeud2(),tripeau->get_noeud3(),tripeau);
585     MG_TRIANGLE_PEAU* voisin3=recherche_voisin(tripeau->get_noeud3(),tripeau->get_noeud1(),tripeau);
586     tripeau->change_voisin1(voisin1);
587     tripeau->change_voisin2(voisin2);
588     tripeau->change_voisin3(voisin3);
589     tripeau->change_nouveau_numero(0);
590     }
591     int fin;
592     do
593     {
594     fin=1;
595     for (MG_TRIANGLE* mgtri=mgmai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mgmai->get_suivant_triangle(it_tri))
596     {
597     MG_TRIANGLE_PEAU *tripeau=(MG_TRIANGLE_PEAU*)mgtri;
598     if (tripeau->get_nouveau_numero()==0)
599     {
600     fin=0;
601     std::vector<MG_TRIANGLE_PEAU*> *peau=new std::vector<MG_TRIANGLE_PEAU*>;
602     lst_peau.push_back(peau);
603     tripeau->change_nouveau_numero(1);
604     peau->push_back(tripeau);
605     determine_peau(peau);
606     }
607     }
608     }
609     while (fin==0);
610 francois 457 return mgmai;
611     }
612 nana 629
613    
614 francois 460 void MGOPT_POSTTRAITEMENT::suppression_peaux_isoles(MG_MAILLAGE* mgmai)
615 francois 457 {
616     affiche((char*)"Suppression des peaux isolées");
617 francois 343
618     char message[500];
619     for (int cas=0;cas<2;cas++)
620     {
621 francois 457 if (cas==0) affiche((char*)" Analyse initiale des peaux");
622     if (cas==1) affiche((char*)" Analyse finale des peaux");
623     int nbisole=0;
624 francois 343 for (int i=0;i<lst_peau.size();i++)
625     {
626     int isole=1;
627     for (int j=0;j<lst_peau[i]->size();j++)
628 francois 791 if ((*lst_peau[i])[j]->get_origine()==MAGIC::ORIGINE::IMPOSE) {isole=0;break;}
629 francois 343 if (isole==1)
630     {
631 francois 457 nbisole++;
632 francois 343 for (int j=0;j<lst_peau[i]->size();j++)
633     {
634     mgmai->supprimer_mg_triangleid((*lst_peau[i])[j]->get_id());
635     }
636     lst_peau[i]->clear();
637     }
638     }
639 francois 457 sprintf(message," %d peaux, %d non isoles, %d isoles",(int)lst_peau.size(),(int)lst_peau.size()-nbisole,nbisole);
640     affiche(message);
641 francois 343 for (std::vector<std::vector<MG_TRIANGLE_PEAU*> *>::iterator j=lst_peau.end()-1;j>lst_peau.begin();j--)
642     if ((*j)->size()==0)
643     lst_peau.erase(j);
644     }
645 francois 457 LISTE_MG_TRIANGLE::iterator itmg;
646 francois 343 for (MG_TRIANGLE* tri=mgmai->get_premier_triangle(itmg);tri!=NULL;tri=mgmai->get_suivant_triangle(itmg))
647     {
648 francois 791 if (tri->get_origine()==MAGIC::ORIGINE::IMPOSE)
649 francois 343 {
650 francois 791 tri->get_noeud1()->change_origine(MAGIC::ORIGINE::IMPOSE);
651     tri->get_noeud2()->change_origine(MAGIC::ORIGINE::IMPOSE);
652     tri->get_noeud3()->change_origine(MAGIC::ORIGINE::IMPOSE);
653 francois 343 }
654     }
655 cuillier 438
656 francois 343 }
657    
658 nana 629
659 francois 460 void MGOPT_POSTTRAITEMENT::oriente_tri(MG_TRIANGLE_PEAU* tri,double *xyz)
660 francois 343 {
661     MG_NOEUD* no1=tri->get_noeud1();
662     MG_NOEUD* no2=tri->get_noeud2();
663     MG_NOEUD* no3=tri->get_noeud3();
664     OT_VECTEUR_3D n1n2(no1->get_coord(),no2->get_coord());
665     OT_VECTEUR_3D n1n3(no1->get_coord(),no3->get_coord());
666 francois 805 OT_VECTEUR_3D normal=n1n3&n1n2;
667 francois 343 OT_VECTEUR_3D dir(no1->get_coord(),xyz);
668     dir.norme();
669     normal.norme();
670     double ps=normal*dir;
671     if (ps<0) tri->inverse_sens();
672     }
673    
674    
675    
676 francois 460 MG_NOEUD* MGOPT_POSTTRAITEMENT::get_noeud_peau(FEM_NOEUD* no,MG_MAILLAGE* mai)
677 francois 343 {
678     static std::map<std::string,MG_NOEUD*> correspond;
679     unsigned long id=no->get_id();
680     char message[255];
681     sprintf(message,"_%lu_",id);
682     std::string key=message;
683     MG_NOEUD* mgno=correspond[key];
684     if (mgno==NULL)
685     {
686 francois 792 int origine=MAGIC::ORIGINE::TRIANGULATION;
687     if (((MG_NOEUD*)no->get_mg_element_maillage())->get_lien_topologie()->get_dimension()==1) origine=MAGIC::ORIGINE::TRIANGULATION_ARETE;
688     mgno=new MG_NOEUD(NULL,no->get_x(),no->get_y(),no->get_z(),origine);
689 francois 343 mai->ajouter_mg_noeud(mgno);
690     correspond[key]=mgno;
691     }
692     return mgno;
693     }
694    
695    
696 francois 460 int MGOPT_POSTTRAITEMENT::test_du_point_milieu(MG_NOEUD* no1,MG_NOEUD* no2,FEM_ELEMENT3* tet)
697 francois 343 {
698     double *xyz1=no1->get_coord();
699     double *xyz2=no2->get_coord();
700     double xyz[3];
701     xyz[0]=0.5*(xyz1[0]+xyz2[0]);
702     xyz[1]=0.5*(xyz1[1]+xyz2[1]);
703     xyz[2]=0.5*(xyz1[2]+xyz2[2]);
704 francois 412 FEM_MAILLAGE_OUTILS ot;
705 francois 388 if (((ot.estdansletetra(tet,xyz[0],xyz[1],xyz[2])>>1)&1)==1) return 1;
706     //if (((MG_MAILLAGE_OUTILS::estdansletetra(tet,xyz[0],xyz[1],xyz[2])>>1)&1)==1) return 1;
707 francois 343 return 0;
708     }
709    
710    
711    
712 francois 792 int MGOPT_POSTTRAITEMENT::interpole_segment(FEM_MAILLAGE* fem,FEM_NOEUD* no1,FEM_NOEUD* no2,std::vector<MG_NOEUD*> *tab,double limit,MG_MAILLAGE* mai,int creation)
713 francois 343 {
714     static std::map<std::string,MG_NOEUD*> correspond;
715     unsigned long id1=no1->get_id();
716     unsigned long id2=no2->get_id();
717     char message[255];
718     sprintf(message,"_%lu_%lu_",id1,id2);
719     std::string key1=message;
720     sprintf(message,"_%lu_%lu_",id2,id1);
721     std::string key2=message;
722     double sol1=no1->get_solution();
723     double sol2=no2->get_solution();
724 francois 792 MG_NOEUD* n1=(MG_NOEUD*)no1->get_mg_element_maillage();
725     MG_NOEUD* n2=(MG_NOEUD*)no2->get_mg_element_maillage();
726     MG_SEGMENT *seg=fem->get_mg_maillage()->get_mg_segment(n1->get_id(),n2->get_id());
727     int origine=MAGIC::ORIGINE::TRIANGULATION;
728     if (seg->get_lien_topologie()->get_dimension()==2) origine=MAGIC::ORIGINE::TRIANGULATION_ARETE;
729     if (seg->get_lien_topologie()->get_dimension()==1) origine=MAGIC::ORIGINE::TRIANGULATION_ARETE;
730    
731 francois 345 if (fabs(sol1-limit)<0.0000001)
732     {
733     sprintf(message,"%lu",id1);
734     std::string key=message;
735     MG_NOEUD* no=correspond[key];
736     if (no==NULL)
737     {
738     double *xyz1=no1->get_coord();
739 francois 792 no=new MG_NOEUD(NULL,xyz1[0],xyz1[1],xyz1[2],origine);
740 francois 345 mai->ajouter_mg_noeud(no);
741     correspond[key]=no;
742     }
743     int present=0;
744     for (int i=0;i<tab->size();i++)
745     if ((*tab)[i]==no) present=1;
746     if (present==0)
747     {
748     tab->push_back(no);
749     return 1;
750     }
751     else return 0;
752     }
753     if (fabs(sol2-limit)<0.0000001)
754     {
755     sprintf(message,"%lu",id2);
756     std::string key=message;
757     MG_NOEUD* no=correspond[key];
758     if (no==NULL)
759     {
760     double *xyz2=no2->get_coord();
761 francois 792 no=new MG_NOEUD(NULL,xyz2[0],xyz2[1],xyz2[2],origine);
762 francois 345 mai->ajouter_mg_noeud(no);
763     correspond[key]=no;
764     }
765     int present=0;
766     for (int i=0;i<tab->size();i++)
767     if ((*tab)[i]==no) present=1;
768     if (present==0)
769     {
770     tab->push_back(no);
771     return 1;
772     }
773     else return 0;
774    
775     }
776    
777     if (((sol1<limit) && (sol2>limit))||((sol1>limit) && (sol2<limit)))
778 francois 343 {
779     MG_NOEUD* no=correspond[key1];
780     if (no==NULL) no=correspond[key2];
781     if ((no==NULL) && (creation==1))
782     {
783     double t=(limit-sol1)/(sol2-sol1);
784     double xyz[3];
785     double *xyz1=no1->get_coord();
786     double *xyz2=no2->get_coord();
787     xyz[0]=xyz1[0]+t*(xyz2[0]-xyz1[0]);
788     xyz[1]=xyz1[1]+t*(xyz2[1]-xyz1[1]);
789     xyz[2]=xyz1[2]+t*(xyz2[2]-xyz1[2]);
790 francois 792 no=new MG_NOEUD(NULL,xyz[0],xyz[1],xyz[2],origine);
791 francois 343 mai->ajouter_mg_noeud(no);
792     correspond[key1]=no;
793     }
794     if (no!=NULL)
795     {
796     tab->push_back(no);
797     return 1;
798     }
799     }
800     return 0;
801     }
802    
803 francois 460 void MGOPT_POSTTRAITEMENT::lire_params(char *fichier)
804 francois 457 {
805     params.lire(fichier);
806     }
807 francois 343
808 francois 461 void MGOPT_POSTTRAITEMENT::posttraite(FEM_SOLUTION* sol, MG_GESTIONNAIRE& gest2,char *nomparam)
809 picher 233 {
810 francois 457 if (nomparam!=NULL) lire_params(nomparam);
811 francois 272 affiche((char*)"Extraction du maillage de surface");
812 francois 457 FEM_MAILLAGE* fem=sol->get_maillage();
813     int decoup=params.get_valeur("decoupage");
814     MG_MAILLAGE* mgmai;
815     if (decoup==0)
816     {
817     affiche((char*)" Découpage par mailles 3D entieres");
818     adapte_seuil(fem,sol);
819     mgmai=extract_skin_maille_entiere(fem,gest2);
820     }
821     if (decoup==1)
822     {
823     affiche((char*)" Découpage par isodensité");
824     double seuil=params.get_valeur("seuil");
825     std::string nomfich=params.get_nom("nomdensextra");
826     mgmai=extract_skin_par_decoupage(sol,seuil,gest2,nomfich.c_str());
827     }
828     suppression_peaux_isoles(mgmai);
829     affiche((char*)"Procedure de lissage");
830     int chen2005_debut=params.get_valeur("chen2005_debut");
831     int chen2008_debut=params.get_valeur("chen2008_debut");
832     int jiao2012_debut=params.get_valeur("jiao2012_debut");
833 mckenzie 804 int McKenzie2016_debut=params.get_valeur("McKenzie2016_debut");
834     int Taubin1995_debut=params.get_valeur("Taubin1995_debut");
835 francois 457 int chen2005fait=0;
836     if (chen2005_debut==0) chen2005fait=1;
837     int chen2008fait=0;
838     if (chen2008_debut==0) chen2008fait=1;
839     int jiao2012fait=0;
840     if (jiao2012_debut==0) jiao2012fait=1;
841 mckenzie 804 int McKenzie2016fait=0;
842     if (McKenzie2016_debut==0) McKenzie2016fait=1;
843     int Taubin1995fait=0;
844     if (Taubin1995_debut==0) Taubin1995fait=1;
845 mckenzie 798
846 francois 457 int fin=0;
847     int iteration=1;
848     do
849     {
850     if ((iteration>=chen2005_debut) && (chen2005fait==0))
851     {
852     char message[300];
853     sprintf(message, " Iteration %d : lissage de Chen 2005",iteration);
854     affiche(message);
855     double epsilon=params.get_valeur("chen2005_epsilon");
856     double sigma=params.get_valeur("chen2005_sigma");
857     int iter_max=params.get_valeur("chen2005_itermax");
858     int nbiter=lissage_chen2005(mgmai,gest2,epsilon,sigma,iter_max);
859     if (nbiter==iter_max) sprintf(message," Arrêt de la procédure de lissage de Chen2005 après %d itérations",nbiter);
860     else sprintf(message," Convergence de la procédure de lissage de Chen2005 après %d itérations",nbiter);
861     affiche(message);
862     chen2005fait=1;
863     iteration=iteration+nbiter;
864     }
865     else if ((iteration>=chen2008_debut) && (chen2008fait==0))
866     {
867     char message[300];
868     sprintf(message, " Iteration %d : lissage de Chen 2008",iteration);
869     affiche(message);
870     double epsilon=params.get_valeur("chen2008_epsilon");
871     double sigma=params.get_valeur("chen2008_sigma");
872     double gamma=params.get_valeur("chen2008_gamma");
873     int iter_max=params.get_valeur("chen2008_itermax");
874     int nbiter=lissage_chen2008(mgmai,gest2,sigma,gamma,epsilon,iter_max);
875     if (nbiter==iter_max) sprintf(message," Arrêt de la procédure de lissage de Chen2008 après %d itérations",nbiter);
876     else sprintf(message," Convergence de la procédure de lissage de Chen2008 après %d itérations",nbiter);
877     affiche(message);
878     chen2008fait=1;
879     iteration=iteration+nbiter;
880     }
881     else if ((iteration>=jiao2012_debut) && (jiao2012fait==0))
882     {
883     char message[300];
884     sprintf(message, " Iteration %d : lissage de Jiao 2012",iteration);
885     affiche(message);
886     int iter_max=params.get_valeur("jiao2012_itermax");
887     int nbiter=lissage_jiao2012(mgmai,gest2,iter_max);
888     if (nbiter==iter_max) sprintf(message," Arrêt de la procédure de lissage de Jiao2012 après %d itérations",nbiter);
889     else sprintf(message," Convergence de la procédure de lissage de Jiao2012 après %d itérations",nbiter);
890     affiche(message);
891     jiao2012fait=1;
892     iteration=iteration+nbiter;
893     }
894 francois 805 else if ((iteration>=McKenzie2016_debut) && (McKenzie2016fait==0))
895 nana 629 {
896     char message[300];
897 mckenzie 804 sprintf(message, "Lissage de McKenzie2016");
898 mckenzie 798 affiche(message);
899 mckenzie 804 double lambda=params.get_valeur("McKenzie2016_lambda");
900     double nu=params.get_valeur("McKenzie2016_nu");
901     double epsilon=params.get_valeur("McKenzie2016_epsilon");
902     double sigma=params.get_valeur("McKenzie2016_sigma");
903     double gamma_ =params.get_valeur("McKenzie2016_sigma");
904     int filtre=params.get_valeur("McKenzie2016_filtre");
905     int iter_max=params.get_valeur("McKenzie2016_itermax");
906     int itr_taubin=params.get_valeur("McKenzie2016_itertaubmax");
907     int nbiter=lissage_McKenzie2016(mgmai,gest2,lambda,nu,epsilon,sigma,gamma_,filtre, iter_max, itr_taubin);
908     if (nbiter==iter_max) sprintf(message," Arrêt de la procédure de lissage de McKenzie2016 après %d itérations",nbiter);
909     else sprintf(message," Convergence de la procédure de lissage de McKenzie2016 après %d itérations",nbiter);
910 mckenzie 798 affiche(message);
911 mckenzie 804 McKenzie2016fait=1;
912 mckenzie 798 iteration=iteration+nbiter;
913     }
914 mckenzie 804
915     else if ((iteration>=Taubin1995_debut) && (Taubin1995fait==0))
916     {
917     char message[300];
918     sprintf(message, "Lissage de Taubin1995");
919     affiche(message);
920     double lambda=params.get_valeur("Taubin1995_lambda");
921     double nu=params.get_valeur("Taubin1995_nu");
922     int iter_max=params.get_valeur("Taubin1995_itermax");
923     int nbiter=lissage_Taubin1995(mgmai,gest2,lambda,nu, iter_max);
924     if (nbiter==iter_max) sprintf(message," Arrêt de la procédure de lissage de Taubin1995 après %d itérations",nbiter);
925     else sprintf(message," Convergence de la procédure de lissage de Taubin1995 après %d itérations",nbiter);
926     affiche(message);
927     Taubin1995fait=1;
928     iteration=iteration+nbiter;
929     }
930    
931 francois 457 else iteration++;
932     if (chen2005fait==1)
933     if (chen2008fait==1)
934     if (jiao2012fait==1)
935 mckenzie 804 if (McKenzie2016fait==1)
936     if (Taubin1995fait==1)
937 nana 629 fin=1;
938 francois 457 }
939     while (fin==0);
940 mckenzie 798
941    
942 francois 457 }
943    
944    
945 francois 460 MG_MAILLAGE* MGOPT_POSTTRAITEMENT::extract_skin_maille_entiere(FEM_MAILLAGE* mai,MG_GESTIONNAIRE &gest2)
946 francois 457 {
947     //Menu de la methode de lissage
948     affiche((char*)"Extraction du maillage de surface");
949 picher 231 int coderesu = 0;
950 picher 233 int mai2_id;
951 francois 457 int imp=params.get_valeur("consimpose");
952     int opti=params.get_valeur("consoptimise");
953     int m_auto=params.get_valeur("consnooptimise");
954 francois 791 if (opti==1) conserve(MAGIC::ORIGINE::OPTIMISE);
955     if (imp==1) conserve(MAGIC::ORIGINE::IMPOSE);
956     if (m_auto==1) conserve(MAGIC::ORIGINE::MAILLEUR_AUTO);
957 francois 457 copieorigine(mai);
958 picher 233 MG_MAILLAGE* mg_mai = (MG_MAILLAGE*)mai->get_mg_maillage();
959 francois 457 //gain_poids(mg_mai,gest2);
960     int reactiv=params.get_valeur("reactivation");
961 picher 233 if (reactiv == 1)
962     {
963     reactivation(mg_mai,gest2);
964     }
965 francois 457 affiche((char*)" Analyse des cas non manifold");
966 picher 231 do
967     {
968 francois 457 int nbmaniare,nbmanino,nbpeau;
969     coderesu = extract_skin(mg_mai,gest2,nbpeau,nbmaniare,nbmanino,&mai2_id);
970     char message[500];
971     sprintf(message," %d peaux. %d manifold par arete. %d manifold par noeud",nbpeau,nbmaniare,nbmanino);
972     affiche(message);
973     // gain_poids(mg_mai,gest2);
974 picher 231 }
975     while (coderesu == 0);
976 picher 233
977     MG_MAILLAGE* mg_mai2=gest2.get_mg_maillageid(mai2_id);
978 francois 457
979     return mg_mai2;
980    
981 picher 231 }
982    
983 nana 629
984 francois 460 void MGOPT_POSTTRAITEMENT::adapte_seuil(class FEM_MAILLAGE* fem,FEM_SOLUTION* solution)
985 picher 230 {
986 francois 457 double seuil=params.get_valeur("seuil");
987     solution->active_solution(0);
988     LISTE_FEM_ELEMENT3::iterator it;
989     for (FEM_ELEMENT3 *tet=fem->get_premier_element3(it);tet!=NULL;tet=fem->get_suivant_element3(it))
990 picher 230 {
991 francois 791 if (((MG_TETRA*)tet->get_mg_element_maillage())->get_origine()!=MAGIC::ORIGINE::IMPOSE)
992 francois 457 if (tet->get_solution()>seuil)
993 francois 791 ((MG_TETRA*)tet->get_mg_element_maillage())->change_origine(MAGIC::ORIGINE::OPTIMISE);
994 francois 457 else
995 francois 791 ((MG_TETRA*)tet->get_mg_element_maillage())->change_origine(MAGIC::ORIGINE::MAILLEUR_AUTO);
996 francois 457
997 picher 230 }
998     }
999 francois 224
1000 francois 457
1001     //---------------------------- Lissage Chen 2005 Gilles Philippe -------------------------------------------------------------------------
1002 francois 460 int MGOPT_POSTTRAITEMENT::lissage_chen2005(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, double epsilon, double sigma, int iter_max)
1003 picher 230 {
1004 francois 457 //Methode de lissage inspiree de Chen(2005) par Gilles Philipe Picher Martel
1005 picher 230 double un_sur_pi = 1./M_PI;
1006     int compteur = 0;
1007     int fin = 0;
1008 francois 224
1009 francois 457
1010 picher 230 do
1011     {
1012     TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales;
1013 picher 233 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales2;
1014 picher 230 TPL_LISTE_ENTITE<double> liste_wij;
1015     LISTE_MG_TRIANGLE::iterator it_tri;
1016     int k = 0; //pour identifier les triangles pour liste_normales et liste_wij
1017     for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
1018     {
1019     MG_TRIANGLE_PEAU* mgtri_i = (MG_TRIANGLE_PEAU*)mgtri;
1020     OT_VECTEUR_3D normal_f_i = mgtri_i->calcul_normal();
1021 picher 233 normal_f_i.norme();
1022     liste_normales2.ajouter(normal_f_i);
1023 picher 230 //Remplissage de la liste des voisins du triangle i
1024     TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*> liste_voisins;
1025     MG_NOEUD* noeud1 = mgtri_i->get_noeud1();
1026     double nb_voisins1 = noeud1->get_lien_triangle()->get_nb();
1027     for (int j = 0;j<nb_voisins1;j++)
1028     {
1029     MG_TRIANGLE_PEAU* mgtri_1 = (MG_TRIANGLE_PEAU*) noeud1->get_lien_triangle()->get(j);
1030     liste_voisins.ajouter(mgtri_1);
1031     }
1032     MG_NOEUD* noeud2 = mgtri_i->get_noeud2();
1033     double nb_voisins2 = noeud2->get_lien_triangle()->get_nb();
1034     for (int j = 0;j<nb_voisins2;j++)
1035     {
1036     MG_TRIANGLE_PEAU* mgtri_2 = (MG_TRIANGLE_PEAU*) noeud2->get_lien_triangle()->get(j);
1037     liste_voisins.ajouter(mgtri_2);
1038     }
1039     MG_NOEUD* noeud3 = mgtri_i->get_noeud3();
1040     double nb_voisins3 = noeud3->get_lien_triangle()->get_nb();
1041     for (int j = 0;j<nb_voisins3;j++)
1042     {
1043     MG_TRIANGLE_PEAU* mgtri_3 = (MG_TRIANGLE_PEAU*) noeud3->get_lien_triangle()->get(j);
1044     liste_voisins.ajouter(mgtri_3);
1045     }
1046     liste_voisins.supprimer(mgtri_i);
1047     int nb_voisins = liste_voisins.get_nb();
1048     double w_ij = 1./nb_voisins;
1049     double phi_i_min = 10.;
1050     double s_i = 0.0;
1051     double phi_im = 0.0;
1052 picher 231 double *phi_ij = new double[nb_voisins];
1053 picher 230 OT_VECTEUR_3D normal_f_i_mean(0.,0.,0.);
1054     OT_VECTEUR_3D eta_i(0.,0.,0.);
1055     TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*>::ITERATEUR it;
1056     int j = 0;
1057     for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
1058     {
1059     OT_VECTEUR_3D normal_f_j = mgtri_j->calcul_normal();
1060     //1-Calculer la normale moyenne pour chaque triangle
1061     normal_f_i_mean = normal_f_i_mean + w_ij*normal_f_j;
1062 francois 457 //2.1-On calcul l'angle entre normal_f_i et normal_f_j pour j allant de 1 a Nb_voisins
1063 picher 230 double prod_scalaire = normal_f_i*normal_f_j;
1064 picher 233 if (prod_scalaire > 1.)
1065     {
1066     prod_scalaire = 1.;
1067     }
1068     if (prod_scalaire < -1.)
1069     {
1070     prod_scalaire = -1.;
1071     }
1072 picher 230 phi_ij[j] = acos(prod_scalaire)*un_sur_pi;
1073     //2.2-On trouve le plus petit des angles et la normale heta_i correspondante
1074     if (phi_ij[j] < phi_i_min)
1075     {
1076     phi_i_min = phi_ij[j];
1077     eta_i = normal_f_j;
1078     }
1079     //3.1-On calcul l'angle moyen phi_im
1080     phi_im = phi_im + w_ij*phi_ij[j];
1081     j++;
1082     }
1083     normal_f_i_mean.norme();
1084     j = 0;
1085     for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
1086     {
1087     //3.2-Calcul de s_i selon la variance
1088     s_i = s_i + w_ij*pow((phi_ij[j] - phi_im),2);
1089     j++;
1090     }
1091 picher 231 delete[] phi_ij;
1092 picher 230 //4-On calcule une nouvelle normale pour chaque triangle
1093 francois 458 double pond;
1094     int num=params.get_valeur("chen2005_filtre");
1095     if (num==1) pond=ponderation_gaussian(s_i,sigma);
1096     else if (num==2) pond=ponderation_laplacian(s_i,sigma);
1097     else if (num==3) pond=ponderation_elfallahford(s_i,sigma);
1098     OT_VECTEUR_3D normal_f_i_new = pond*normal_f_i_mean + (1. - pond)*eta_i;
1099 picher 230 normal_f_i_new.norme();
1100     liste_normales.ajouter(normal_f_i_new);
1101     liste_wij.ajouter(w_ij);
1102     mgtri->change_nouveau_numero(k);
1103     k++;
1104     }
1105    
1106     LISTE_MG_NOEUD::iterator it_no;
1107     for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1108     {
1109     int nb_voisins_j = noeud_i->get_lien_triangle()->get_nb();
1110     double w_ij_prime = 0.0;
1111     OT_VECTEUR_3D v_temp(0.,0.,0.);
1112     OT_VECTEUR_3D v_i(noeud_i->get_x(),noeud_i->get_y(),noeud_i->get_z());
1113     for(int j=0;j<nb_voisins_j;j++)
1114     {
1115     MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
1116 francois 457 //On calcule le centroide cj du triangle mgtri_j
1117 picher 230 MG_NOEUD* n1 = mgtri_j->get_noeud1();
1118     MG_NOEUD* n2 = mgtri_j->get_noeud2();
1119     MG_NOEUD* n3 = mgtri_j->get_noeud3();
1120     double cj_x = 0.333333333333333*(n1->get_x() + n2->get_x() + n3->get_x());
1121     double cj_y = 0.333333333333333*(n1->get_y() + n2->get_y() + n3->get_y());
1122     double cj_z = 0.333333333333333*(n1->get_z() + n2->get_z() + n3->get_z());
1123     //On forme le vecteur vi_cj
1124     OT_VECTEUR_3D vi_cj(cj_x - noeud_i->get_x(),cj_y - noeud_i->get_y(),cj_z - noeud_i->get_z());
1125     OT_VECTEUR_3D normal_f_i_new = liste_normales.get(mgtri_j->get_nouveau_numero());
1126 francois 457 // w_ij_prime correspond a la somme des aires des triangles voisins du noeuds
1127 picher 233 OT_VECTEUR_3D AB(n2->get_x() - n1->get_x(),n2->get_y() - n1->get_y(),n2->get_z() - n1->get_z());
1128     OT_VECTEUR_3D AC(n3->get_x() - n1->get_x(),n3->get_y() - n1->get_y(),n3->get_z() - n1->get_z());
1129     OT_VECTEUR_3D prodvect = AB&AC;
1130     double w_ij = 0.5*prodvect.get_longueur();
1131 picher 230 w_ij_prime = w_ij_prime + w_ij;
1132     v_temp = v_temp + w_ij*(vi_cj*normal_f_i_new)*normal_f_i_new;
1133     }
1134 francois 457 //5-On met a jour la position des noeuds
1135 picher 230 v_i = v_i + v_temp/w_ij_prime;
1136 picher 233 int origine = noeud_i->get_origine();
1137 francois 791 if (origine != MAGIC::ORIGINE::IMPOSE)
1138 picher 233 {
1139     noeud_i->change_x(v_i.get_x());
1140     noeud_i->change_y(v_i.get_y());
1141     noeud_i->change_z(v_i.get_z());
1142     }
1143 picher 230 }
1144 francois 457 //Critere d'arret de l'algorithme
1145 picher 230 int l=0;
1146     int nb_tri = mg_mai->get_nb_mg_triangle();
1147     for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
1148     {
1149     MG_TRIANGLE_PEAU* mgtri_i = (MG_TRIANGLE_PEAU*)mgtri;
1150 picher 233 OT_VECTEUR_3D normal_f_i = liste_normales2.get(mgtri_i->get_nouveau_numero());
1151 picher 230 OT_VECTEUR_3D normal_f_i_new = liste_normales.get(mgtri_i->get_nouveau_numero());
1152 picher 248 double critere = 1. - normal_f_i*normal_f_i_new;
1153 picher 230 if (critere <= epsilon) l++;
1154     }
1155 picher 248 double tolerance = 0.01*nb_tri;
1156     if (nb_tri - l <= 0) fin = 1;
1157 picher 230 compteur++;
1158     }
1159     while ((fin == 0) && (compteur < iter_max));
1160    
1161 francois 457 return compteur;
1162     }
1163 picher 230
1164 francois 457 //---------------------------- Lissage Jiao 2012 -------------------------------------------------------------------------
1165 francois 460 int MGOPT_POSTTRAITEMENT::lissage_jiao2012(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, int iter_max)
1166 picher 248 {
1167 francois 457 // Lissage global avec methode de lissage inspiree de JIAO IMR2012 par Jean Christophe sept 2013
1168 picher 248 int compteur = 0;
1169    
1170 cuillier 438 do
1171     {
1172     vector<double> nouv_position_x;
1173     vector<double> nouv_position_y;
1174     vector<double> nouv_position_z;
1175     LISTE_MG_NOEUD::iterator it_no;
1176     for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1177     {
1178     int origine = noeud_i->get_origine();
1179 francois 791 if (origine != MAGIC::ORIGINE::IMPOSE)
1180 cuillier 438 {
1181     int nb_voisins_j = noeud_i->get_lien_triangle()->get_nb();
1182     double wij = 0.0;
1183     double wij_sommej = 0.0;
1184     OT_VECTEUR_3D v_temp(0.,0.,0.);
1185     OT_VECTEUR_3D v_i(noeud_i->get_x(),noeud_i->get_y(),noeud_i->get_z());
1186     for(int j=0;j<nb_voisins_j;j++)
1187     {
1188     MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
1189 francois 457 //On calcule le centroide cj du triangle mgtri_j
1190 cuillier 438 MG_NOEUD* n1 = mgtri_j->get_noeud1();
1191     MG_NOEUD* n2 = mgtri_j->get_noeud2();
1192     MG_NOEUD* n3 = mgtri_j->get_noeud3();
1193     double cj_x = 0.333333333333333*(n1->get_x() + n2->get_x() + n3->get_x());
1194     double cj_y = 0.333333333333333*(n1->get_y() + n2->get_y() + n3->get_y());
1195     double cj_z = 0.333333333333333*(n1->get_z() + n2->get_z() + n3->get_z());
1196     //On forme le vecteur vi_cj et le vecteur cj
1197     OT_VECTEUR_3D cj(cj_x ,cj_y,cj_z);
1198     OT_VECTEUR_3D vi_cj(cj_x - noeud_i->get_x(),cj_y - noeud_i->get_y(),cj_z - noeud_i->get_z());
1199     wij=vi_cj.get_longueur();
1200     wij_sommej=wij_sommej+wij;
1201     v_temp = v_temp + (wij*cj);
1202     }
1203     //5-On calcule la nouvelle position des noeuds et on affecte au tableau temporaire
1204     v_i =v_temp/wij_sommej;
1205     nouv_position_x.push_back(v_i.get_x());
1206     nouv_position_y.push_back(v_i.get_y());
1207     nouv_position_z.push_back(v_i.get_z());
1208     }
1209     }
1210     //On actualise la position des noeuds
1211     int ind_noeud=0;
1212     for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1213     {
1214     int origine = noeud_i->get_origine();
1215 francois 791 if (origine != MAGIC::ORIGINE::IMPOSE)
1216 cuillier 438 {
1217     noeud_i->change_x(nouv_position_x[ind_noeud]);
1218     noeud_i->change_y(nouv_position_y[ind_noeud]);
1219     noeud_i->change_z(nouv_position_z[ind_noeud]);
1220     ind_noeud++;
1221     }
1222     }
1223     //Critere d'arret de l'algorithme
1224     compteur++;
1225     }
1226     while (compteur < iter_max);
1227    
1228 francois 457 return compteur;
1229 cuillier 438 }
1230    
1231 francois 457 //---------------------------- Lissage Chen 2008 -------------------------------------------------------------------------
1232 francois 460 int MGOPT_POSTTRAITEMENT::lissage_chen2008(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, double sigma, double gamma, double epsilon, int iter_max)
1233 cuillier 438 {
1234 francois 457 //Lissage global inspire de Chen(2008) corrige par Jean Christophe sept 2013
1235 cuillier 438 double un_sur_pi = 1./M_PI;
1236     int compteur = 0;
1237     int fin = 0;
1238 francois 457 compteur = 0;
1239 cuillier 438
1240     do
1241     {
1242     vector<double> nouv_position_x;
1243     vector<double> nouv_position_y;
1244     vector<double> nouv_position_z;
1245     TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales;
1246     TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales2;
1247     TPL_LISTE_ENTITE<double> liste_wij;
1248     LISTE_MG_TRIANGLE::iterator it_tri;
1249     int k = 0; //pour identifier les triangles pour liste_normales et liste_wij
1250     for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
1251     {
1252     MG_TRIANGLE_PEAU* mgtri_i = (MG_TRIANGLE_PEAU*)mgtri;
1253     OT_VECTEUR_3D normal_f_i = mgtri_i->calcul_normal();
1254     normal_f_i.norme();
1255     liste_normales2.ajouter(normal_f_i);
1256     //Remplissage de la liste des voisins du triangle i
1257     TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*> liste_voisins;
1258     MG_NOEUD* noeud1 = mgtri_i->get_noeud1();
1259     double nb_voisins1 = noeud1->get_lien_triangle()->get_nb();
1260     for (int j = 0;j<nb_voisins1;j++)
1261     {
1262     MG_TRIANGLE_PEAU* mgtri_1 = (MG_TRIANGLE_PEAU*) noeud1->get_lien_triangle()->get(j);
1263     liste_voisins.ajouter(mgtri_1);
1264     }
1265     MG_NOEUD* noeud2 = mgtri_i->get_noeud2();
1266     double nb_voisins2 = noeud2->get_lien_triangle()->get_nb();
1267     for (int j = 0;j<nb_voisins2;j++)
1268     {
1269     MG_TRIANGLE_PEAU* mgtri_2 = (MG_TRIANGLE_PEAU*) noeud2->get_lien_triangle()->get(j);
1270     liste_voisins.ajouter(mgtri_2);
1271     }
1272     MG_NOEUD* noeud3 = mgtri_i->get_noeud3();
1273     double nb_voisins3 = noeud3->get_lien_triangle()->get_nb();
1274     for (int j = 0;j<nb_voisins3;j++)
1275     {
1276     MG_TRIANGLE_PEAU* mgtri_3 = (MG_TRIANGLE_PEAU*) noeud3->get_lien_triangle()->get(j);
1277     liste_voisins.ajouter(mgtri_3);
1278     }
1279     liste_voisins.supprimer(mgtri_i);
1280     int nb_voisins = liste_voisins.get_nb();
1281     double w_ij = 1./nb_voisins;
1282     double phi_i_min = 10.;
1283     double s_i = 0.0;
1284     double phi_im = 0.0;
1285     double *phi_ij = new double[nb_voisins];
1286     OT_VECTEUR_3D normal_f_i_mean(0.,0.,0.);
1287     normal_f_i_mean = normal_f_i;
1288     OT_VECTEUR_3D eta_i(0.,0.,0.);
1289     TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*>::ITERATEUR it;
1290     int j = 0;
1291     for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
1292     {
1293     OT_VECTEUR_3D normal_f_j = mgtri_j->calcul_normal();
1294     //1-Calculer la normale moyenne pour chaque triangle
1295     normal_f_i_mean = normal_f_i_mean + normal_f_j;
1296 francois 457 //2.1-On calcule l'angle entre normal_f_i et normal_f_j pour j allant de 1 a Nb_voisins
1297 cuillier 438 double prod_scalaire = normal_f_i*normal_f_j;
1298     if (prod_scalaire > 1.)
1299     {
1300     prod_scalaire = 1.;
1301     }
1302     if (prod_scalaire < -1.)
1303     {
1304     prod_scalaire = -1.;
1305     }
1306     phi_ij[j] = acos(prod_scalaire)*un_sur_pi;
1307     //2.2-On trouve le plus petit des angles et la normale heta_i correspondante
1308     if (phi_ij[j] < phi_i_min)
1309     {
1310     phi_i_min = phi_ij[j];
1311     eta_i = normal_f_j;
1312     }
1313 francois 457 //3.1-On calcule l'angle moyen phi_im
1314 cuillier 438 phi_im = phi_im + w_ij*phi_ij[j];
1315     j++;
1316     }
1317     normal_f_i_mean.norme();
1318     j = 0;
1319     for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
1320     {
1321     //3.2-Calcul de s_i selon la variance
1322     s_i = s_i + w_ij*pow((phi_ij[j] - phi_im),2);
1323     j++;
1324     }
1325     delete[] phi_ij;
1326     //4-On calcule une nouvelle normale pour chaque triangle
1327 francois 458 double pond;
1328     int num=params.get_valeur("chen2008_filtre");
1329     if (num==1) pond=ponderation_gaussian(s_i,sigma);
1330     else if (num==2) pond=ponderation_laplacian(s_i,sigma);
1331     else if (num==3) pond=ponderation_elfallahford(s_i,sigma);
1332     OT_VECTEUR_3D normal_f_i_new = pond*normal_f_i_mean + (1. - pond)*eta_i;
1333 cuillier 438 normal_f_i_new.norme();
1334     liste_normales.ajouter(normal_f_i_new);
1335     liste_wij.ajouter(w_ij);
1336     mgtri->change_nouveau_numero(k);
1337     k++;
1338     }
1339    
1340     LISTE_MG_NOEUD::iterator it_no;
1341     for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1342     {
1343     int origine = noeud_i->get_origine();
1344 francois 791 if (origine != MAGIC::ORIGINE::IMPOSE)
1345 cuillier 438 {
1346     int nb_voisins_j = noeud_i->get_lien_triangle()->get_nb();
1347     double w_ij_prime = 0.0;
1348     OT_VECTEUR_3D v_temp(0.,0.,0.);
1349     OT_VECTEUR_3D v_i(noeud_i->get_x(),noeud_i->get_y(),noeud_i->get_z());
1350     for(int j=0;j<nb_voisins_j;j++)
1351     {
1352     MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
1353 francois 457 //On calcule le centroide cj du triangle mgtri_j
1354 cuillier 438 MG_NOEUD* n1 = mgtri_j->get_noeud1();
1355     MG_NOEUD* n2 = mgtri_j->get_noeud2();
1356     MG_NOEUD* n3 = mgtri_j->get_noeud3();
1357     double cj_x = 0.333333333333333*(n1->get_x() + n2->get_x() + n3->get_x());
1358     double cj_y = 0.333333333333333*(n1->get_y() + n2->get_y() + n3->get_y());
1359     double cj_z = 0.333333333333333*(n1->get_z() + n2->get_z() + n3->get_z());
1360     //On forme le vecteur vi_cj
1361     OT_VECTEUR_3D vi_cj(cj_x - noeud_i->get_x(),cj_y - noeud_i->get_y(),cj_z - noeud_i->get_z());
1362     OT_VECTEUR_3D normal_f_i_new = liste_normales.get(mgtri_j->get_nouveau_numero());
1363     v_temp = v_temp + (vi_cj*normal_f_i_new)*normal_f_i_new;
1364     }
1365 francois 457 //5-On met a jour la position des noeuds
1366 cuillier 438 v_i = v_i + (gamma/(2*nb_voisins_j))*v_temp;
1367     nouv_position_x.push_back(v_i.get_x());
1368     nouv_position_y.push_back(v_i.get_y());
1369     nouv_position_z.push_back(v_i.get_z());
1370     }
1371     }
1372    
1373     //On actualise la position des noeuds
1374     int ind_noeud=0;
1375     for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1376     {
1377     int origine = noeud_i->get_origine();
1378 francois 791 if (origine != MAGIC::ORIGINE::IMPOSE)
1379 cuillier 438 {
1380     noeud_i->change_x(nouv_position_x[ind_noeud]);
1381     noeud_i->change_y(nouv_position_y[ind_noeud]);
1382     noeud_i->change_z(nouv_position_z[ind_noeud]);
1383     ind_noeud++;
1384     }
1385     }
1386    
1387     //Critere d'arret de l'algorithme
1388     int l=0;
1389     int nb_tri = mg_mai->get_nb_mg_triangle();
1390     for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
1391     {
1392     MG_TRIANGLE_PEAU* mgtri_i = (MG_TRIANGLE_PEAU*)mgtri;
1393     OT_VECTEUR_3D normal_f_i = liste_normales2.get(mgtri_i->get_nouveau_numero());
1394     OT_VECTEUR_3D normal_f_i_new = liste_normales.get(mgtri_i->get_nouveau_numero());
1395     double critere = 1. - normal_f_i*normal_f_i_new;
1396 picher 248 if (critere <= epsilon) l++;
1397     }
1398     double tolerance = 0.01*nb_tri;
1399     if (nb_tri - l <= 0) fin = 1;
1400     compteur++;
1401     }
1402     while ((fin == 0) && (compteur < iter_max));
1403    
1404 francois 457 return compteur;
1405    
1406 picher 248 }
1407    
1408 cuillier 438
1409 nana 629
1410 mckenzie 804 //---------------------------- Cycle Taubin 1995 par Bryan McKnezie 2016-------------------------------------------------------------------------
1411 francois 805 int MGOPT_POSTTRAITEMENT::cycle_taubin1995(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, double lambda, double nu)
1412 mckenzie 798 {
1413    
1414     /////partie lambda du lissage
1415     vector<double> nouv_position_x;
1416     vector<double> nouv_position_y;
1417     vector<double> nouv_position_z;
1418     LISTE_MG_NOEUD::iterator it_no;
1419     for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1420     {
1421     int origine = noeud_i->get_origine();
1422 francois 805 if ((origine != MAGIC::ORIGINE::IMPOSE)&& (noeud_i->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&& (origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&&(noeud_i->get_lien_topologie()==NULL))///////////////////////////////////////////////////////////////////////////////
1423 mckenzie 798 {
1424 francois 805 TPL_MAP_ENTITE<MG_NOEUD*> liste_voisin;
1425     MG_MAILLAGE_OUTILS ot;
1426     ot.get_noeud_voisin(noeud_i,liste_voisin,2);
1427    
1428 mckenzie 798 int nb_voisins_j = noeud_i->get_lien_triangle()->get_nb();
1429     double delta_x = 0.0;
1430     double delta_y = 0.0;
1431     double delta_z = 0.0;
1432 francois 805 double v_x = noeud_i->get_x();//v_1->get_x();
1433     double v_y = noeud_i->get_y();//v_1->get_y();
1434     double v_z = noeud_i->get_z();//v_1->get_z();
1435     double multiplicateur = (1.0/nb_voisins_j);
1436    
1437 mckenzie 798 for(int j=0;j<nb_voisins_j;j++)
1438     {
1439 francois 805 double v_i_x=liste_voisin.get(j)->get_x();
1440     double v_i_y=liste_voisin.get(j)->get_y();
1441     double v_i_z=liste_voisin.get(j)->get_z();
1442 mckenzie 798 delta_x = delta_x+(multiplicateur*(v_i_x-v_x));
1443     delta_y = delta_y+(multiplicateur*(v_i_y-v_y));
1444     delta_z = delta_z+(multiplicateur*(v_i_z-v_z));
1445    
1446     }
1447 francois 805 double x_prime = (v_x)+(lambda*delta_x);
1448     double y_prime = (v_y)+(lambda*delta_y);
1449     double z_prime = (v_z)+(lambda*delta_z);
1450 mckenzie 798
1451 francois 805 //On calcule la nouvelle position des noeuds et on affecte au tableau temporaire
1452     nouv_position_x.push_back(x_prime);
1453     nouv_position_y.push_back(y_prime);
1454     nouv_position_z.push_back(z_prime);
1455 mckenzie 798 }
1456     }
1457     //On actualise la position des noeuds
1458     int ind_noeud=0;
1459     for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1460     {
1461     int origine = noeud_i->get_origine();
1462     if ((origine != MAGIC::ORIGINE::IMPOSE)&& (noeud_i->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&& (origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&&(noeud_i->get_lien_topologie()==NULL))///////////////////////////////////////////////////////////////////////////////
1463     {
1464     noeud_i->change_x(nouv_position_x[ind_noeud]);
1465     noeud_i->change_y(nouv_position_y[ind_noeud]);
1466     noeud_i->change_z(nouv_position_z[ind_noeud]);
1467     ind_noeud++;
1468     }
1469     }
1470    
1471    
1472     //partie nu du lissage
1473 francois 805 nouv_position_x.clear();
1474     nouv_position_y.clear();
1475     nouv_position_z.clear();
1476     for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1477 mckenzie 798 {
1478 francois 805 int origine = noeud_i->get_origine();
1479     if ((origine != MAGIC::ORIGINE::IMPOSE)&& (noeud_i->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&& (origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&&(noeud_i2->get_lien_topologie()==NULL))///////////////////////////////////////////////////////////////////////////////
1480 mckenzie 798 {
1481 francois 805 TPL_MAP_ENTITE<MG_NOEUD*> liste_voisin;
1482     MG_MAILLAGE_OUTILS ot;
1483     ot.get_noeud_voisin(noeud_i,liste_voisin,2);
1484    
1485     int nb_voisins_j = noeud_i->get_lien_triangle()->get_nb();
1486 mckenzie 798 double delta_x = 0.0;
1487     double delta_y = 0.0;
1488     double delta_z = 0.0;
1489 francois 805 double v_x = noeud_i->get_x();//v_1->get_x();
1490     double v_y = noeud_i->get_y();//v_1->get_y();
1491     double v_z = noeud_i->get_z();//v_1->get_z();
1492     double multiplicateur = (1.0/nb_voisins_j);
1493    
1494 mckenzie 798 for(int j=0;j<nb_voisins_j;j++)
1495     {
1496 francois 805 double v_i_x=liste_voisin.get(j)->get_x();
1497     double v_i_y=liste_voisin.get(j)->get_y();
1498     double v_i_z=liste_voisin.get(j)->get_z();
1499 mckenzie 798 delta_x = delta_x+(multiplicateur*(v_i_x-v_x));
1500     delta_y = delta_y+(multiplicateur*(v_i_y-v_y));
1501     delta_z = delta_z+(multiplicateur*(v_i_z-v_z));
1502    
1503     }
1504 francois 805 double x_prime = (v_x)+(nu*delta_x);
1505     double y_prime = (v_y)+(nu*delta_y);
1506     double z_prime = (v_z)+(nu*delta_z);
1507 mckenzie 798
1508 francois 805 //On calcule la nouvelle position des noeuds et on affecte au tableau temporaire
1509     nouv_position_x.push_back(x_prime);
1510     nouv_position_y.push_back(y_prime);
1511     nouv_position_z.push_back(z_prime);
1512 mckenzie 798 }
1513 francois 805 }
1514 mckenzie 798 //On actualise la position des noeuds
1515 francois 805 ind_noeud=0;
1516     for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1517 mckenzie 798 {
1518 francois 805 int origine = noeud_i->get_origine();
1519     if ((origine != MAGIC::ORIGINE::IMPOSE)&& ( noeud_i->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&& (origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&&( noeud_i2->get_lien_topologie()==NULL))/////////////////////////////////////////////////////////////////////////////
1520 mckenzie 798 {
1521 francois 805 noeud_i->change_x(nouv_position_x[ind_noeud]);
1522     noeud_i->change_y(nouv_position_y[ind_noeud]);
1523     noeud_i->change_z(nouv_position_z[ind_noeud]);
1524     ind_noeud++;
1525 mckenzie 798 }
1526     }
1527 francois 805 return 1;
1528 mckenzie 798
1529     }
1530    
1531 mckenzie 804 //---------------------------- Lissage Taubin 1995 par Bryan McKenzie-------------------------------------------------------------------------
1532     int MGOPT_POSTTRAITEMENT::lissage_Taubin1995(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, double lambda, double nu, int iter_max)
1533 mckenzie 798 {
1534 mckenzie 804 int compt = 0;
1535     int ok = 0;
1536     char mess[200];
1537     do
1538     {
1539     int taubin=cycle_taubin1995(mg_mai, gest2, lambda, nu);
1540     sprintf(mess, "cycle taubin faite"); affiche(mess);
1541     compt = compt+1;
1542     sprintf(mess, "incrémentation compt %d",compt); affiche(mess);
1543     }while (compt < iter_max);
1544     return compt;
1545     sprintf(mess, "fin Taubin1995"); affiche(mess);
1546     }
1547    
1548    
1549     //---------------------------- Varience/Ecart type/ pour McKenzie2016-------------------------------------------------------------------------
1550     void MGOPT_POSTTRAITEMENT::varience_McKenzie2016(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, double *vari0,double *vari1,double *vari2)
1551     {
1552     char mess[300];
1553     int ecart_type = 0;
1554 mckenzie 798 double s_i = 0.0;
1555     double phi_im = 0.0;
1556     double ecart_type_i = 0.;
1557 mckenzie 804 ecart_type = 0;
1558 mckenzie 798 do
1559     {
1560    
1561     TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales;
1562     TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales2;
1563     TPL_LISTE_ENTITE<double> liste_wij;
1564     LISTE_MG_TRIANGLE::iterator it_tri;
1565     int k = 0; //pour identifier les triangles pour liste_normales et liste_wij
1566     for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
1567     {
1568     MG_TRIANGLE_PEAU* mgtri_i = (MG_TRIANGLE_PEAU*)mgtri;
1569     OT_VECTEUR_3D normal_f_i = mgtri_i->calcul_normal();
1570     normal_f_i.norme();
1571     liste_normales2.ajouter(normal_f_i);
1572     //Remplissage de la liste des voisins du triangle i
1573     TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*> liste_voisins;
1574     MG_NOEUD* noeud1 = mgtri_i->get_noeud1();
1575     double nb_voisins1 = noeud1->get_lien_triangle()->get_nb();
1576     for (int j = 0;j<nb_voisins1;j++)
1577     {
1578     MG_TRIANGLE_PEAU* mgtri_1 = (MG_TRIANGLE_PEAU*) noeud1->get_lien_triangle()->get(j);
1579     liste_voisins.ajouter(mgtri_1);
1580     }
1581     MG_NOEUD* noeud2 = mgtri_i->get_noeud2();
1582     double nb_voisins2 = noeud2->get_lien_triangle()->get_nb();
1583     for (int j = 0;j<nb_voisins2;j++)
1584     {
1585     MG_TRIANGLE_PEAU* mgtri_2 = (MG_TRIANGLE_PEAU*) noeud2->get_lien_triangle()->get(j);
1586     liste_voisins.ajouter(mgtri_2);
1587     }
1588     MG_NOEUD* noeud3 = mgtri_i->get_noeud3();
1589     double nb_voisins3 = noeud3->get_lien_triangle()->get_nb();
1590     for (int j = 0;j<nb_voisins3;j++)
1591     {
1592     MG_TRIANGLE_PEAU* mgtri_3 = (MG_TRIANGLE_PEAU*) noeud3->get_lien_triangle()->get(j);
1593     liste_voisins.ajouter(mgtri_3);
1594     }
1595     liste_voisins.supprimer(mgtri_i);
1596     int nb_voisins = liste_voisins.get_nb();
1597     double w_ij = 1./nb_voisins;
1598     double phi_i_min = 10.;
1599     s_i = 0.0;
1600     phi_im = 0.0;
1601     double *phi_ij = new double[nb_voisins];
1602     OT_VECTEUR_3D normal_f_i_mean(0.,0.,0.);
1603     normal_f_i_mean = normal_f_i;
1604     OT_VECTEUR_3D eta_i(0.,0.,0.);
1605     TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*>::ITERATEUR it;
1606     int j = 0;
1607     double un_sur_pi = 1./M_PI;
1608     for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
1609     {
1610     OT_VECTEUR_3D normal_f_j = mgtri_j->calcul_normal();
1611     //1-Calculer la normale moyenne pour chaque triangle
1612     normal_f_i_mean = normal_f_i_mean + normal_f_j;
1613     //2.1-On calcule l'angle entre normal_f_i et normal_f_j pour j allant de 1 a Nb_voisins
1614     double prod_scalaire = normal_f_i*normal_f_j;
1615     if (prod_scalaire > 1.)
1616     {
1617     prod_scalaire = 1.;
1618     }
1619     if (prod_scalaire < -1.)
1620     {
1621     prod_scalaire = -1.;
1622     }
1623     phi_ij[j] = acos(prod_scalaire)*un_sur_pi;
1624     //2.2-On trouve le plus petit des angles et la normale heta_i correspondante
1625     if (phi_ij[j] < phi_i_min)
1626     {
1627     phi_i_min = phi_ij[j];
1628     eta_i = normal_f_j;
1629     }
1630     //3.1-On calcule l'angle moyen phi_im
1631     phi_im = phi_im + w_ij*phi_ij[j];
1632     j++;
1633     }
1634     normal_f_i_mean.norme();
1635     j = 0;
1636     for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
1637     {
1638     //3.2-Calcul de s_i selon la variance
1639     s_i = s_i + w_ij*pow((phi_ij[j] - phi_im),2);
1640     j++;
1641     }
1642     delete[] phi_ij;
1643     }
1644     ecart_type_i = sqrt(s_i);
1645     ecart_type = 1;
1646     }
1647     while (ecart_type == 0);
1648     ecart_type = 0;//reinitialisation d'ecart_type pour la prochainepasse
1649 mckenzie 804 *vari0 = phi_im;
1650     *vari1 = s_i;
1651     *vari2 = ecart_type_i;
1652     //return &varience[0];
1653 mckenzie 798
1654     }
1655    
1656    
1657 mckenzie 804 //---------------------------- Lissage McKenzie2016 par Bryan Mckenzie 2016-------------------------------------------------------------------------
1658     int MGOPT_POSTTRAITEMENT::lissage_McKenzie2016(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, double lambda, double nu, double epsilon,double sigma,double gamma_,int filtre, int iter_max, int itr_taubin)
1659 mckenzie 798 {
1660 mckenzie 804 // Lissage global avec methode de lissage inspiree de Taubin 1995 et Chen 2008 par Bryan McKenzie 2016
1661 mckenzie 798
1662    
1663     //sauvegarde des differents position de noeuds pour conservation des position
1664     vector<double> coord_x;
1665     vector<double> coord_y;
1666     vector<double> coord_z;
1667     vector<double> vecteur_original;
1668     LISTE_MG_NOEUD::iterator it_no;
1669     int ii=0;
1670     for (MG_NOEUD* noeud=mg_mai->get_premier_noeud(it_no);noeud!=NULL;noeud=mg_mai->get_suivant_noeud(it_no))
1671     {
1672     MG_NOEUD* tri=(MG_NOEUD*)noeud;
1673     if(tri->get_origine()!=MAGIC::ORIGINE::MAILLEUR_AUTO)
1674     {
1675     coord_x.push_back(noeud->get_x());
1676     coord_y.push_back(noeud->get_y());
1677     coord_z.push_back(noeud->get_z());
1678     vecteur_original.push_back(sqrt(coord_x[ii]*coord_x[ii] + coord_y[ii]*coord_y[ii] + coord_z[ii]*coord_z[ii]));
1679     ii++;
1680     }
1681    
1682     }
1683    
1684    
1685    
1686     char mess[300];
1687     sprintf(mess, "Depart Taubin1995"); affiche(mess);
1688     double v_initial = 0.0;
1689     double v_final = 0.0;
1690     double v_taubin = 0.0;
1691     double v_taubin_prime = 0.0;
1692     double d_initial = 0.0;
1693     double d_final = 0.0;
1694     double d_taubin = 0.0;
1695     double nu_ = nu;
1696     double sigma_ = sigma;//variable utiliser pour sassuré que la pièce ne grossie pas dan taubin_chen 2
1697     int ecart_type = 0;
1698     double s_i = 0.0;
1699     double phi_im = 0.0;
1700     double ecart_type_i = 0.;
1701     int compteur_triangle_retourne =0;
1702     int compteur_total = 0;
1703     int compteur_taubin_initial = 0;
1704     int compteur_chen = 0;
1705     int compteur_taubin_chen = 0;
1706     int compteur_taubin_final = 0;
1707     int compteur_temp = 0;
1708     int compteur_taubin2D = 0;
1709     int triangle_final_retourne =0;
1710     int iter_taubin = itr_taubin;
1711    
1712    
1713    
1714     int activationPI = 1; // variable qui active l'adjustement du volume dans taubin1995
1715     int activationPI2 = 1; // variable qui active l'adjustement du volume dans taubin_chen
1716     double condition_de_varience = 1000.0; //variable de sortie pour les prenières iteration taubin pour s'assuré que la surface a une certaine surface lisse
1717     int taubin_premiere_passe = 0;
1718    
1719     /// Calcul du volume initial
1720 francois 805 MG_MAILLAGE_OUTILS ot;
1721     v_initial=ot.get_volume(mg_mai);
1722    
1723 mckenzie 798
1724    
1725     //******************parti taubin pur***********************************//
1726    
1727    
1728    
1729     //calcule de la varience et l'écart type pour la surface du maillaige au début
1730 mckenzie 804 double varience_ori0 = 10.0;
1731     double varience_ori1 = 10.0;
1732     double varience_ori2 = 10.0;
1733     varience_McKenzie2016(mg_mai,gest2, &varience_ori0, &varience_ori1, &varience_ori2);
1734     sprintf(mess," Moyenne des normes des triangles de la surface : %f",varience_ori0); affiche(mess);
1735     sprintf(mess," Varience des normes des triangles de la surface : %f",varience_ori1); affiche(mess);
1736     sprintf(mess," Ecart type des normes des triangles de la surface : %f",varience_ori2); affiche(mess);
1737 francois 805 v_taubin=v_initial; //ajout vincent
1738 mckenzie 798 do
1739     {
1740     v_taubin_prime = v_taubin;//assignation du volume de l'itération précédente pour fair la loi de controle
1741     int taubin=cycle_taubin1995(mg_mai, gest2, lambda, nu);
1742    
1743     /// Calcul du volume
1744 francois 805 MG_MAILLAGE_OUTILS ot;
1745     v_taubin=ot.get_volume(mg_mai);
1746 mckenzie 798
1747     //implemantion d'un PI por controler le volume
1748 francois 805 if (activationPI==1)
1749     {
1750 mckenzie 798 if (((fabs(v_taubin)-fabs(v_taubin_prime))/fabs(v_taubin))<-0.1)//fine adjustment makes part bigger if new iteration of part is smaller than the preceeding pass and volume is less than 10% bigger than original
1751     {
1752     nu_ =nu_-0.00005;
1753     }
1754     if (((fabs(v_taubin)-fabs(v_taubin_prime))/fabs(v_taubin))>0.1)//fine adjustment makes part smaller if part is much bigger than preceeding pass and the volume is larger than original
1755     {
1756     nu_ = nu_+0.00005;
1757     }
1758     if (fabs(v_taubin)>(fabs(v_initial)*1.015))//gross adjustment makes part smaller if part is 3% bigger than original make smaller
1759     {
1760     nu_ =nu_+0.0005;
1761     }
1762     if (fabs(v_taubin)<(fabs(v_initial)*0.985))//gross adjustment makes part bigger if it is smaller than the original
1763     {
1764     nu_ =nu_-0.0005;
1765     }
1766 francois 805 }
1767     //double un_sur_pi = 1./M_PI;
1768 mckenzie 798
1769    
1770    
1771    
1772     //code qui vérifie la qualité des different trianges
1773 francois 805 MAILLEUR_ANALYSE m3d(mg_mai);
1774     m3d.change_eps_angle_retourne(0.03000);
1775     m3d.change_borne(0.1,0.2,0.5);
1776     double qualmin,qualmax,qualmoy;
1777     int tab[7];
1778     m3d.analyse_qualite_maillage_2D(NULL,qualmin,qualmax,qualmoy,tab);
1779     int nbretourne=tab[0];
1780 mckenzie 798 int itri=0;
1781    
1782    
1783 francois 805
1784 mckenzie 798 if (tab[0]>0)
1785     {
1786     compteur_triangle_retourne++;
1787     compteur_temp--;
1788     sprintf(mess, "Triangle retourné");
1789     affiche(mess);
1790     }
1791     compteur_taubin_initial++;
1792     compteur_total++;
1793     compteur_temp++;
1794    
1795    
1796     //calcule de la varience et l'écart type pour la surface du maillaige au début
1797 mckenzie 804 double varience0 = 0.0;
1798     double varience1 =0.0;
1799     double varience2 =0.0;
1800     varience_McKenzie2016(mg_mai,gest2, &varience0, &varience1, &varience2);
1801    
1802     if (((compteur_temp >= iter_taubin)&&(varience1<0.0275))||(compteur_taubin_initial >(2*iter_taubin)))
1803 mckenzie 798 {
1804     taubin_premiere_passe = 1;
1805     }
1806    
1807    
1808     }
1809     while (taubin_premiere_passe == 0);
1810    
1811    
1812    
1813    
1814    
1815    
1816    
1817    
1818    
1819     //code d'utilisation de chen pour garder la forme et de taubin pour retirer les triangles retournés
1820 francois 805 sprintf(mess, "Début de Chen pour %d iterations avec Taubin qui résoud les triangles retournés",iter_max); affiche(mess);
1821 mckenzie 798
1822     do
1823     {
1824    
1825 mckenzie 804 int nbiter=lissage_chen2008(mg_mai,gest2,sigma,gamma_,epsilon,1);
1826 mckenzie 798
1827     // code de vérifiaction de triangle retourner
1828 francois 805 MAILLEUR_ANALYSE m3d(mg_mai);
1829     m3d.change_eps_angle_retourne(0.03000);
1830     m3d.change_borne(0.1,0.2,0.5);
1831     double qualmin,qualmax,qualmoy;
1832     int tab[7];
1833     m3d.analyse_qualite_maillage_2D(NULL,qualmin,qualmax,qualmoy,tab);
1834     int triangleretourner =tab[0];
1835 mckenzie 798
1836     //code de retourenage de triangle inverser avec taubin 1995
1837 francois 805 if (triangleretourner >0)
1838 mckenzie 798 {
1839     do
1840     {
1841     v_taubin_prime = v_taubin;//assignation du volume de l'itération précédente pour fair la loi de controle
1842     int taubin=cycle_taubin1995(mg_mai, gest2, lambda, nu);
1843    
1844     /// Calcul du volume
1845 francois 805 MG_MAILLAGE_OUTILS ot;
1846     v_taubin=ot.get_volume(mg_mai);
1847 mckenzie 798
1848     //implemantion d'un PI por controler le volume
1849     if (activationPI2 = 1)
1850     {
1851    
1852     if (((fabs(v_taubin)-fabs(v_taubin_prime))/fabs(v_taubin))<-0.1)//fine adjustment makes part bigger if new iteration of part is smaller than the preceeding pass and volume is less than 10% bigger than original
1853     {
1854     nu_ =nu_-0.00005;
1855     }
1856    
1857     if (((fabs(v_taubin)-fabs(v_taubin_prime))/fabs(v_taubin))>0.1)//fine adjustment makes part smaller if part is much bigger than preceeding pass and the volume is larger than original
1858     {
1859     nu_ = nu_+0.00005;
1860     }
1861    
1862     if (fabs(v_taubin)>(fabs(v_initial)*1.015))//gross adjustment makes part smaller if part is 3% bigger than original make smaller
1863     {
1864     nu_ =nu_+0.0005;
1865     }
1866 mckenzie 804 if (fabs(v_taubin)<(fabs(v_initial)*0.985))//gross adjustment makes part bigger if it is smaller than the original
1867 mckenzie 798 {
1868     nu_ =nu_-0.0005;
1869     }
1870     }
1871    
1872     //code qui vérifie la qualité des different trianges
1873 francois 805 m3d.analyse_qualite_maillage_2D(NULL,qualmin,qualmax,qualmoy,tab);
1874     if (tab[0]>0)
1875 mckenzie 798 {
1876     triangleretourner = 1;
1877     sprintf(mess, "Trianlge retourner pas régler"); affiche(mess);
1878    
1879     }
1880     else
1881     {
1882     triangleretourner = 0;
1883     sprintf(mess, "Trianlge retourner régler"); affiche(mess);
1884     }
1885     compteur_triangle_retourne++;
1886     compteur_taubin_chen++;
1887     compteur_total++;
1888     }
1889    
1890     while ((triangleretourner > 0));
1891    
1892     }
1893     compteur_total++;
1894     compteur_chen++;
1895    
1896    
1897     }
1898     while (compteur_chen < iter_max);
1899    
1900     sprintf(mess, "Début du retour de volume avec Taubin1995 qui résoud les triangles retournés"); affiche(mess);
1901     // passe final de taubin pour revenir au volume initial
1902 francois 805 v_taubin=ot.get_volume(mg_mai);
1903 mckenzie 798
1904 francois 805 if ((fabs(fabs(v_initial)-fabs(v_taubin)))>(0.02*(fabs(v_initial))))
1905 mckenzie 798 {
1906     do
1907     {
1908     v_taubin_prime = v_taubin;
1909     int taubin=cycle_taubin1995(mg_mai, gest2, lambda, nu);
1910    
1911     /// Calcul du volume
1912 francois 805 v_taubin=ot.get_volume(mg_mai);
1913 mckenzie 798
1914     //implemantion d'un PDF pour controler le volume
1915    
1916     if (((fabs(v_taubin)-fabs(v_taubin_prime))/fabs(v_taubin))<-0.1)//fine adjustment makes part bigger if new iteration of part is smaller than the preceeding pass and volume is less than 10% bigger than original
1917     {
1918     nu_ =nu_-0.00002;
1919     sprintf(mess, "ajustement mineur 1"); affiche(mess);
1920     }
1921    
1922     if (((fabs(v_taubin)-fabs(v_taubin_prime))/fabs(v_taubin))>0.1)//fine adjustment makes part smaller if part is much bigger than preceeding pass and the volume is larger than original
1923     {
1924     nu_ = nu_+0.00002;
1925     sprintf(mess, "ajustement mineur 2"); affiche(mess);
1926     }
1927    
1928     if (fabs(v_taubin)>(fabs(v_initial)*1.015))//gross adjustment makes part smaller if part is 1.5% bigger than original make smaller
1929     {
1930     nu_ =nu_+0.0005;
1931     sprintf(mess, "ajustement majeur 1"); affiche(mess);
1932     }
1933     if (fabs(v_taubin)<(fabs(v_initial)*0.985))//gross adjustment makes part bigger if it is more than 1.5% smaller than the original
1934     {
1935     nu_ =nu_-0.0005;
1936     sprintf(mess, "ajustement majeur 2"); affiche(mess);
1937     }
1938     sprintf(mess, "Volume: %f\n old vol: %f\n nu_: %f\n",v_taubin,v_taubin_prime, nu_); affiche(mess);
1939    
1940    
1941    
1942    
1943     //code qui vérifie la qualité des different trianges
1944 francois 805 MAILLEUR_ANALYSE m3d(mg_mai);
1945     m3d.change_eps_angle_retourne(0.03000);
1946     m3d.change_borne(0.1,0.2,0.5);
1947     double qualmin,qualmax,qualmoy;
1948     int tab[7];
1949     m3d.analyse_qualite_maillage_2D(NULL,qualmin,qualmax,qualmoy,tab);
1950     int triangleretourner =tab[0];
1951     if (tab[0]>0)
1952 mckenzie 798 {
1953     compteur_triangle_retourne++;
1954     sprintf(mess, "Triangle retourné");
1955     affiche(mess);
1956     triangle_final_retourne =1;
1957     }
1958     else{triangle_final_retourne =0;}
1959    
1960     compteur_taubin_final++;
1961     compteur_total++;
1962    
1963     }
1964    
1965     while ((triangle_final_retourne ==0)&&(fabs(v_initial-v_taubin)>(fabs(0.02*v_initial))));//((compteur_ < 1000));
1966    
1967     }
1968    
1969     ////////////////////////////calcul du mouvement des noeuds par rapport a l'original
1970     /******************code qui calcule la moyenne de pourcentage de déplacement des differents noeuds*/
1971     //LISTE_MG_NOEUD::iterator it_no;
1972     ii=0;
1973 francois 805 int numdepla=0;
1974     double distot=0;
1975     double distotx=0;
1976     double distoty=0;
1977     double distotz=0;
1978     double dismin=1e300,dismax=-1e300;
1979     double disminx=1e300,dismaxx=-1e300;
1980     double disminy=1e300,dismaxy=-1e300;
1981     double disminz=1e300,dismaxz=-1e300;
1982     double xmin=1e300,xmax=-1e300;
1983     double ymin=1e300,ymax=-1e300;
1984     double zmin=1e300,zmax=-1e300;
1985 mckenzie 798 for (MG_NOEUD* noeud=mg_mai->get_premier_noeud(it_no);noeud!=NULL;noeud=mg_mai->get_suivant_noeud(it_no))
1986     {
1987 francois 805 if(noeud->get_origine()!=MAGIC::ORIGINE::IMPOSE)////////
1988 mckenzie 798 {
1989 francois 805 double x=noeud->get_x();
1990     double y=noeud->get_y();
1991     double z=noeud->get_z();
1992     if (x<xmin) xmin=x;
1993     if (y<ymin) ymin=y;
1994     if (z<zmin) zmin=z;
1995     if (x>xmax) xmax=x;
1996     if (y>ymax) ymax=y;
1997     if (z>zmax) zmax=z;
1998     double dx=fabs(noeud->get_x()-coord_x[ii]);
1999     double dy=fabs(noeud->get_y()-coord_y[ii]);
2000     double dz=fabs(noeud->get_z()-coord_z[ii]);
2001     double dis=sqrt(dx*dx+dy*dy+dz*dz);
2002     if (dx>dismaxx) dismaxx=dx;
2003     if (dx<disminx) disminx=dx;
2004     if (dy>dismaxy) dismaxy=dy;
2005     if (dy<disminy) disminy=dy;
2006     if (dz>dismaxz) dismaxz=dz;
2007     if (dz<disminz) disminz=dz;
2008     if (dis>dismax) dismax=dis;
2009     if (dis<dismin) dismin=dis;
2010     distot=distot+dis;
2011     distotx=distoty+dx;
2012     distoty=distoty+dy;
2013     distotz=distotz+dz;
2014     numdepla++;
2015 mckenzie 798 }
2016 francois 805 ii++;
2017 mckenzie 798 }
2018 francois 805 affiche((char*)"");
2019     sprintf(mess, "Déplacement absolu minimum en X : %f en Y : %f en Z : %f en amplitude : %f",disminx,disminy,disminz,dismin); affiche(mess);
2020     sprintf(mess, "Déplacement absolu maximum en X : %f en Y : %f en Z : %f en amplitude : %f",dismaxx,dismaxy,dismaxz,dismax); affiche(mess);
2021     sprintf(mess, "Déplacement absolu moyen (tous les noeuds) en X : %f en Y : %f en Z : %f en amplitude : %f",distotx/ii,distoty/ii,distotz/ii,distot/ii); affiche(mess);
2022     sprintf(mess, "Déplacement absolu moyen (les noeuds du non design) en X : %f en Y : %f en Z : %f en amplitude : %f",distotx/numdepla,distoty/numdepla,distotz/numdepla,distot/numdepla); affiche(mess);
2023     double dx=xmax-xmin;
2024     double dy=ymax-ymin;
2025     double dz=zmax-zmin;
2026     double dmax=dx;
2027     if (dy>dmax) dmax=dy;
2028     if (dz>dmax) dmax=dz;
2029     sprintf(mess, "Déplacement relatif moyen (tous les noeuds) en X : %f%% en Y : %f%% en Z : %f%% en amplitude : %f%%",distotx/ii/dx*100.,distoty/ii/dy*100.,distotz/ii/dz*100.,distot/ii/dmax*100.); affiche(mess);
2030     sprintf(mess, "Déplacement relatif moyen (les noeuds du non design) en X : %f%% en Y : %f%% en Z : %f%% en amplitude : %f%%",distotx/numdepla/dx*100.,distoty/numdepla/dy*100.,distotz/numdepla/dz*100.,distot/numdepla/dmax*100.); affiche(mess);
2031 mckenzie 798
2032    
2033    
2034 francois 805 affiche((char*)"");
2035 mckenzie 798
2036 francois 805 affiche((char*)"");
2037    
2038    
2039    
2040 mckenzie 798 /// Calcul du volume final
2041 francois 805 v_final=ot.get_volume(mg_mai);
2042    
2043 mckenzie 798 double delta_vol = v_final-v_initial;
2044     double vol_pourcent = (v_final/v_initial)*100;
2045     double delta_vol_pourcent = vol_pourcent-100;
2046     sprintf(mess, "Volume initial: %f",v_initial);affiche(mess);
2047     sprintf(mess, "Volume final: %f",v_final);affiche(mess);
2048 francois 805 sprintf(mess, "Volume final pourcentage: %f%%",vol_pourcent);affiche(mess);
2049 mckenzie 798 sprintf(mess, "Delta Volume: %f",delta_vol);affiche(mess);
2050 francois 805 sprintf(mess, "Delta Volume pourcentage: %f%%",delta_vol_pourcent);affiche(mess);
2051 mckenzie 798 sprintf(mess, " Iteration inital Taubin1995: %i",compteur_taubin_initial); affiche(mess);
2052     sprintf(mess, " Iteration Chen2008: %i",compteur_chen); affiche(mess);
2053     sprintf(mess, " Iteration Taubin1995 dans Chen2008: %i",compteur_taubin_chen); affiche(mess);
2054     sprintf(mess, " epsilon: %f",epsilon); affiche(mess);
2055     sprintf(mess, " sigma: %f",sigma); affiche(mess);
2056     sprintf(mess, " gamma_: %f",gamma_); affiche(mess);
2057     sprintf(mess, " filtre: %i",filtre); affiche(mess);
2058     sprintf(mess, " Iteration final Taubin1995: %i",compteur_taubin_final); affiche(mess);
2059     sprintf(mess, " lambda(depart): %f",lambda); affiche(mess);
2060     sprintf(mess, " nu(depart):%f",nu); affiche(mess);
2061     sprintf(mess, " nu(fin):%f",nu_); affiche(mess);
2062     sprintf(mess, " Iteration triangle retourné: %i",compteur_triangle_retourne); affiche(mess);
2063     sprintf(mess, " Iteration Total: %i",compteur_total); affiche(mess);
2064    
2065    
2066    
2067     //verification de nombre de triange retournée
2068 francois 805 MAILLEUR_ANALYSE m3d(mg_mai);
2069     double eps_angle_retourne=0.03;
2070     m3d.change_eps_angle_retourne(eps_angle_retourne);
2071     double borne1=0.1;
2072     double borne2=0.2;
2073     double borne3=0.5;
2074     m3d.change_borne(borne1,borne2,borne3);
2075     double qualmin,qualmax,qualmoy;
2076     int tab[7];
2077     m3d.analyse_qualite_maillage_2D(NULL,qualmin,qualmax,qualmoy,tab);
2078     sprintf(mess,"\n\nANALYSEUR DE MG MAILLAGE 2D"); affiche(mess);
2079 mckenzie 798 sprintf(mess," Nombre de triangles avec des noeuds fusionnés : %d",tab[6]); affiche(mess);
2080     sprintf(mess," Nombre de triangles avec 1 voisin manquant : %d",tab[5]); affiche(mess);
2081     sprintf(mess," critere d'angle limite pour l'inversion : %lf",eps_angle_retourne); affiche(mess);
2082 francois 805 sprintf(mess," qualite moyenne des triangles de frontiere : %lf",qualmoy); affiche(mess);
2083 mckenzie 798 sprintf(mess," qualite min des triangles de frontiere : %lf",qualmin); affiche(mess);
2084     sprintf(mess," qualite max des triangles de frontiere : %lf",qualmax); affiche(mess);
2085 francois 805 sprintf(mess," nombre de triangles de frontiere >%lf : %d (%.2lf%%)",borne3,tab[4],tab[4]*100./mg_mai->get_nb_mg_triangle()); affiche(mess);
2086     sprintf(mess," nombre de triangles de frontiere >%lf : %d (%.2lf%%)",borne2,tab[3],tab[3]*100./mg_mai->get_nb_mg_triangle()); affiche(mess);
2087     sprintf(mess," nombre de triangles de frontiere >%lf : %d (%.2lf%%)",borne1,tab[2],tab[2]*100./mg_mai->get_nb_mg_triangle()); affiche(mess);
2088     sprintf(mess," nombre de triangles de frontiere >%lf : %d (%.2lf%%)",0.,tab[1],tab[1]*100./mg_mai->get_nb_mg_triangle()); affiche(mess);
2089     sprintf(mess," nombre de triangles de frontiere retournes : %d (%.2lf%%)",tab[0],tab[0]*100./mg_mai->get_nb_mg_triangle()); affiche(mess);
2090 mckenzie 798
2091     //calcule de la varience et l'écart type pour la surface du maillaige
2092 mckenzie 804 double varience00 =0.0;
2093     double varience11 =0.0;
2094     double varience22 =0.0;
2095     varience_McKenzie2016(mg_mai,gest2, &varience00, &varience11, &varience22);
2096 francois 805 sprintf(mess,"\n Moyenne des normes des triangles de la surface : %f",varience00); affiche(mess);
2097 mckenzie 804 sprintf(mess," Varience des normes des triangles de la surface : %f",varience11); affiche(mess);
2098     sprintf(mess," Ecart type des normes des triangles de la surface : %f",varience22); affiche(mess);
2099 mckenzie 798
2100     return compteur_total;
2101     }
2102    
2103    
2104    
2105    
2106 francois 457 //---------------------------- Extract skin -------------------------------------------------------------------------
2107 francois 460 int MGOPT_POSTTRAITEMENT::extract_skin(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2,int &nbpeau,int &nbmaniare,int &nbmanino, int *mai2_id)
2108 cuillier 438 {
2109    
2110 francois 457 //etape 0 - On commence par mettre a zero tous les nouveau_numero des triangles et des noeuds du maillage
2111 francois 222 LISTE_MG_TRIANGLE::iterator it_tri;
2112     for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
2113     {
2114     mgtri->change_nouveau_numero(0);
2115 francois 791 mgtri->change_origine(MAGIC::ORIGINE::MAILLEUR_AUTO);
2116 francois 222 }
2117     LISTE_MG_NOEUD::iterator it_noeud;
2118     for (MG_NOEUD* mgnoeud=mg_mai->get_premier_noeud(it_noeud);mgnoeud!=NULL;mgnoeud=mg_mai->get_suivant_noeud(it_noeud))
2119     {
2120     mgnoeud->change_nouveau_numero(0);
2121     }
2122    
2123 francois 457 //etape 1 - On boucle ensuite tous les tetraedres pour ajouter un compteur du nombre de fois qu'un triangle appartient a 1 tetra
2124 picher 233 LISTE_MG_TETRA::iterator it_tetra;
2125     for (MG_TETRA* mgtet=mg_mai->get_premier_tetra(it_tetra);mgtet!=NULL;mgtet=mg_mai->get_suivant_tetra(it_tetra))
2126 francois 222 {
2127     int origine = mgtet->get_origine();
2128 francois 791 if (origine==MAGIC::ORIGINE::IMPOSE)
2129 francois 222 {
2130 francois 791 mgtet->get_triangle1()->change_origine(MAGIC::ORIGINE::IMPOSE);
2131     mgtet->get_triangle2()->change_origine(MAGIC::ORIGINE::IMPOSE);
2132     mgtet->get_triangle3()->change_origine(MAGIC::ORIGINE::IMPOSE);
2133     mgtet->get_triangle4()->change_origine(MAGIC::ORIGINE::IMPOSE);
2134 francois 224 }
2135 francois 791 if (origine==MAGIC::ORIGINE::OPTIMISE)
2136 francois 224 {
2137 francois 791 if (mgtet->get_triangle1()->get_origine()!=MAGIC::ORIGINE::IMPOSE) mgtet->get_triangle1()->change_origine(MAGIC::ORIGINE::OPTIMISE);
2138     if (mgtet->get_triangle2()->get_origine()!=MAGIC::ORIGINE::IMPOSE) mgtet->get_triangle2()->change_origine(MAGIC::ORIGINE::OPTIMISE);
2139     if (mgtet->get_triangle3()->get_origine()!=MAGIC::ORIGINE::IMPOSE) mgtet->get_triangle3()->change_origine(MAGIC::ORIGINE::OPTIMISE);
2140     if (mgtet->get_triangle4()->get_origine()!=MAGIC::ORIGINE::IMPOSE) mgtet->get_triangle4()->change_origine(MAGIC::ORIGINE::OPTIMISE);
2141 francois 224 }
2142    
2143 francois 791 if (((origine == MAGIC::ORIGINE::OPTIMISE) && (etat[(MAGIC::ORIGINE::OPTIMISE-1000)/10]==1) ) ||
2144     ((origine == MAGIC::ORIGINE::IMPOSE) && (etat[(MAGIC::ORIGINE::IMPOSE-1000)/10]==1) ) ||
2145     ((origine == MAGIC::ORIGINE::MAILLEUR_AUTO) && (etat[(MAGIC::ORIGINE::MAILLEUR_AUTO-1000)/10]==1) ) ||
2146     ((origine == MAGIC::ORIGINE::TRIANGULATION) && (etat[(MAGIC::ORIGINE::TRIANGULATION-1000)/10]==1) ) ||
2147     ((origine == MAGIC::ORIGINE::MODIFICATION) && (etat[(MAGIC::ORIGINE::MODIFICATION-1000)/10]==1) ) ||
2148     ((origine == MAGIC::ORIGINE::DUPLIQUER) && (etat[(MAGIC::ORIGINE::DUPLIQUER-1000)/10]==1) ) )
2149 francois 224
2150     {
2151 francois 222 int num1 = mgtet->get_triangle1()->get_nouveau_numero();
2152     int num2 = mgtet->get_triangle2()->get_nouveau_numero();
2153     int num3 = mgtet->get_triangle3()->get_nouveau_numero();
2154     int num4 = mgtet->get_triangle4()->get_nouveau_numero();
2155     num1++;
2156     num2++;
2157     num3++;
2158     num4++;
2159     mgtet->get_triangle1()->change_nouveau_numero(num1);
2160     mgtet->get_triangle2()->change_nouveau_numero(num2);
2161     mgtet->get_triangle3()->change_nouveau_numero(num3);
2162     mgtet->get_triangle4()->change_nouveau_numero(num4);
2163     }
2164     }
2165    
2166 francois 457 //etape 2 - On boucle l'ensemble des triangles identifies a l'etape 1 pour identifier les noeuds leur appartenant
2167 francois 222 for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
2168     {
2169     int num = mgtri->get_nouveau_numero();
2170     if (num == 1)
2171     {
2172     MG_NOEUD* noeud1 = mgtri->get_noeud1();
2173     MG_NOEUD* noeud2 = mgtri->get_noeud2();
2174     MG_NOEUD* noeud3 = mgtri->get_noeud3();
2175     noeud1->change_nouveau_numero(1);
2176     noeud2->change_nouveau_numero(1);
2177     noeud3->change_nouveau_numero(1);
2178 francois 791 if (mgtri->get_origine()==MAGIC::ORIGINE::IMPOSE)
2179 picher 248 {
2180 francois 791 noeud1->change_origine(MAGIC::ORIGINE::IMPOSE);
2181     noeud2->change_origine(MAGIC::ORIGINE::IMPOSE);
2182     noeud3->change_origine(MAGIC::ORIGINE::IMPOSE);
2183 picher 248 }
2184 francois 222 }
2185     }
2186    
2187 francois 457 //etape 3 - On cree un nouveau maillage pour la peau
2188 francois 793 gest2.vide();
2189     MG_GEOMETRIE* geo=new MG_GEOMETRIE((char*)"VIRTUEL",(char*)"VIRTUEL");
2190     geo->change_valeur_unite(mg_mai->get_mg_geometrie()->get_valeur_unite());
2191     gest2.ajouter_mg_geometrie(geo);
2192     MG_FACE_ELEMENT* face=new MG_FACE_ELEMENT();
2193     geo->ajouter_mg_face(face);
2194     MG_MAILLAGE* mai2 = new MG_MAILLAGE(geo);
2195 francois 222 gest2.ajouter_mg_maillage(mai2);
2196    
2197 francois 457 //etape 4 - On boucle l'ensemble des noeuds identifies a l'etape 2 pour les recreer dans le second maillage
2198 francois 222 for (MG_NOEUD* mgnoeud=mg_mai->get_premier_noeud(it_noeud);mgnoeud!=NULL;mgnoeud=mg_mai->get_suivant_noeud(it_noeud))
2199     {
2200     int num = mgnoeud->get_nouveau_numero();
2201     if (num == 1)
2202     {
2203     double x = mgnoeud->get_x();
2204     double y = mgnoeud->get_y();
2205     double z = mgnoeud->get_z();
2206 francois 791 int origine=MAGIC::ORIGINE::TRIANGULATION;
2207 francois 792 int nb_tri=mgnoeud->get_lien_triangle()->get_nb();
2208     bool tri2d=false,tri3d=false;
2209     for (int i=0;i<nb_tri;i++)
2210     {
2211     if (mgnoeud->get_lien_triangle()->get(i)->get_nouveau_numero()==1)
2212     {
2213     if (mgnoeud->get_lien_triangle()->get(i)->get_lien_topologie()->get_dimension()==2) tri2d=true;
2214     if (mgnoeud->get_lien_triangle()->get(i)->get_lien_topologie()->get_dimension()==3) tri3d=true;
2215     }
2216     }
2217     if ((tri2d)&&(tri3d)) origine=MAGIC::ORIGINE::TRIANGULATION_ARETE;
2218     if (mgnoeud->get_lien_topologie()->get_dimension()==1) origine=MAGIC::ORIGINE::TRIANGULATION_ARETE;
2219 francois 791 if (mgnoeud->get_origine()==MAGIC::ORIGINE::IMPOSE) origine=MAGIC::ORIGINE::IMPOSE;
2220 francois 224 MG_NOEUD* noeud1 = new MG_NOEUD(NULL,x,y,z,origine);
2221 francois 222 mai2->ajouter_mg_noeud(noeud1);
2222     mgnoeud->change_nouveau_numero(noeud1->get_id());
2223 francois 234 noeud1->change_nouveau_numero(mgnoeud->get_id());
2224 francois 222 }
2225     }
2226    
2227 francois 457 // etape 5 - On boucle l'ensemble des triangles identifies a l'etape 1 pour les recreer dans le maillage 2
2228 picher 233 for (MG_TETRA* mgtet=mg_mai->get_premier_tetra(it_tetra);mgtet!=NULL;mgtet=mg_mai->get_suivant_tetra(it_tetra))
2229 francois 222 {
2230 francois 224 int originetet=mgtet->get_origine();
2231 francois 791 if (((originetet == MAGIC::ORIGINE::OPTIMISE) && (etat[(MAGIC::ORIGINE::OPTIMISE-1000)/10]==1) ) ||
2232     ((originetet == MAGIC::ORIGINE::IMPOSE) && (etat[(MAGIC::ORIGINE::IMPOSE-1000)/10]==1) ) ||
2233     ((originetet == MAGIC::ORIGINE::MAILLEUR_AUTO) && (etat[(MAGIC::ORIGINE::MAILLEUR_AUTO-1000)/10]==1) ) ||
2234     ((originetet == MAGIC::ORIGINE::TRIANGULATION) && (etat[(MAGIC::ORIGINE::TRIANGULATION-1000)/10]==1) ) ||
2235     ((originetet == MAGIC::ORIGINE::MODIFICATION) && (etat[(MAGIC::ORIGINE::MODIFICATION-1000)/10]==1) ) ||
2236     ((originetet == MAGIC::ORIGINE::DUPLIQUER) && (etat[(MAGIC::ORIGINE::DUPLIQUER-1000)/10]==1) ) )
2237 francois 222 {
2238 francois 224 MG_NOEUD* noeud1 = mgtet->get_noeud1();
2239     MG_NOEUD* noeud2 = mgtet->get_noeud2();
2240     MG_NOEUD* noeud3 = mgtet->get_noeud3();
2241     MG_NOEUD* noeud4 = mgtet->get_noeud4();
2242 francois 222 MG_NOEUD* node1 = mai2->get_mg_noeudid(noeud1->get_nouveau_numero());
2243     MG_NOEUD* node2 = mai2->get_mg_noeudid(noeud2->get_nouveau_numero());
2244     MG_NOEUD* node3 = mai2->get_mg_noeudid(noeud3->get_nouveau_numero());
2245 francois 224 MG_NOEUD* node4 = mai2->get_mg_noeudid(noeud4->get_nouveau_numero());
2246     MG_TRIANGLE* tri1=mgtet->get_triangle1();
2247     MG_TRIANGLE* tri2=mgtet->get_triangle2();
2248     MG_TRIANGLE* tri3=mgtet->get_triangle3();
2249     MG_TRIANGLE* tri4=mgtet->get_triangle4();
2250     if (tri1->get_nouveau_numero()==1)
2251     {
2252 francois 791 int origine=MAGIC::ORIGINE::TRIANGULATION;
2253     if (tri1->get_origine()==MAGIC::ORIGINE::IMPOSE) origine=MAGIC::ORIGINE::IMPOSE;
2254 francois 793 MG_FACE* topo=NULL;
2255     if (tri1->get_lien_topologie()->get_dimension()==2) topo=face;
2256     MG_TRIANGLE_PEAU* tripeau = insere_triangle(topo,node1,node2,node3,mai2,origine);
2257 francois 224 tripeau->change_nouveau_numero(0);
2258     tri1->change_nouveau_numero(0);
2259     }
2260     if (tri2->get_nouveau_numero()==1)
2261     {
2262 francois 791 int origine=MAGIC::ORIGINE::TRIANGULATION;
2263     if (tri2->get_origine()==MAGIC::ORIGINE::IMPOSE) origine=MAGIC::ORIGINE::IMPOSE;
2264 francois 793 MG_FACE* topo=NULL;
2265     if (tri2->get_lien_topologie()->get_dimension()==2) topo=face;
2266     MG_TRIANGLE_PEAU* tripeau = insere_triangle(topo,node1,node4,node2,mai2,origine);
2267 francois 224 tripeau->change_nouveau_numero(0);
2268     tri2->change_nouveau_numero(0);
2269     }
2270     if (tri3->get_nouveau_numero()==1)
2271     {
2272 francois 791 int origine=MAGIC::ORIGINE::TRIANGULATION;
2273 francois 793 MG_FACE* topo=NULL;
2274     if (tri3->get_lien_topologie()->get_dimension()==2) topo=face;
2275 francois 791 if (tri3->get_origine()==MAGIC::ORIGINE::IMPOSE) origine=MAGIC::ORIGINE::IMPOSE;
2276 francois 793 MG_TRIANGLE_PEAU* tripeau = insere_triangle(topo,node2,node4,node3,mai2,origine);
2277 francois 224 tripeau->change_nouveau_numero(0);
2278     tri3->change_nouveau_numero(0);
2279     }
2280     if (tri4->get_nouveau_numero()==1)
2281     {
2282 francois 791 int origine=MAGIC::ORIGINE::TRIANGULATION;
2283 francois 793 MG_FACE* topo=NULL;
2284     if (tri4->get_lien_topologie()->get_dimension()==2) topo=face;
2285 francois 791 if (tri4->get_origine()==MAGIC::ORIGINE::IMPOSE) origine=MAGIC::ORIGINE::IMPOSE;
2286 francois 793 MG_TRIANGLE_PEAU* tripeau = insere_triangle(topo,node1,node3,node4,mai2,origine);
2287 francois 224 tripeau->change_nouveau_numero(0);
2288     tri4->change_nouveau_numero(0);
2289     }
2290 francois 222 }
2291 francois 224 }
2292     // etape 6 recherche des vosins
2293     for (MG_TRIANGLE* mgtri=mai2->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mai2->get_suivant_triangle(it_tri))
2294     {
2295     MG_TRIANGLE_PEAU* tripeau=(MG_TRIANGLE_PEAU*)mgtri;
2296     MG_TRIANGLE_PEAU* voisin1=recherche_voisin(tripeau->get_noeud1(),tripeau->get_noeud2(),tripeau);
2297     MG_TRIANGLE_PEAU* voisin2=recherche_voisin(tripeau->get_noeud2(),tripeau->get_noeud3(),tripeau);
2298     MG_TRIANGLE_PEAU* voisin3=recherche_voisin(tripeau->get_noeud3(),tripeau->get_noeud1(),tripeau);
2299     tripeau->change_voisin1(voisin1);
2300     tripeau->change_voisin2(voisin2);
2301     tripeau->change_voisin3(voisin3);
2302     }
2303 francois 457 // etape 7 - On recherche les peaux
2304 francois 224 int fin;
2305     do
2306     {
2307     fin=1;
2308     for (MG_TRIANGLE* mgtri=mai2->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mai2->get_suivant_triangle(it_tri))
2309     {
2310     MG_TRIANGLE_PEAU *tripeau=(MG_TRIANGLE_PEAU*)mgtri;
2311     if (tripeau->get_nouveau_numero()==0)
2312     {
2313     fin=0;
2314     std::vector<MG_TRIANGLE_PEAU*> *peau=new std::vector<MG_TRIANGLE_PEAU*>;
2315     lst_peau.push_back(peau);
2316     tripeau->change_nouveau_numero(1);
2317     peau->push_back(tripeau);
2318     determine_peau(peau);
2319     }
2320     }
2321     }
2322     while (fin==0);
2323 francois 457 nbpeau=lst_peau.size();
2324 francois 224 //test de manifold
2325     LISTE_MG_SEGMENT::iterator itseg;
2326     for (MG_SEGMENT* seg=mai2->get_premier_segment(itseg);seg!=NULL;seg=mai2->get_suivant_segment(itseg))
2327     seg->change_nouveau_numero(0);
2328     TPL_MAP_ENTITE<MG_SEGMENT*> nonmanifoldarete;
2329     TPL_MAP_ENTITE<MG_NOEUD*> nonmanifoldnoeud;
2330 francois 234 TPL_MAP_ENTITE<MG_NOEUD*> nonmanifoldnoeuddepuisarete;
2331 francois 457 nbpeau=lst_peau.size();
2332 francois 224 for (int i=0;i<nbpeau;i++)
2333     {
2334     int nbtri=lst_peau[i]->size();
2335     for (int j=0;j<nbtri;j++)
2336     {
2337     MG_TRIANGLE_PEAU* tripeau=(*lst_peau[i])[j];
2338     tripeau->get_segment1()->change_nouveau_numero(tripeau->get_segment1()->get_nouveau_numero()+1);
2339     tripeau->get_segment2()->change_nouveau_numero(tripeau->get_segment2()->get_nouveau_numero()+1);
2340     tripeau->get_segment3()->change_nouveau_numero(tripeau->get_segment3()->get_nouveau_numero()+1);
2341     if (tripeau->get_segment1()->get_nouveau_numero()>2)
2342     nonmanifoldarete.ajouter(tripeau->get_segment1());
2343     if (tripeau->get_segment2()->get_nouveau_numero()>2)
2344     nonmanifoldarete.ajouter(tripeau->get_segment2());
2345     if (tripeau->get_segment3()->get_nouveau_numero()>2)
2346     nonmanifoldarete.ajouter(tripeau->get_segment3());
2347     }
2348     }
2349 picher 233
2350 francois 224 int nbnonmanifoldarete=nonmanifoldarete.get_nb();
2351     for (int i=0;i<nbnonmanifoldarete;i++)
2352     {
2353     MG_SEGMENT* seg=nonmanifoldarete.get(i);
2354     MG_NOEUD* n1=seg->get_noeud1();
2355     MG_NOEUD* n2=seg->get_noeud2();
2356 francois 234 nonmanifoldnoeuddepuisarete.ajouter(n1);
2357     nonmanifoldnoeuddepuisarete.ajouter(n2);
2358 francois 224 }
2359 francois 234 LISTE_MG_NOEUD::iterator itnoeud;
2360     for (MG_NOEUD* no=mai2->get_premier_noeud(itnoeud);no!=NULL;no=mai2->get_suivant_noeud(itnoeud))
2361     {
2362     if (nonmanifoldnoeuddepuisarete.existe(no)) continue;
2363     if (est_non_manifold(no)) nonmanifoldnoeud.ajouter(no);
2364     }
2365 francois 224
2366 francois 457 nbmaniare = nonmanifoldarete.get_nb();
2367     nbmanino = nonmanifoldnoeud.get_nb();
2368 picher 230
2369 francois 457 //etape 8 - Traitement des cas de non manifold
2370     //non manifold par arete
2371 picher 233 for (int i=0;i<nbnonmanifoldarete;i++)
2372     {
2373     MG_SEGMENT* segment=nonmanifoldarete.get(i);
2374 francois 234 MG_NOEUD* noeud1 = mg_mai->get_mg_noeudid(segment->get_noeud1()->get_nouveau_numero());
2375     MG_NOEUD* noeud2 = mg_mai->get_mg_noeudid(segment->get_noeud2()->get_nouveau_numero());
2376     int nb_tetra = noeud1->get_lien_tetra()->get_nb();
2377     for (int j=0;j<nb_tetra;j++)
2378 picher 233 {
2379 francois 234 MG_TETRA* mgtet =noeud1->get_lien_tetra()->get(j);
2380     int originetet=mgtet->get_origine();
2381 francois 791 if (originetet == MAGIC::ORIGINE::MAILLEUR_AUTO)
2382 picher 233 {
2383 francois 457 //On reactive le tetra si l'autre noeud du segment lui appartient aussi
2384 francois 234 MG_NOEUD* no1 = mgtet->get_noeud1();
2385     MG_NOEUD* no2 = mgtet->get_noeud2();
2386     MG_NOEUD* no3 = mgtet->get_noeud3();
2387     MG_NOEUD* no4 = mgtet->get_noeud4();
2388     if((no1 == noeud2) ||(no2 == noeud2) || (no3 == noeud2) || (no4 == noeud2))
2389 francois 791 mgtet->change_origine(MAGIC::ORIGINE::OPTIMISE);
2390 picher 233 }
2391     }
2392     }
2393    
2394     //non manifold par noeud
2395 picher 231 int nbnonmanifoldnoeud=nonmanifoldnoeud.get_nb();
2396     for (int i=0;i<nbnonmanifoldnoeud;i++)
2397     {
2398 francois 234 MG_NOEUD* noeud=mg_mai->get_mg_noeudid(nonmanifoldnoeud.get(i)->get_nouveau_numero());
2399     int nb_tetra = noeud->get_lien_tetra()->get_nb();
2400     for (int j = 0;j<nb_tetra;j++)
2401 francois 345 {
2402 francois 234 MG_TETRA* mgtet =noeud->get_lien_tetra()->get(j);
2403     int originetet=mgtet->get_origine();
2404 francois 791 if (originetet == MAGIC::ORIGINE::MAILLEUR_AUTO)
2405 picher 231 {
2406 francois 791 mgtet->change_origine(MAGIC::ORIGINE::OPTIMISE);
2407 picher 231 }
2408     }
2409     }
2410 francois 234 *mai2_id = mai2->get_id();
2411     if ((nbnonmanifoldarete != 0) || (nbnonmanifoldnoeud != 0))
2412     {
2413     for (int i=0;i<lst_peau.size();i++)
2414     {
2415     delete lst_peau[i];
2416     }
2417     lst_peau.clear();
2418     gest2.supprimer_mg_maillageid(*mai2_id);
2419     return 0;
2420     }
2421 picher 230
2422 francois 234 return 1;
2423 francois 222 }
2424    
2425 francois 457 //---------------------------- Determine peau -------------------------------------------------------------------------
2426 francois 460 void MGOPT_POSTTRAITEMENT::determine_peau(std::vector<MG_TRIANGLE_PEAU*> * peau)
2427 francois 222 {
2428 francois 224 int num=0;
2429     while (num!=peau->size())
2430     {
2431     MG_TRIANGLE_PEAU* p=(*peau)[num];
2432     if (p->get_voisin1()->get_nouveau_numero()==0)
2433     {
2434     peau->push_back(p->get_voisin1());
2435     p->get_voisin1()->change_nouveau_numero(1);
2436     }
2437     if (p->get_voisin2()->get_nouveau_numero()==0)
2438     {
2439     peau->push_back(p->get_voisin2());
2440     p->get_voisin2()->change_nouveau_numero(1);
2441     }
2442     if (p->get_voisin3()->get_nouveau_numero()==0)
2443     {
2444     peau->push_back(p->get_voisin3());
2445     p->get_voisin3()->change_nouveau_numero(1);
2446     }
2447     num++;
2448     }
2449     }
2450    
2451 francois 457 //---------------------------- Insere triangle -------------------------------------------------------------------------
2452 francois 460 MG_TRIANGLE_PEAU* MGOPT_POSTTRAITEMENT::insere_triangle(MG_ELEMENT_TOPOLOGIQUE* topo,class MG_NOEUD *mgnoeud1,class MG_NOEUD *mgnoeud2,class MG_NOEUD *mgnoeud3,MG_MAILLAGE* mg_maillage,int origine)
2453 francois 224 {
2454 francois 222 MG_TRIANGLE_PEAU* voisin1=NULL,*voisin2=NULL,*voisin3=NULL;
2455     MG_SEGMENT* mgsegment1=mg_maillage->get_mg_segment(mgnoeud1->get_id(),mgnoeud2->get_id());
2456     MG_SEGMENT* mgsegment2=mg_maillage->get_mg_segment(mgnoeud2->get_id(),mgnoeud3->get_id());
2457     MG_SEGMENT* mgsegment3=mg_maillage->get_mg_segment(mgnoeud3->get_id(),mgnoeud1->get_id());
2458     if (mgsegment1==NULL)
2459 francois 224 mgsegment1=mg_maillage->ajouter_mg_segment(topo,mgnoeud1,mgnoeud2,origine);
2460 francois 222 if (mgsegment2==NULL)
2461 francois 224 mgsegment2=mg_maillage->ajouter_mg_segment(topo,mgnoeud2,mgnoeud3,origine);
2462 francois 222 if (mgsegment3==NULL)
2463 francois 224 mgsegment3=mg_maillage->ajouter_mg_segment(topo,mgnoeud3,mgnoeud1,origine);
2464     MG_TRIANGLE_PEAU* mtriangle=new MG_TRIANGLE_PEAU(topo,mgnoeud1,mgnoeud2,mgnoeud3,mgsegment1,mgsegment2,mgsegment3,origine);
2465 francois 222 mg_maillage->ajouter_mg_triangle(mtriangle);
2466     return mtriangle;
2467     }
2468    
2469 francois 457 //---------------------------- Recherche voisin -------------------------------------------------------------------------
2470 francois 460 MG_TRIANGLE_PEAU* MGOPT_POSTTRAITEMENT::recherche_voisin(MG_NOEUD* mg_noeud1,MG_NOEUD* mg_noeud2,MG_TRIANGLE_PEAU* triref)
2471 francois 222 {
2472 francois 224 MG_TRIANGLE_PEAU* trisol=NULL;
2473     double angleref=4.*M_PI;
2474 francois 222 int nb1=mg_noeud1->get_lien_triangle()->get_nb();
2475     int nb2=mg_noeud2->get_lien_triangle()->get_nb();
2476     for (int i=0;i<nb1;i++)
2477     for (int j=0;j<nb2;j++)
2478 francois 224 if (mg_noeud1->get_lien_triangle()->get(i)==mg_noeud2->get_lien_triangle()->get(j))
2479     if ((MG_TRIANGLE_PEAU*)mg_noeud1->get_lien_triangle()->get(i)!=triref)
2480     {
2481     double angle=calcul_angle(triref,(MG_TRIANGLE_PEAU*)mg_noeud1->get_lien_triangle()->get(i));
2482     if (angle<angleref)
2483     {
2484     angleref=angle;
2485     trisol=(MG_TRIANGLE_PEAU*)mg_noeud1->get_lien_triangle()->get(i);
2486     }
2487     }
2488     return trisol;
2489 francois 222 }
2490 francois 223
2491 francois 460 int MGOPT_POSTTRAITEMENT::est_non_manifold(MG_NOEUD* no)
2492 francois 234 {
2493     static int compteur=0;
2494     compteur++;
2495     int nb_tri=no->get_lien_triangle()->get_nb();
2496     TPL_MAP_ENTITE<MG_TRIANGLE*> lst;
2497     for (int i=0;i<nb_tri;i++)
2498     lst.ajouter(no->get_lien_triangle()->get(i));
2499     MG_TRIANGLE_PEAU* premier_triangle=(MG_TRIANGLE_PEAU*)lst.get(0);
2500     lst.supprimer(premier_triangle);
2501     MG_TRIANGLE_PEAU* tricour=(MG_TRIANGLE_PEAU*)premier_triangle;
2502     int i=0;
2503     do
2504     {
2505     if (lst.existe(tricour->get_voisin1()) || ((tricour->get_voisin1()==premier_triangle)&& (i>1)))
2506     {
2507     tricour=tricour->get_voisin1();
2508     lst.supprimer(tricour);
2509     }
2510     else if (lst.existe(tricour->get_voisin2()) || ((tricour->get_voisin2()==premier_triangle)&& (i>1)))
2511     {
2512     tricour=tricour->get_voisin2();
2513     lst.supprimer(tricour);
2514     }
2515     else if (lst.existe(tricour->get_voisin3()) || ((tricour->get_voisin3()==premier_triangle)&& (i>1)))
2516     {
2517     tricour=tricour->get_voisin3();
2518     lst.supprimer(tricour);
2519     }
2520     i++;
2521     }
2522     while (tricour!=premier_triangle);
2523     if (lst.get_nb()>0)
2524     return 1;
2525     return 0;
2526     }
2527 francois 224
2528 francois 457 //---------------------------- Calcule angle -------------------------------------------------------------------------
2529 francois 460 double MGOPT_POSTTRAITEMENT::calcul_angle(MG_TRIANGLE_PEAU* ft1,MG_TRIANGLE_PEAU* ft2)
2530 francois 223 {
2531 francois 388 MG_NOEUD* noeud1=ft1->get_noeud1();
2532     MG_NOEUD* noeud2=ft1->get_noeud2();
2533     MG_NOEUD* noeud3=ft1->get_noeud3();
2534     MG_NOEUD* noeud4=ft2->get_noeud1();
2535     MG_NOEUD* noeud5=ft2->get_noeud2();
2536     MG_NOEUD* noeud6=ft2->get_noeud3();
2537     double angle=get_angle_par_noeud<MG_NOEUD*>(noeud1,noeud2,noeud3,noeud4,noeud5,noeud6);
2538     return angle;
2539 francois 223 }
2540 picher 230
2541 francois 457 //---------------------------- Ponderation gaussian -------------------------------------------------------------------------
2542 francois 460 double MGOPT_POSTTRAITEMENT::ponderation_gaussian(double s,double sigma)
2543 picher 230 {
2544     double w_s;
2545     w_s = exp(-(s*s)/(2.*sigma*sigma));
2546     return w_s;
2547     }
2548    
2549 francois 457 //---------------------------- Ponderation Laplacian -------------------------------------------------------------------------
2550 francois 460 double MGOPT_POSTTRAITEMENT::ponderation_laplacian(double s,double sigma)
2551 picher 230 {
2552     double w_s;
2553     w_s = exp(-(sqrt(2.)*fabs(s))/sigma);
2554     return w_s;
2555     }
2556    
2557 francois 457 //---------------------------- Ponderation elfallahford -------------------------------------------------------------------------
2558 francois 460 double MGOPT_POSTTRAITEMENT::ponderation_elfallahford(double s,double sigma)
2559 picher 230 {
2560     double w_s;
2561     w_s = 1./sqrt(1+pow((s/sigma),2));
2562     return w_s;
2563     }