ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/aster/src/mgopt_posttraitement.cpp
Revision: 793
Committed: Tue Mar 29 21:01:55 2016 UTC (9 years, 1 month ago) by francois
File size: 93627 byte(s)
Log Message:
Creation d'une geometrie virtuelle pour la creation d'une peau après une optimisation topologique.
Les triangles deja sur la surface originale sont attachées a une surface virtuelle dans la peau.

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