ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/aster/src/mgopt_posttraitement.cpp
Revision: 792
Committed: Mon Mar 21 21:35:52 2016 UTC (9 years, 1 month ago) by francois
File size: 92706 byte(s)
Log Message:
tag des noeuds pouvant former une arete lors du post traitement de topo_optis
+ noueau visualisateur des ORIGINE qui permet de voir aussi les tag origines des noeuds, GMSH ne le fait pas.

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