ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/aster/src/mgopt_posttraitement.cpp
Revision: 629
Committed: Wed Jan 14 21:25:18 2015 UTC (10 years, 4 months ago) by nana
File size: 89172 byte(s)
Log Message:
Methodologie de lissage

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     if (originetet != MAILLEUR_AUTO)
125     {
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     if (originetet == MAILLEUR_AUTO)
140     {
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     if ((tet1 != mgtet) && (ori1 == MAILLEUR_AUTO)) compteur++;
151     }
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     if ((tet2 != mgtet) && (ori2 == MAILLEUR_AUTO)) compteur++;
158     }
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     if ((tet3 != mgtet) && (ori3 == MAILLEUR_AUTO)) compteur++;
165     }
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     if ((tet4 != mgtet) && (ori4 == MAILLEUR_AUTO)) compteur++;
172     }
173 picher 248 if (compteur == 0) mgtet->change_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     if (tet->get_mg_element_maillage()->get_origine()!=IMPOSE)
198     {
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     if (tet2->get_origine()==IMPOSE)
223     {
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     if (tet2->get_origine()==IMPOSE)
255     {
256     tet2->get_triangle1()->change_origine(IMPOSE);
257     tet2->get_triangle2()->change_origine(IMPOSE);
258     tet2->get_triangle3()->change_origine(IMPOSE);
259     tet2->get_triangle4()->change_origine(IMPOSE);
260     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     if (tri->get_origine()==IMPOSE)
291     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     if (tet->get_mg_element_maillage()->get_origine()!=IMPOSE)
298     {
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     interpole_segment(no1,no2,&tab,limit,mgmai);
305     interpole_segment(no1,no3,&tab,limit,mgmai);
306     interpole_segment(no1,no4,&tab,limit,mgmai);
307     interpole_segment(no2,no3,&tab,limit,mgmai);
308     interpole_segment(no2,no4,&tab,limit,mgmai);
309     interpole_segment(no3,no4,&tab,limit,mgmai);
310     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     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[1],tab[2],mgmai,TRIANGULATION);
322     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     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[1],tab[2],mgmai,TRIANGULATION);
329     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[0],tab[1],tab[3],mgmai,TRIANGULATION);
330     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     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[2],tab[1],mgmai,TRIANGULATION);
336     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[0],tab[2],tab[3],mgmai,TRIANGULATION);
337     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     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[3],tab[1],mgmai,TRIANGULATION);
342     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[0],tab[3],tab[2],mgmai,TRIANGULATION);
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     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[1],tab[2],tab[0],mgmai,TRIANGULATION);
348     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[1],tab[2],tab[3],mgmai,TRIANGULATION);
349     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     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[1],tab[3],tab[0],mgmai,TRIANGULATION);
355     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[1],tab[3],tab[2],mgmai,TRIANGULATION);
356     oriente_tri(tri,noext->get_coord());
357     oriente_tri(tri2,noext->get_coord());}
358     else
359     {
360     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[2],tab[3],tab[0],mgmai,TRIANGULATION);
361     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[2],tab[3],tab[1],mgmai,TRIANGULATION);
362     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     if (num1*num2<0) interpole_segment(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->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->get_fem_noeudid(no2->get_nouveau_numero()),mai->get_fem_noeudid(no3->get_nouveau_numero()),&tab,limit,mgmai);
401     MG_NOEUD* noint=mgfem->get_mg_noeudid(tri->get_nouveau_numero());
402     int nb=tab.size();
403     if (nb==3)
404     {
405     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[1],tab[2],mgmai,IMPOSE);
406     oriente_tri(tri,noint->get_coord());
407     tri->inverse_sens();
408     }
409     if (nb==4)
410     {
411     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[1],tab[2],mgmai,IMPOSE);
412     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[1],tab[2],tab[3],mgmai,IMPOSE);
413     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     if (tri->get_mg_element_maillage()->get_origine()==IMPOSE)
436     {
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     int num1=interpole_segment(no1,no2,&tab,limit,mgmai,0);
441     int num2=interpole_segment(no1,no3,&tab,limit,mgmai,0);
442     int num3=interpole_segment(no2,no3,&tab,limit,mgmai,0);
443     int nb=tab.size();
444     if (nb==0)
445     {
446     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,mgno1,mgno2,mgno3,mgmai,IMPOSE);
447     oriente_tri(tri,xyzext);
448     }
449     if (nb==1)
450     {
451     if (num1==1)
452     {
453     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,mgno1,mgno3,tab[0],mgmai,IMPOSE);
454     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,mgno2,mgno3,tab[0],mgmai,IMPOSE);
455     oriente_tri(tri,xyzext);
456     oriente_tri(tri2,xyzext);
457     }
458     if (num2==1)
459     {
460     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,mgno1,mgno2,tab[0],mgmai,IMPOSE);
461     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,mgno2,mgno3,tab[0],mgmai,IMPOSE);
462     oriente_tri(tri,xyzext);
463     oriente_tri(tri2,xyzext);
464     }
465     if (num3==1)
466     {
467     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,mgno1,mgno2,tab[0],mgmai,IMPOSE);
468     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,mgno1,mgno3,tab[0],mgmai,IMPOSE);
469     oriente_tri(tri,xyzext);
470     oriente_tri(tri2,xyzext);
471     }
472     }
473     if (nb==2)
474     {
475     if (num1==0)
476     {
477     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,mgno1,mgno2,tab[0],mgmai,IMPOSE);
478     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,mgno2,tab[0],tab[1],mgmai,IMPOSE);
479     MG_TRIANGLE_PEAU* tri3=insere_triangle(NULL,mgno3,tab[0],tab[1],mgmai,IMPOSE);
480     oriente_tri(tri,xyzext);
481     oriente_tri(tri2,xyzext);
482     oriente_tri(tri3,xyzext);
483     }
484     if (num2==0)
485     {
486     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,mgno1,mgno3,tab[0],mgmai,IMPOSE);
487     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,mgno3,tab[0],tab[1],mgmai,IMPOSE);
488     MG_TRIANGLE_PEAU* tri3=insere_triangle(NULL,mgno2,tab[0],tab[1],mgmai,IMPOSE);
489     oriente_tri(tri,xyzext);
490     oriente_tri(tri2,xyzext);
491     oriente_tri(tri3,xyzext);
492     }
493     if (num2==0)
494     {
495     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,mgno2,mgno3,tab[0],mgmai,IMPOSE);
496     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,mgno3,tab[0],tab[1],mgmai,IMPOSE);
497     MG_TRIANGLE_PEAU* tri3=insere_triangle(NULL,mgno1,tab[0],tab[1],mgmai,IMPOSE);
498     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     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,mgno1,mgno2,mgno3,mgmai,TRIANGULATION);
510     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     if (num1*num2<0) interpole_segment(no1,no2,&tab,limit,mgmai);
537     if (num1*num3<0) interpole_segment(no1,no3,&tab,limit,mgmai);
538     if (num2*num3<0) interpole_segment(no2,no3,&tab,limit,mgmai);
539     int nb=tab.size();
540     if (nb==3)
541     {
542     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[1],tab[2],mgmai,TRIANGULATION);
543     oriente_tri(tri,xyzext);
544     }
545     if (nb==4)
546     {
547     MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[1],tab[2],mgmai,TRIANGULATION);
548     MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[1],tab[2],tab[3],mgmai,TRIANGULATION);
549     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     if ((*lst_peau[i])[j]->get_origine()==IMPOSE) {isole=0;break;}
604     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     if (tri->get_origine()==IMPOSE)
624     {
625     tri->get_noeud1()->change_origine(IMPOSE);
626     tri->get_noeud2()->change_origine(IMPOSE);
627     tri->get_noeud3()->change_origine(IMPOSE);
628     }
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     mgno=new MG_NOEUD(NULL,no->get_x(),no->get_y(),no->get_z(),TRIANGULATION);
662     mai->ajouter_mg_noeud(mgno);
663     correspond[key]=mgno;
664     }
665     return mgno;
666     }
667    
668    
669 francois 460 int MGOPT_POSTTRAITEMENT::test_du_point_milieu(MG_NOEUD* no1,MG_NOEUD* no2,FEM_ELEMENT3* tet)
670 francois 343 {
671     double *xyz1=no1->get_coord();
672     double *xyz2=no2->get_coord();
673     double xyz[3];
674     xyz[0]=0.5*(xyz1[0]+xyz2[0]);
675     xyz[1]=0.5*(xyz1[1]+xyz2[1]);
676     xyz[2]=0.5*(xyz1[2]+xyz2[2]);
677 francois 412 FEM_MAILLAGE_OUTILS ot;
678 francois 388 if (((ot.estdansletetra(tet,xyz[0],xyz[1],xyz[2])>>1)&1)==1) return 1;
679     //if (((MG_MAILLAGE_OUTILS::estdansletetra(tet,xyz[0],xyz[1],xyz[2])>>1)&1)==1) return 1;
680 francois 343 return 0;
681     }
682    
683    
684    
685 francois 460 int MGOPT_POSTTRAITEMENT::interpole_segment(FEM_NOEUD* no1,FEM_NOEUD* no2,std::vector<MG_NOEUD*> *tab,double limit,MG_MAILLAGE* mai,int creation)
686 francois 343 {
687     static std::map<std::string,MG_NOEUD*> correspond;
688     unsigned long id1=no1->get_id();
689     unsigned long id2=no2->get_id();
690     char message[255];
691     sprintf(message,"_%lu_%lu_",id1,id2);
692     std::string key1=message;
693     sprintf(message,"_%lu_%lu_",id2,id1);
694     std::string key2=message;
695     double sol1=no1->get_solution();
696     double sol2=no2->get_solution();
697 francois 345 if (fabs(sol1-limit)<0.0000001)
698     {
699     sprintf(message,"%lu",id1);
700     std::string key=message;
701     MG_NOEUD* no=correspond[key];
702     if (no==NULL)
703     {
704     double *xyz1=no1->get_coord();
705     no=new MG_NOEUD(NULL,xyz1[0],xyz1[1],xyz1[2],TRIANGULATION);
706     mai->ajouter_mg_noeud(no);
707     correspond[key]=no;
708     }
709     int present=0;
710     for (int i=0;i<tab->size();i++)
711     if ((*tab)[i]==no) present=1;
712     if (present==0)
713     {
714     tab->push_back(no);
715     return 1;
716     }
717     else return 0;
718     }
719     if (fabs(sol2-limit)<0.0000001)
720     {
721     sprintf(message,"%lu",id2);
722     std::string key=message;
723     MG_NOEUD* no=correspond[key];
724     if (no==NULL)
725     {
726     double *xyz2=no2->get_coord();
727     no=new MG_NOEUD(NULL,xyz2[0],xyz2[1],xyz2[2],TRIANGULATION);
728     mai->ajouter_mg_noeud(no);
729     correspond[key]=no;
730     }
731     int present=0;
732     for (int i=0;i<tab->size();i++)
733     if ((*tab)[i]==no) present=1;
734     if (present==0)
735     {
736     tab->push_back(no);
737     return 1;
738     }
739     else return 0;
740    
741     }
742    
743     if (((sol1<limit) && (sol2>limit))||((sol1>limit) && (sol2<limit)))
744 francois 343 {
745     MG_NOEUD* no=correspond[key1];
746     if (no==NULL) no=correspond[key2];
747     if ((no==NULL) && (creation==1))
748     {
749     double t=(limit-sol1)/(sol2-sol1);
750     double xyz[3];
751     double *xyz1=no1->get_coord();
752     double *xyz2=no2->get_coord();
753     xyz[0]=xyz1[0]+t*(xyz2[0]-xyz1[0]);
754     xyz[1]=xyz1[1]+t*(xyz2[1]-xyz1[1]);
755     xyz[2]=xyz1[2]+t*(xyz2[2]-xyz1[2]);
756     no=new MG_NOEUD(NULL,xyz[0],xyz[1],xyz[2],TRIANGULATION);
757     mai->ajouter_mg_noeud(no);
758     correspond[key1]=no;
759     }
760     if (no!=NULL)
761     {
762     tab->push_back(no);
763     return 1;
764     }
765     }
766     return 0;
767     }
768    
769 francois 460 void MGOPT_POSTTRAITEMENT::lire_params(char *fichier)
770 francois 457 {
771     params.lire(fichier);
772     }
773 francois 343
774 francois 461 void MGOPT_POSTTRAITEMENT::posttraite(FEM_SOLUTION* sol, MG_GESTIONNAIRE& gest2,char *nomparam)
775 picher 233 {
776 francois 457 if (nomparam!=NULL) lire_params(nomparam);
777 francois 272 affiche((char*)"Extraction du maillage de surface");
778 francois 457 FEM_MAILLAGE* fem=sol->get_maillage();
779     int decoup=params.get_valeur("decoupage");
780     MG_MAILLAGE* mgmai;
781     if (decoup==0)
782     {
783     affiche((char*)" Découpage par mailles 3D entieres");
784     adapte_seuil(fem,sol);
785     mgmai=extract_skin_maille_entiere(fem,gest2);
786     }
787     if (decoup==1)
788     {
789     affiche((char*)" Découpage par isodensité");
790     double seuil=params.get_valeur("seuil");
791     std::string nomfich=params.get_nom("nomdensextra");
792     mgmai=extract_skin_par_decoupage(sol,seuil,gest2,nomfich.c_str());
793     }
794     suppression_peaux_isoles(mgmai);
795     affiche((char*)"Procedure de lissage");
796     int chen2005_debut=params.get_valeur("chen2005_debut");
797     int chen2008_debut=params.get_valeur("chen2008_debut");
798     int jiao2012_debut=params.get_valeur("jiao2012_debut");
799 nana 629 int nana2015_debut=params.get_valeur("nana2015_debut");
800 francois 457 int chen2005fait=0;
801     if (chen2005_debut==0) chen2005fait=1;
802     int chen2008fait=0;
803     if (chen2008_debut==0) chen2008fait=1;
804     int jiao2012fait=0;
805     if (jiao2012_debut==0) jiao2012fait=1;
806 nana 629 int nana2015fait=0;
807     if (nana2015_debut==0) nana2015fait=1;
808 francois 457 int fin=0;
809     int iteration=1;
810     do
811     {
812     if ((iteration>=chen2005_debut) && (chen2005fait==0))
813     {
814     char message[300];
815     sprintf(message, " Iteration %d : lissage de Chen 2005",iteration);
816     affiche(message);
817     double epsilon=params.get_valeur("chen2005_epsilon");
818     double sigma=params.get_valeur("chen2005_sigma");
819     int iter_max=params.get_valeur("chen2005_itermax");
820     int nbiter=lissage_chen2005(mgmai,gest2,epsilon,sigma,iter_max);
821     if (nbiter==iter_max) sprintf(message," Arrêt de la procédure de lissage de Chen2005 après %d itérations",nbiter);
822     else sprintf(message," Convergence de la procédure de lissage de Chen2005 après %d itérations",nbiter);
823     affiche(message);
824     chen2005fait=1;
825     iteration=iteration+nbiter;
826     }
827     else if ((iteration>=chen2008_debut) && (chen2008fait==0))
828     {
829     char message[300];
830     sprintf(message, " Iteration %d : lissage de Chen 2008",iteration);
831     affiche(message);
832     double epsilon=params.get_valeur("chen2008_epsilon");
833     double sigma=params.get_valeur("chen2008_sigma");
834     double gamma=params.get_valeur("chen2008_gamma");
835     int iter_max=params.get_valeur("chen2008_itermax");
836     int nbiter=lissage_chen2008(mgmai,gest2,sigma,gamma,epsilon,iter_max);
837     if (nbiter==iter_max) sprintf(message," Arrêt de la procédure de lissage de Chen2008 après %d itérations",nbiter);
838     else sprintf(message," Convergence de la procédure de lissage de Chen2008 après %d itérations",nbiter);
839     affiche(message);
840     chen2008fait=1;
841     iteration=iteration+nbiter;
842     }
843     else if ((iteration>=jiao2012_debut) && (jiao2012fait==0))
844     {
845     char message[300];
846     sprintf(message, " Iteration %d : lissage de Jiao 2012",iteration);
847     affiche(message);
848     int iter_max=params.get_valeur("jiao2012_itermax");
849     int nbiter=lissage_jiao2012(mgmai,gest2,iter_max);
850     if (nbiter==iter_max) sprintf(message," Arrêt de la procédure de lissage de Jiao2012 après %d itérations",nbiter);
851     else sprintf(message," Convergence de la procédure de lissage de Jiao2012 après %d itérations",nbiter);
852     affiche(message);
853     jiao2012fait=1;
854     iteration=iteration+nbiter;
855     }
856 nana 629 else if ((iteration>=nana2015_debut) && (nana2015fait==0))
857     {
858     char message[300];
859     sprintf(message, " Iteration %d : lissage de Nana 2015",iteration);
860     affiche(message);
861     int iter_max=params.get_valeur("nana2015_itermax");
862     int nbiter=lissage_nana2015(mgmai,gest2,iter_max);
863     if (nbiter==iter_max) sprintf(message," Arrêt de la procédure de lissage de nana2015 après %d itérations",nbiter);
864     else sprintf(message," Convergence de la procédure de lissage de nana2015 après %d itérations",nbiter);
865     affiche(message);
866     nana2015fait=1;
867     iteration=iteration+nbiter;
868     }
869 francois 457 else iteration++;
870     if (chen2005fait==1)
871     if (chen2008fait==1)
872     if (jiao2012fait==1)
873 nana 629 if (nana2015fait==1)
874     fin=1;
875 francois 457 }
876     while (fin==0);
877     }
878    
879    
880 francois 460 MG_MAILLAGE* MGOPT_POSTTRAITEMENT::extract_skin_maille_entiere(FEM_MAILLAGE* mai,MG_GESTIONNAIRE &gest2)
881 francois 457 {
882     //Menu de la methode de lissage
883     affiche((char*)"Extraction du maillage de surface");
884 picher 231 int coderesu = 0;
885 picher 233 int mai2_id;
886 francois 457 int imp=params.get_valeur("consimpose");
887     int opti=params.get_valeur("consoptimise");
888     int m_auto=params.get_valeur("consnooptimise");
889 francois 232 if (opti==1) conserve(OPTIMISE);
890     if (imp==1) conserve(IMPOSE);
891 picher 233 if (m_auto==1) conserve(MAILLEUR_AUTO);
892 francois 457 copieorigine(mai);
893 picher 233 MG_MAILLAGE* mg_mai = (MG_MAILLAGE*)mai->get_mg_maillage();
894 francois 457 //gain_poids(mg_mai,gest2);
895     int reactiv=params.get_valeur("reactivation");
896 picher 233 if (reactiv == 1)
897     {
898     reactivation(mg_mai,gest2);
899     }
900 francois 457 affiche((char*)" Analyse des cas non manifold");
901 picher 231 do
902     {
903 francois 457 int nbmaniare,nbmanino,nbpeau;
904     coderesu = extract_skin(mg_mai,gest2,nbpeau,nbmaniare,nbmanino,&mai2_id);
905     char message[500];
906     sprintf(message," %d peaux. %d manifold par arete. %d manifold par noeud",nbpeau,nbmaniare,nbmanino);
907     affiche(message);
908     // gain_poids(mg_mai,gest2);
909 picher 231 }
910     while (coderesu == 0);
911 picher 233
912     MG_MAILLAGE* mg_mai2=gest2.get_mg_maillageid(mai2_id);
913 francois 457
914     return mg_mai2;
915    
916 picher 231 }
917    
918 nana 629
919 francois 460 void MGOPT_POSTTRAITEMENT::adapte_seuil(class FEM_MAILLAGE* fem,FEM_SOLUTION* solution)
920 picher 230 {
921 francois 457 double seuil=params.get_valeur("seuil");
922     solution->active_solution(0);
923     LISTE_FEM_ELEMENT3::iterator it;
924     for (FEM_ELEMENT3 *tet=fem->get_premier_element3(it);tet!=NULL;tet=fem->get_suivant_element3(it))
925 picher 230 {
926 francois 457 if (((MG_TETRA*)tet->get_mg_element_maillage())->get_origine()!=IMPOSE)
927     if (tet->get_solution()>seuil)
928     ((MG_TETRA*)tet->get_mg_element_maillage())->change_origine(OPTIMISE);
929     else
930     ((MG_TETRA*)tet->get_mg_element_maillage())->change_origine(MAILLEUR_AUTO);
931    
932 picher 230 }
933     }
934 francois 224
935 francois 457
936     //---------------------------- Lissage Chen 2005 Gilles Philippe -------------------------------------------------------------------------
937 francois 460 int MGOPT_POSTTRAITEMENT::lissage_chen2005(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, double epsilon, double sigma, int iter_max)
938 picher 230 {
939 francois 457 //Methode de lissage inspiree de Chen(2005) par Gilles Philipe Picher Martel
940 picher 230 double un_sur_pi = 1./M_PI;
941     int compteur = 0;
942     int fin = 0;
943 francois 224
944 francois 457
945 picher 230 do
946     {
947     TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales;
948 picher 233 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales2;
949 picher 230 TPL_LISTE_ENTITE<double> liste_wij;
950     LISTE_MG_TRIANGLE::iterator it_tri;
951     int k = 0; //pour identifier les triangles pour liste_normales et liste_wij
952     for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
953     {
954     MG_TRIANGLE_PEAU* mgtri_i = (MG_TRIANGLE_PEAU*)mgtri;
955     OT_VECTEUR_3D normal_f_i = mgtri_i->calcul_normal();
956 picher 233 normal_f_i.norme();
957     liste_normales2.ajouter(normal_f_i);
958 picher 230 //Remplissage de la liste des voisins du triangle i
959     TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*> liste_voisins;
960     MG_NOEUD* noeud1 = mgtri_i->get_noeud1();
961     double nb_voisins1 = noeud1->get_lien_triangle()->get_nb();
962     for (int j = 0;j<nb_voisins1;j++)
963     {
964     MG_TRIANGLE_PEAU* mgtri_1 = (MG_TRIANGLE_PEAU*) noeud1->get_lien_triangle()->get(j);
965     liste_voisins.ajouter(mgtri_1);
966     }
967     MG_NOEUD* noeud2 = mgtri_i->get_noeud2();
968     double nb_voisins2 = noeud2->get_lien_triangle()->get_nb();
969     for (int j = 0;j<nb_voisins2;j++)
970     {
971     MG_TRIANGLE_PEAU* mgtri_2 = (MG_TRIANGLE_PEAU*) noeud2->get_lien_triangle()->get(j);
972     liste_voisins.ajouter(mgtri_2);
973     }
974     MG_NOEUD* noeud3 = mgtri_i->get_noeud3();
975     double nb_voisins3 = noeud3->get_lien_triangle()->get_nb();
976     for (int j = 0;j<nb_voisins3;j++)
977     {
978     MG_TRIANGLE_PEAU* mgtri_3 = (MG_TRIANGLE_PEAU*) noeud3->get_lien_triangle()->get(j);
979     liste_voisins.ajouter(mgtri_3);
980     }
981     liste_voisins.supprimer(mgtri_i);
982     int nb_voisins = liste_voisins.get_nb();
983     double w_ij = 1./nb_voisins;
984     double phi_i_min = 10.;
985     double s_i = 0.0;
986     double phi_im = 0.0;
987 picher 231 double *phi_ij = new double[nb_voisins];
988 picher 230 OT_VECTEUR_3D normal_f_i_mean(0.,0.,0.);
989     OT_VECTEUR_3D eta_i(0.,0.,0.);
990     TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*>::ITERATEUR it;
991     int j = 0;
992     for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
993     {
994     OT_VECTEUR_3D normal_f_j = mgtri_j->calcul_normal();
995     //1-Calculer la normale moyenne pour chaque triangle
996     normal_f_i_mean = normal_f_i_mean + w_ij*normal_f_j;
997 francois 457 //2.1-On calcul l'angle entre normal_f_i et normal_f_j pour j allant de 1 a Nb_voisins
998 picher 230 double prod_scalaire = normal_f_i*normal_f_j;
999 picher 233 if (prod_scalaire > 1.)
1000     {
1001     prod_scalaire = 1.;
1002     }
1003     if (prod_scalaire < -1.)
1004     {
1005     prod_scalaire = -1.;
1006     }
1007 picher 230 phi_ij[j] = acos(prod_scalaire)*un_sur_pi;
1008     //2.2-On trouve le plus petit des angles et la normale heta_i correspondante
1009     if (phi_ij[j] < phi_i_min)
1010     {
1011     phi_i_min = phi_ij[j];
1012     eta_i = normal_f_j;
1013     }
1014     //3.1-On calcul l'angle moyen phi_im
1015     phi_im = phi_im + w_ij*phi_ij[j];
1016     j++;
1017     }
1018     normal_f_i_mean.norme();
1019     j = 0;
1020     for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
1021     {
1022     //3.2-Calcul de s_i selon la variance
1023     s_i = s_i + w_ij*pow((phi_ij[j] - phi_im),2);
1024     j++;
1025     }
1026 picher 231 delete[] phi_ij;
1027 picher 230 //4-On calcule une nouvelle normale pour chaque triangle
1028 francois 458 double pond;
1029     int num=params.get_valeur("chen2005_filtre");
1030     if (num==1) pond=ponderation_gaussian(s_i,sigma);
1031     else if (num==2) pond=ponderation_laplacian(s_i,sigma);
1032     else if (num==3) pond=ponderation_elfallahford(s_i,sigma);
1033     OT_VECTEUR_3D normal_f_i_new = pond*normal_f_i_mean + (1. - pond)*eta_i;
1034 picher 230 normal_f_i_new.norme();
1035     liste_normales.ajouter(normal_f_i_new);
1036     liste_wij.ajouter(w_ij);
1037     mgtri->change_nouveau_numero(k);
1038     k++;
1039     }
1040    
1041     LISTE_MG_NOEUD::iterator it_no;
1042     for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1043     {
1044     int nb_voisins_j = noeud_i->get_lien_triangle()->get_nb();
1045     double w_ij_prime = 0.0;
1046     OT_VECTEUR_3D v_temp(0.,0.,0.);
1047     OT_VECTEUR_3D v_i(noeud_i->get_x(),noeud_i->get_y(),noeud_i->get_z());
1048     for(int j=0;j<nb_voisins_j;j++)
1049     {
1050     MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
1051 francois 457 //On calcule le centroide cj du triangle mgtri_j
1052 picher 230 MG_NOEUD* n1 = mgtri_j->get_noeud1();
1053     MG_NOEUD* n2 = mgtri_j->get_noeud2();
1054     MG_NOEUD* n3 = mgtri_j->get_noeud3();
1055     double cj_x = 0.333333333333333*(n1->get_x() + n2->get_x() + n3->get_x());
1056     double cj_y = 0.333333333333333*(n1->get_y() + n2->get_y() + n3->get_y());
1057     double cj_z = 0.333333333333333*(n1->get_z() + n2->get_z() + n3->get_z());
1058     //On forme le vecteur vi_cj
1059     OT_VECTEUR_3D vi_cj(cj_x - noeud_i->get_x(),cj_y - noeud_i->get_y(),cj_z - noeud_i->get_z());
1060     OT_VECTEUR_3D normal_f_i_new = liste_normales.get(mgtri_j->get_nouveau_numero());
1061 francois 457 // w_ij_prime correspond a la somme des aires des triangles voisins du noeuds
1062 picher 233 OT_VECTEUR_3D AB(n2->get_x() - n1->get_x(),n2->get_y() - n1->get_y(),n2->get_z() - n1->get_z());
1063     OT_VECTEUR_3D AC(n3->get_x() - n1->get_x(),n3->get_y() - n1->get_y(),n3->get_z() - n1->get_z());
1064     OT_VECTEUR_3D prodvect = AB&AC;
1065     double w_ij = 0.5*prodvect.get_longueur();
1066 picher 230 w_ij_prime = w_ij_prime + w_ij;
1067     v_temp = v_temp + w_ij*(vi_cj*normal_f_i_new)*normal_f_i_new;
1068     }
1069 francois 457 //5-On met a jour la position des noeuds
1070 picher 230 v_i = v_i + v_temp/w_ij_prime;
1071 picher 233 int origine = noeud_i->get_origine();
1072     if (origine != IMPOSE)
1073     {
1074     noeud_i->change_x(v_i.get_x());
1075     noeud_i->change_y(v_i.get_y());
1076     noeud_i->change_z(v_i.get_z());
1077     }
1078 picher 230 }
1079 francois 457 //Critere d'arret de l'algorithme
1080 picher 230 int l=0;
1081     int nb_tri = mg_mai->get_nb_mg_triangle();
1082     for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
1083     {
1084     MG_TRIANGLE_PEAU* mgtri_i = (MG_TRIANGLE_PEAU*)mgtri;
1085 picher 233 OT_VECTEUR_3D normal_f_i = liste_normales2.get(mgtri_i->get_nouveau_numero());
1086 picher 230 OT_VECTEUR_3D normal_f_i_new = liste_normales.get(mgtri_i->get_nouveau_numero());
1087 picher 248 double critere = 1. - normal_f_i*normal_f_i_new;
1088 picher 230 if (critere <= epsilon) l++;
1089     }
1090 picher 248 double tolerance = 0.01*nb_tri;
1091     if (nb_tri - l <= 0) fin = 1;
1092 picher 230 compteur++;
1093     }
1094     while ((fin == 0) && (compteur < iter_max));
1095    
1096 francois 457 return compteur;
1097     }
1098 picher 230
1099 francois 457 //---------------------------- Lissage Jiao 2012 -------------------------------------------------------------------------
1100 francois 460 int MGOPT_POSTTRAITEMENT::lissage_jiao2012(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, int iter_max)
1101 picher 248 {
1102 francois 457 // Lissage global avec methode de lissage inspiree de JIAO IMR2012 par Jean Christophe sept 2013
1103 picher 248 int compteur = 0;
1104    
1105 cuillier 438 do
1106     {
1107     vector<double> nouv_position_x;
1108     vector<double> nouv_position_y;
1109     vector<double> nouv_position_z;
1110     LISTE_MG_NOEUD::iterator it_no;
1111     for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1112     {
1113     int origine = noeud_i->get_origine();
1114 nana 629 if (origine != IMPOSE)
1115 cuillier 438 {
1116     int nb_voisins_j = noeud_i->get_lien_triangle()->get_nb();
1117     double wij = 0.0;
1118     double wij_sommej = 0.0;
1119     OT_VECTEUR_3D v_temp(0.,0.,0.);
1120     OT_VECTEUR_3D v_i(noeud_i->get_x(),noeud_i->get_y(),noeud_i->get_z());
1121     for(int j=0;j<nb_voisins_j;j++)
1122     {
1123     MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
1124 francois 457 //On calcule le centroide cj du triangle mgtri_j
1125 cuillier 438 MG_NOEUD* n1 = mgtri_j->get_noeud1();
1126     MG_NOEUD* n2 = mgtri_j->get_noeud2();
1127     MG_NOEUD* n3 = mgtri_j->get_noeud3();
1128     double cj_x = 0.333333333333333*(n1->get_x() + n2->get_x() + n3->get_x());
1129     double cj_y = 0.333333333333333*(n1->get_y() + n2->get_y() + n3->get_y());
1130     double cj_z = 0.333333333333333*(n1->get_z() + n2->get_z() + n3->get_z());
1131     //On forme le vecteur vi_cj et le vecteur cj
1132     OT_VECTEUR_3D cj(cj_x ,cj_y,cj_z);
1133     OT_VECTEUR_3D vi_cj(cj_x - noeud_i->get_x(),cj_y - noeud_i->get_y(),cj_z - noeud_i->get_z());
1134     wij=vi_cj.get_longueur();
1135     wij_sommej=wij_sommej+wij;
1136     v_temp = v_temp + (wij*cj);
1137     }
1138     //5-On calcule la nouvelle position des noeuds et on affecte au tableau temporaire
1139     v_i =v_temp/wij_sommej;
1140     nouv_position_x.push_back(v_i.get_x());
1141     nouv_position_y.push_back(v_i.get_y());
1142     nouv_position_z.push_back(v_i.get_z());
1143     }
1144     }
1145     //On actualise la position des noeuds
1146     int ind_noeud=0;
1147     for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1148     {
1149     int origine = noeud_i->get_origine();
1150 nana 629 if (origine != IMPOSE)
1151 cuillier 438 {
1152     noeud_i->change_x(nouv_position_x[ind_noeud]);
1153     noeud_i->change_y(nouv_position_y[ind_noeud]);
1154     noeud_i->change_z(nouv_position_z[ind_noeud]);
1155     ind_noeud++;
1156     }
1157     }
1158     //Critere d'arret de l'algorithme
1159     compteur++;
1160     }
1161     while (compteur < iter_max);
1162    
1163 francois 457 return compteur;
1164 cuillier 438 }
1165    
1166 francois 457 //---------------------------- Lissage Chen 2008 -------------------------------------------------------------------------
1167 francois 460 int MGOPT_POSTTRAITEMENT::lissage_chen2008(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, double sigma, double gamma, double epsilon, int iter_max)
1168 cuillier 438 {
1169 francois 457 //Lissage global inspire de Chen(2008) corrige par Jean Christophe sept 2013
1170 cuillier 438 double un_sur_pi = 1./M_PI;
1171     int compteur = 0;
1172     int fin = 0;
1173 francois 457 compteur = 0;
1174 cuillier 438
1175     do
1176     {
1177     vector<double> nouv_position_x;
1178     vector<double> nouv_position_y;
1179     vector<double> nouv_position_z;
1180     TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales;
1181     TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales2;
1182     TPL_LISTE_ENTITE<double> liste_wij;
1183     LISTE_MG_TRIANGLE::iterator it_tri;
1184     int k = 0; //pour identifier les triangles pour liste_normales et liste_wij
1185     for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
1186     {
1187     MG_TRIANGLE_PEAU* mgtri_i = (MG_TRIANGLE_PEAU*)mgtri;
1188     OT_VECTEUR_3D normal_f_i = mgtri_i->calcul_normal();
1189     normal_f_i.norme();
1190     liste_normales2.ajouter(normal_f_i);
1191     //Remplissage de la liste des voisins du triangle i
1192     TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*> liste_voisins;
1193     MG_NOEUD* noeud1 = mgtri_i->get_noeud1();
1194     double nb_voisins1 = noeud1->get_lien_triangle()->get_nb();
1195     for (int j = 0;j<nb_voisins1;j++)
1196     {
1197     MG_TRIANGLE_PEAU* mgtri_1 = (MG_TRIANGLE_PEAU*) noeud1->get_lien_triangle()->get(j);
1198     liste_voisins.ajouter(mgtri_1);
1199     }
1200     MG_NOEUD* noeud2 = mgtri_i->get_noeud2();
1201     double nb_voisins2 = noeud2->get_lien_triangle()->get_nb();
1202     for (int j = 0;j<nb_voisins2;j++)
1203     {
1204     MG_TRIANGLE_PEAU* mgtri_2 = (MG_TRIANGLE_PEAU*) noeud2->get_lien_triangle()->get(j);
1205     liste_voisins.ajouter(mgtri_2);
1206     }
1207     MG_NOEUD* noeud3 = mgtri_i->get_noeud3();
1208     double nb_voisins3 = noeud3->get_lien_triangle()->get_nb();
1209     for (int j = 0;j<nb_voisins3;j++)
1210     {
1211     MG_TRIANGLE_PEAU* mgtri_3 = (MG_TRIANGLE_PEAU*) noeud3->get_lien_triangle()->get(j);
1212     liste_voisins.ajouter(mgtri_3);
1213     }
1214     liste_voisins.supprimer(mgtri_i);
1215     int nb_voisins = liste_voisins.get_nb();
1216     double w_ij = 1./nb_voisins;
1217     double phi_i_min = 10.;
1218     double s_i = 0.0;
1219     double phi_im = 0.0;
1220     double *phi_ij = new double[nb_voisins];
1221     OT_VECTEUR_3D normal_f_i_mean(0.,0.,0.);
1222     normal_f_i_mean = normal_f_i;
1223     OT_VECTEUR_3D eta_i(0.,0.,0.);
1224     TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*>::ITERATEUR it;
1225     int j = 0;
1226     for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
1227     {
1228     OT_VECTEUR_3D normal_f_j = mgtri_j->calcul_normal();
1229     //1-Calculer la normale moyenne pour chaque triangle
1230     normal_f_i_mean = normal_f_i_mean + normal_f_j;
1231 francois 457 //2.1-On calcule l'angle entre normal_f_i et normal_f_j pour j allant de 1 a Nb_voisins
1232 cuillier 438 double prod_scalaire = normal_f_i*normal_f_j;
1233     if (prod_scalaire > 1.)
1234     {
1235     prod_scalaire = 1.;
1236     }
1237     if (prod_scalaire < -1.)
1238     {
1239     prod_scalaire = -1.;
1240     }
1241     phi_ij[j] = acos(prod_scalaire)*un_sur_pi;
1242     //2.2-On trouve le plus petit des angles et la normale heta_i correspondante
1243     if (phi_ij[j] < phi_i_min)
1244     {
1245     phi_i_min = phi_ij[j];
1246     eta_i = normal_f_j;
1247     }
1248 francois 457 //3.1-On calcule l'angle moyen phi_im
1249 cuillier 438 phi_im = phi_im + w_ij*phi_ij[j];
1250     j++;
1251     }
1252     normal_f_i_mean.norme();
1253     j = 0;
1254     for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
1255     {
1256     //3.2-Calcul de s_i selon la variance
1257     s_i = s_i + w_ij*pow((phi_ij[j] - phi_im),2);
1258     j++;
1259     }
1260     delete[] phi_ij;
1261     //4-On calcule une nouvelle normale pour chaque triangle
1262 francois 458 double pond;
1263     int num=params.get_valeur("chen2008_filtre");
1264     if (num==1) pond=ponderation_gaussian(s_i,sigma);
1265     else if (num==2) pond=ponderation_laplacian(s_i,sigma);
1266     else if (num==3) pond=ponderation_elfallahford(s_i,sigma);
1267     OT_VECTEUR_3D normal_f_i_new = pond*normal_f_i_mean + (1. - pond)*eta_i;
1268 cuillier 438 normal_f_i_new.norme();
1269     liste_normales.ajouter(normal_f_i_new);
1270     liste_wij.ajouter(w_ij);
1271     mgtri->change_nouveau_numero(k);
1272     k++;
1273     }
1274    
1275     LISTE_MG_NOEUD::iterator it_no;
1276     for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1277     {
1278     int origine = noeud_i->get_origine();
1279     if (origine != IMPOSE)
1280     {
1281     int nb_voisins_j = noeud_i->get_lien_triangle()->get_nb();
1282     double w_ij_prime = 0.0;
1283     OT_VECTEUR_3D v_temp(0.,0.,0.);
1284     OT_VECTEUR_3D v_i(noeud_i->get_x(),noeud_i->get_y(),noeud_i->get_z());
1285     for(int j=0;j<nb_voisins_j;j++)
1286     {
1287     MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
1288 francois 457 //On calcule le centroide cj du triangle mgtri_j
1289 cuillier 438 MG_NOEUD* n1 = mgtri_j->get_noeud1();
1290     MG_NOEUD* n2 = mgtri_j->get_noeud2();
1291     MG_NOEUD* n3 = mgtri_j->get_noeud3();
1292     double cj_x = 0.333333333333333*(n1->get_x() + n2->get_x() + n3->get_x());
1293     double cj_y = 0.333333333333333*(n1->get_y() + n2->get_y() + n3->get_y());
1294     double cj_z = 0.333333333333333*(n1->get_z() + n2->get_z() + n3->get_z());
1295     //On forme le vecteur vi_cj
1296     OT_VECTEUR_3D vi_cj(cj_x - noeud_i->get_x(),cj_y - noeud_i->get_y(),cj_z - noeud_i->get_z());
1297     OT_VECTEUR_3D normal_f_i_new = liste_normales.get(mgtri_j->get_nouveau_numero());
1298     v_temp = v_temp + (vi_cj*normal_f_i_new)*normal_f_i_new;
1299     }
1300 francois 457 //5-On met a jour la position des noeuds
1301 cuillier 438 v_i = v_i + (gamma/(2*nb_voisins_j))*v_temp;
1302     nouv_position_x.push_back(v_i.get_x());
1303     nouv_position_y.push_back(v_i.get_y());
1304     nouv_position_z.push_back(v_i.get_z());
1305     }
1306     }
1307    
1308     //On actualise la position des noeuds
1309     int ind_noeud=0;
1310     for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1311     {
1312     int origine = noeud_i->get_origine();
1313 nana 629 if (origine != IMPOSE)
1314 cuillier 438 {
1315     noeud_i->change_x(nouv_position_x[ind_noeud]);
1316     noeud_i->change_y(nouv_position_y[ind_noeud]);
1317     noeud_i->change_z(nouv_position_z[ind_noeud]);
1318     ind_noeud++;
1319     }
1320     }
1321    
1322     //Critere d'arret de l'algorithme
1323     int l=0;
1324     int nb_tri = mg_mai->get_nb_mg_triangle();
1325     for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
1326     {
1327     MG_TRIANGLE_PEAU* mgtri_i = (MG_TRIANGLE_PEAU*)mgtri;
1328     OT_VECTEUR_3D normal_f_i = liste_normales2.get(mgtri_i->get_nouveau_numero());
1329     OT_VECTEUR_3D normal_f_i_new = liste_normales.get(mgtri_i->get_nouveau_numero());
1330     double critere = 1. - normal_f_i*normal_f_i_new;
1331 picher 248 if (critere <= epsilon) l++;
1332     }
1333     double tolerance = 0.01*nb_tri;
1334     if (nb_tri - l <= 0) fin = 1;
1335     compteur++;
1336     }
1337     while ((fin == 0) && (compteur < iter_max));
1338    
1339 francois 457 return compteur;
1340    
1341 picher 248 }
1342    
1343 cuillier 438
1344 nana 629 //---------------------------- Lissage Nana 2015 -------------------------------------------------------------------------
1345     int MGOPT_POSTTRAITEMENT::lissage_nana2015(MG_MAILLAGE* mg_mai, MG_GESTIONNAIRE& gest2, int iter_max)
1346     {
1347     // Lissage par la methode Nana(2015) par Alexandre Nana janvier 2015
1348     int fin = 0;
1349     int compteur = 0;
1350    
1351     /// Calcul du volume initial
1352     double d1=0.;
1353     double v1=0.;
1354     LISTE_MG_TRIANGLE::iterator it;
1355     for (MG_TRIANGLE* ttr=mg_mai->get_premier_triangle(it);ttr!=NULL;ttr=mg_mai->get_suivant_triangle(it))
1356     {
1357     MG_TRIANGLE_PEAU* tri=(MG_TRIANGLE_PEAU*)ttr;
1358     if(tri->get_origine()!=MAILLEUR_AUTO)
1359     {
1360     MG_NOEUD* no1=tri->get_noeud1();
1361     MG_NOEUD* no2=tri->get_noeud2();
1362     MG_NOEUD* no3=tri->get_noeud3();
1363     double *xyz1=no1->get_coord();
1364     double *xyz2=no2->get_coord();
1365     double *xyz3=no3->get_coord();
1366     OT_VECTEUR_3D vec1(xyz1,xyz2);
1367     OT_VECTEUR_3D vec2(xyz1,xyz3);
1368     OT_VECTEUR_3D pvec=vec2&vec1;
1369    
1370     d1=pvec.get_longueur(); // En fait surface=pvec.get_longueur()/2. et det=2*surface
1371     OT_VECTEUR_3D N=pvec/(pvec.get_longueur());
1372     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}
1373     +(xyz1+(2/3.)*vec1+(1/6.)*vec2)
1374     +(xyz1+(1/6.)*vec1+(2/3.)*vec2));
1375     v1=v1+d1*N*F;
1376     }
1377     }
1378     cout << "Volume avant lissage = " << v1 << endl;
1379    
1380    
1381     /// detection du "bruit"
1382     double kM1=0.;
1383     double km1=0.;
1384     TPL_MAP_ENTITE<MG_NOEUD*> liste_nodes_bruit;
1385     TPL_MAP_ENTITE<MG_NOEUD*> liste_nodes_non_modifies;
1386     TPL_MAP_ENTITE<MG_NOEUD*> liste_nodes_aretes_vives;
1387     TPL_MAP_ENTITE<MG_NOEUD*>::ITERATEUR inode;
1388     TPL_MAP_ENTITE<MG_NOEUD*>::ITERATEUR inode2;
1389     TPL_MAP_ENTITE<MG_NOEUD*>::ITERATEUR inode3;
1390    
1391    
1392     LISTE_MG_NOEUD::iterator it_no;
1393     for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1394     {
1395     if ((noeud_i->get_origine() != IMPOSE))
1396     {
1397     TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*> liste_map_triangle;
1398     TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*>::ITERATEUR it;
1399     TPL_LISTE_ENTITE<MG_TRIANGLE_PEAU*> liste_tpl_triangle;
1400    
1401     for (int k=0;k<noeud_i->get_lien_triangle()->get_nb();k++)
1402     {
1403     MG_TRIANGLE_PEAU* tri1= (MG_TRIANGLE_PEAU*)noeud_i->get_lien_triangle()->get(k);
1404     liste_map_triangle.ajouter(tri1);
1405     }
1406    
1407     MG_TRIANGLE_PEAU* tri2=liste_map_triangle.get_premier(it);
1408     MG_NOEUD* na=tri2->get_noeud1();
1409     MG_NOEUD* nb=tri2->get_noeud2();
1410     MG_NOEUD* nc=tri2->get_noeud3();
1411     MG_NOEUD* n1=NULL;
1412     MG_NOEUD* n2=NULL;
1413     MG_NOEUD* n3=NULL;
1414    
1415     if (na==noeud_i) {n1=na;n2=nb;n3=nc;}
1416     if (nb==noeud_i) {n1=nb;n2=nc;n3=na;}
1417     if (nc==noeud_i) {n1=nc;n2=na;n3=nb;}
1418    
1419     liste_tpl_triangle.ajouter(tri2);
1420    
1421     while (liste_map_triangle.get_nb()!=liste_tpl_triangle.get_nb())
1422     for (MG_TRIANGLE_PEAU* tri=liste_map_triangle.get_premier(it);tri;tri=liste_map_triangle.get_suivant(it))
1423     {
1424     if (tri!=tri2)
1425     {
1426     MG_NOEUD* noa=tri->get_noeud1();
1427     MG_NOEUD* nob=tri->get_noeud2();
1428     MG_NOEUD* noc=tri->get_noeud3();
1429     MG_NOEUD* n4=NULL;
1430     MG_NOEUD* n5=NULL;
1431     MG_NOEUD* n6=NULL;
1432    
1433     if (noa==noeud_i) {n4=noa;n5=nob;n6=noc;}
1434     if (nob==noeud_i) {n4=nob;n5=noc;n6=noa;}
1435     if (noc==noeud_i) {n4=noc;n5=noa;n6=nob;}
1436    
1437     if (n1==n4)
1438     if (n3==n5)
1439     {
1440     liste_tpl_triangle.ajouter(tri);
1441     n1=n4;
1442     n2=n5;
1443     n3=n6;
1444     if (liste_map_triangle.get_nb()==liste_tpl_triangle.get_nb()) break;
1445     }
1446     }
1447     }
1448    
1449     double K=0.;
1450     double H=0.;
1451    
1452     double beta=0.;
1453     double surface=0.;
1454     double som1=0.;
1455     double som2=0.;
1456     double som3=0.;
1457     double som4=0.;
1458    
1459     for (int i=0;i<liste_tpl_triangle.get_nb();i++)
1460     {
1461     MG_TRIANGLE_PEAU* tri00=NULL;
1462     MG_TRIANGLE_PEAU* tri01=NULL;
1463    
1464     if (!(i==(liste_tpl_triangle.get_nb()-1))) {tri00=liste_tpl_triangle.get(i);tri01=liste_tpl_triangle.get(i+1);}
1465     if (i==(liste_tpl_triangle.get_nb()-1)) {tri00=liste_tpl_triangle.get(i);tri01=tri2;}
1466    
1467     MG_NOEUD* noeud1=NULL;
1468     MG_NOEUD* noeud2=NULL;
1469     MG_NOEUD* noeud3=NULL;
1470     MG_NOEUD* noeud4=NULL;
1471     MG_NOEUD* noeud5=NULL;
1472     MG_NOEUD* noeud6=NULL;
1473    
1474     MG_NOEUD* nd1=tri00->get_noeud1();
1475     MG_NOEUD* nd2=tri00->get_noeud2();
1476     MG_NOEUD* nd3=tri00->get_noeud3();
1477     MG_NOEUD* nd4=tri01->get_noeud1();
1478     MG_NOEUD* nd5=tri01->get_noeud2();
1479     MG_NOEUD* nd6=tri01->get_noeud3();
1480    
1481     if (nd1==noeud_i) {noeud1=nd1;noeud2=nd2;noeud3=nd3;}
1482     if (nd2==noeud_i) {noeud1=nd2;noeud2=nd3;noeud3=nd1;}
1483     if (nd3==noeud_i) {noeud1=nd3;noeud2=nd1;noeud3=nd2;}
1484     if (nd4==noeud_i) {noeud4=nd4;noeud5=nd5;noeud6=nd6;}
1485     if (nd5==noeud_i) {noeud4=nd5;noeud5=nd6;noeud6=nd4;}
1486     if (nd6==noeud_i) {noeud4=nd6;noeud5=nd4;noeud6=nd5;}
1487    
1488     double *xyz1=noeud1->get_coord();
1489     double *xyz2=noeud2->get_coord();
1490     double *xyz3=noeud3->get_coord();
1491     double *xyz4=noeud4->get_coord();
1492     double *xyz5=noeud5->get_coord();
1493     double *xyz6=noeud6->get_coord();
1494    
1495     OT_VECTEUR_3D vec1(xyz1,xyz2);
1496     OT_VECTEUR_3D vec2(xyz1,xyz3);
1497     OT_VECTEUR_3D vec3(xyz2,xyz3);
1498     OT_VECTEUR_3D vec4(xyz4,xyz5);
1499     OT_VECTEUR_3D vec5(xyz4,xyz6);
1500     OT_VECTEUR_3D vec6(xyz5,xyz6);
1501    
1502    
1503     // COURBURE GAUSSIENNE
1504     // Calcul de alpha (i) de chaque triangle lié au noeud
1505     double cosalpha=((vec1*vec2)/(vec1.get_longueur()*vec2.get_longueur()));
1506     double alpha=acos(cosalpha);
1507     double cotalpha=(cosalpha/sin(alpha));
1508     som1=som1+alpha;
1509     // Calcul Aire triangle 1
1510     OT_VECTEUR_3D pvec1=vec1&vec2;
1511     surface=0.5*pvec1.get_longueur();
1512     som2=som2+surface;
1513     // Calcul de I = longueur de l'arête opposée à l'angle alpha
1514     double I=vec3.get_longueur();
1515     som3=som3+(I*I*cotalpha);
1516     // COURBURE MOYENNE
1517     // Calcul de la longueur de l'arête commune au deux triangles adjacents ftr et fnd
1518     double L=vec2.get_longueur();
1519     // Calcul de beta, l'angle entre les normales de 2 triangles adjacents
1520     beta=M_PI-calcul_angle(tri00,tri01);
1521     som4=som4+(beta*L);
1522     }
1523    
1524     // Courbure de Gauss, moyenne, max et min
1525     K=((2.*M_PI-som1)/((0.5*som2)-(0.125*som3)));
1526     H=((0.25*som4)/((0.5*som2)-(0.125*som3)));
1527     if (H*H-K>0.) kM1=H+sqrt((H)*(H)-(K)); else kM1=H;
1528     if (H*H-K>0.) km1=H-sqrt((H)*(H)-(K)); else km1=H;
1529    
1530     if ((fabs(kM1)>1.e-06) && (fabs(km1)>1.e-06))
1531     liste_nodes_bruit.ajouter(noeud_i);
1532     }
1533     }
1534     cout << "nb_noeuds_bruit = " << liste_nodes_bruit.get_nb() << endl;
1535    
1536    
1537     do
1538     {
1539     /// Lissage Laplacien des noeuds bruites
1540     vector<double> nouv_position_x;
1541     vector<double> nouv_position_y;
1542     vector<double> nouv_position_z;
1543     for(MG_NOEUD* noeud_i=liste_nodes_bruit.get_premier(inode);noeud_i;noeud_i=liste_nodes_bruit.get_suivant(inode))
1544     {
1545     int nb_voisins_j = noeud_i->get_lien_triangle()->get_nb();
1546     double wij = 0.0;
1547     double wij_sommej = 0.0;
1548     OT_VECTEUR_3D v_temp(0.,0.,0.);
1549     OT_VECTEUR_3D v_i(noeud_i->get_x(),noeud_i->get_y(),noeud_i->get_z());
1550     for(int j=0;j<nb_voisins_j;j++)
1551     {
1552     MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
1553     //On calcule le centroide cj du triangle mgtri_j
1554     MG_NOEUD* n1 = mgtri_j->get_noeud1();
1555     MG_NOEUD* n2 = mgtri_j->get_noeud2();
1556     MG_NOEUD* n3 = mgtri_j->get_noeud3();
1557     double cj_x = 0.333333333333333*(n1->get_x() + n2->get_x() + n3->get_x());
1558     double cj_y = 0.333333333333333*(n1->get_y() + n2->get_y() + n3->get_y());
1559     double cj_z = 0.333333333333333*(n1->get_z() + n2->get_z() + n3->get_z());
1560     //On forme le vecteur vi_cj et le vecteur cj
1561     OT_VECTEUR_3D cj(cj_x ,cj_y,cj_z);
1562     OT_VECTEUR_3D vi_cj(cj_x - noeud_i->get_x(),cj_y - noeud_i->get_y(),cj_z - noeud_i->get_z());
1563     wij=vi_cj.get_longueur();
1564     wij_sommej=wij_sommej+wij;
1565     v_temp = v_temp + (wij*cj);
1566     }
1567     v_i =v_temp/wij_sommej;
1568    
1569     /*
1570     OT_VECTEUR_3D v_temp(0.,0.,0.);
1571     OT_VECTEUR_3D v_i(noeud_i->get_x(),noeud_i->get_y(),noeud_i->get_z());
1572     TPL_MAP_ENTITE<MG_NOEUD*> listenoeud;
1573     TPL_MAP_ENTITE<MG_NOEUD*>::ITERATEUR in;
1574     for(int j=0;j<noeud_i->get_lien_triangle()->get_nb();j++)
1575     {
1576     MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
1577     MG_NOEUD* n1 = mgtri_j->get_noeud1();
1578     MG_NOEUD* n2 = mgtri_j->get_noeud2();
1579     MG_NOEUD* n3 = mgtri_j->get_noeud3();
1580     listenoeud.ajouter(n1);
1581     listenoeud.ajouter(n2);
1582     listenoeud.ajouter(n3);
1583     }
1584     listenoeud.supprimer(noeud_i);
1585     for (MG_NOEUD* no=listenoeud.get_premier(in);no;no=listenoeud.get_suivant(in))
1586     v_temp=v_temp+no->get_coord();
1587    
1588     v_i = v_temp/listenoeud.get_nb();
1589     for (MG_NOEUD* no=listenoeud.get_premier(in);no;no=listenoeud.get_suivant(in))
1590     listenoeud.supprimer(no);
1591     */
1592    
1593     nouv_position_x.push_back(v_i.get_x());
1594     nouv_position_y.push_back(v_i.get_y());
1595     nouv_position_z.push_back(v_i.get_z());
1596     }
1597    
1598    
1599     /// Mise a jour de la position des noeuds
1600     int ind_noeud=0;
1601     for(MG_NOEUD* noeud_i=liste_nodes_bruit.get_premier(inode);noeud_i;noeud_i=liste_nodes_bruit.get_suivant(inode))
1602     {
1603     noeud_i->change_x(nouv_position_x[ind_noeud]);
1604     noeud_i->change_y(nouv_position_y[ind_noeud]);
1605     noeud_i->change_z(nouv_position_z[ind_noeud]);
1606     ind_noeud++;
1607     }
1608    
1609    
1610     /// Calcul du volume apres chaque iteration
1611     double d2=0.;
1612     double v2=0.;
1613     for (MG_TRIANGLE* ttr=mg_mai->get_premier_triangle(it);ttr!=NULL;ttr=mg_mai->get_suivant_triangle(it))
1614     {
1615     MG_TRIANGLE_PEAU* tri=(MG_TRIANGLE_PEAU*)ttr;
1616     if(tri->get_origine()!=MAILLEUR_AUTO)
1617     {
1618     MG_NOEUD* no1=tri->get_noeud1();
1619     MG_NOEUD* no2=tri->get_noeud2();
1620     MG_NOEUD* no3=tri->get_noeud3();
1621     double *xyz1=no1->get_coord();
1622     double *xyz2=no2->get_coord();
1623     double *xyz3=no3->get_coord();
1624     OT_VECTEUR_3D vec1(xyz1,xyz2);
1625     OT_VECTEUR_3D vec2(xyz1,xyz3);
1626     OT_VECTEUR_3D pvec=vec2&vec1;
1627    
1628     d2=pvec.get_longueur();
1629     OT_VECTEUR_3D N =pvec/(pvec.get_longueur());
1630     OT_VECTEUR_3D F3=(1/6.)*(1/3.)*((xyz1+(1/6.)*vec1+(1/6.)*vec2)
1631     +(xyz1+(2/3.)*vec1+(1/6.)*vec2)
1632     +(xyz1+(1/6.)*vec1+(2/3.)*vec2));
1633     v2=v2+d2*N*F3;
1634     }
1635     }
1636     //cout << v2 << endl;
1637    
1638     /// Critere d'arret volumique
1639     if ((fabs(v1) - fabs(v2)) < -1000.) fin=1;
1640     if (((fabs(v1) - fabs(v2)) < -1000.) || (compteur == iter_max-1)) cout << "Volume apres lissage = " << v2 << endl;
1641     compteur++;
1642     }
1643    
1644     while ((fin == 0) && (compteur < iter_max));
1645    
1646    
1647     for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1648     if ((noeud_i->get_origine() != IMPOSE))
1649     {
1650     noeud_i->change_solution(0.);
1651     noeud_i->change_nouveau_numero(0);
1652     }
1653    
1654     for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1655     for(MG_NOEUD* noeud=liste_nodes_bruit.get_premier(inode);noeud;noeud=liste_nodes_bruit.get_suivant(inode))
1656     if ((noeud_i->get_origine() != IMPOSE) && (noeud_i != noeud))
1657     {
1658     liste_nodes_non_modifies.ajouter(noeud_i);
1659     noeud_i->change_nouveau_numero(1);
1660     }
1661    
1662     cout << "nb_noeuds_intact = " << liste_nodes_non_modifies.get_nb() << endl;
1663    
1664     /// Detection des noeuds "features"
1665     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);
1666     gest2.ajouter_mg_solution(sol);
1667     sol->change_legende(0,"courbure_max");
1668     sol->change_legende(1,"courbure_min");
1669     int t=0;
1670     for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1671     {
1672     if ((noeud_i->get_origine() != IMPOSE))
1673     {
1674     TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*> liste_map_triangle;
1675     TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*>::ITERATEUR it;
1676     TPL_LISTE_ENTITE<MG_TRIANGLE_PEAU*> liste_tpl_triangle;
1677    
1678     for (int k=0;k<noeud_i->get_lien_triangle()->get_nb();k++)
1679     {
1680     MG_TRIANGLE_PEAU* tri1= (MG_TRIANGLE_PEAU*)noeud_i->get_lien_triangle()->get(k);
1681     liste_map_triangle.ajouter(tri1);
1682     }
1683    
1684     MG_TRIANGLE_PEAU* tri2=liste_map_triangle.get_premier(it);
1685     MG_NOEUD* na=tri2->get_noeud1();
1686     MG_NOEUD* nb=tri2->get_noeud2();
1687     MG_NOEUD* nc=tri2->get_noeud3();
1688     MG_NOEUD* n1=NULL;
1689     MG_NOEUD* n2=NULL;
1690     MG_NOEUD* n3=NULL;
1691    
1692     if (na==noeud_i) {n1=na;n2=nb;n3=nc;}
1693     if (nb==noeud_i) {n1=nb;n2=nc;n3=na;}
1694     if (nc==noeud_i) {n1=nc;n2=na;n3=nb;}
1695    
1696     liste_tpl_triangle.ajouter(tri2);
1697    
1698     while (liste_map_triangle.get_nb()!=liste_tpl_triangle.get_nb())
1699     for (MG_TRIANGLE_PEAU* tri=liste_map_triangle.get_premier(it);tri;tri=liste_map_triangle.get_suivant(it))
1700     {
1701     if (tri!=tri2)
1702     {
1703     MG_NOEUD* noa=tri->get_noeud1();
1704     MG_NOEUD* nob=tri->get_noeud2();
1705     MG_NOEUD* noc=tri->get_noeud3();
1706     MG_NOEUD* n4=NULL;
1707     MG_NOEUD* n5=NULL;
1708     MG_NOEUD* n6=NULL;
1709    
1710     if (noa==noeud_i) {n4=noa;n5=nob;n6=noc;}
1711     if (nob==noeud_i) {n4=nob;n5=noc;n6=noa;}
1712     if (noc==noeud_i) {n4=noc;n5=noa;n6=nob;}
1713    
1714     if (n1==n4)
1715     if (n3==n5)
1716     {
1717     liste_tpl_triangle.ajouter(tri);
1718     n1=n4;
1719     n2=n5;
1720     n3=n6;
1721     if (liste_map_triangle.get_nb()==liste_tpl_triangle.get_nb()) break;
1722     }
1723     }
1724     }
1725    
1726     double K=0.;
1727     double H=0.;
1728    
1729     double beta=0.;
1730     double surface=0.;
1731     double som1=0.;
1732     double som2=0.;
1733     double som3=0.;
1734     double som4=0.;
1735    
1736     for (int i=0;i<liste_tpl_triangle.get_nb();i++)
1737     {
1738     MG_TRIANGLE_PEAU* tri00=NULL;
1739     MG_TRIANGLE_PEAU* tri01=NULL;
1740    
1741     if (!(i==(liste_tpl_triangle.get_nb()-1))) {tri00=liste_tpl_triangle.get(i);tri01=liste_tpl_triangle.get(i+1);}
1742     if (i==(liste_tpl_triangle.get_nb()-1)) {tri00=liste_tpl_triangle.get(i);tri01=tri2;}
1743    
1744     MG_NOEUD* noeud1=NULL;
1745     MG_NOEUD* noeud2=NULL;
1746     MG_NOEUD* noeud3=NULL;
1747     MG_NOEUD* noeud4=NULL;
1748     MG_NOEUD* noeud5=NULL;
1749     MG_NOEUD* noeud6=NULL;
1750    
1751     MG_NOEUD* nd1=tri00->get_noeud1();
1752     MG_NOEUD* nd2=tri00->get_noeud2();
1753     MG_NOEUD* nd3=tri00->get_noeud3();
1754     MG_NOEUD* nd4=tri01->get_noeud1();
1755     MG_NOEUD* nd5=tri01->get_noeud2();
1756     MG_NOEUD* nd6=tri01->get_noeud3();
1757    
1758     if (nd1==noeud_i) {noeud1=nd1;noeud2=nd2;noeud3=nd3;}
1759     if (nd2==noeud_i) {noeud1=nd2;noeud2=nd3;noeud3=nd1;}
1760     if (nd3==noeud_i) {noeud1=nd3;noeud2=nd1;noeud3=nd2;}
1761     if (nd4==noeud_i) {noeud4=nd4;noeud5=nd5;noeud6=nd6;}
1762     if (nd5==noeud_i) {noeud4=nd5;noeud5=nd6;noeud6=nd4;}
1763     if (nd6==noeud_i) {noeud4=nd6;noeud5=nd4;noeud6=nd5;}
1764    
1765     double *xyz1=noeud1->get_coord();
1766     double *xyz2=noeud2->get_coord();
1767     double *xyz3=noeud3->get_coord();
1768     double *xyz4=noeud4->get_coord();
1769     double *xyz5=noeud5->get_coord();
1770     double *xyz6=noeud6->get_coord();
1771    
1772     OT_VECTEUR_3D vec1(xyz1,xyz2);
1773     OT_VECTEUR_3D vec2(xyz1,xyz3);
1774     OT_VECTEUR_3D vec3(xyz2,xyz3);
1775     OT_VECTEUR_3D vec4(xyz4,xyz5);
1776     OT_VECTEUR_3D vec5(xyz4,xyz6);
1777     OT_VECTEUR_3D vec6(xyz5,xyz6);
1778    
1779    
1780     // COURBURE GAUSSIENNE
1781     // Calcul de alpha (i) de chaque triangle lié au noeud
1782     double cosalpha=((vec1*vec2)/(vec1.get_longueur()*vec2.get_longueur()));
1783     double alpha=acos(cosalpha);
1784     double cotalpha=(cosalpha/sin(alpha));
1785     som1=som1+alpha;
1786     // Calcul Aire triangle 1
1787     OT_VECTEUR_3D pvec1=vec1&vec2;
1788     surface=0.5*pvec1.get_longueur();
1789     som2=som2+surface;
1790     // Calcul de I = longueur de l'arête opposée à l'angle alpha
1791     double I=vec3.get_longueur();
1792     som3=som3+(I*I*cotalpha);
1793     // COURBURE MOYENNE
1794     // Calcul de la longueur de l'arête commune au deux triangles adjacents ftr et fnd
1795     double L=vec2.get_longueur();
1796     // Calcul de beta, l'angle entre les normales de 2 triangles adjacents
1797     beta=M_PI-calcul_angle(tri00,tri01);
1798     som4=som4+(beta*L);
1799     }
1800    
1801     // Courbure de Gauss
1802     K=((2.*M_PI-som1)/((0.5*som2)-(0.125*som3)));
1803     H=((0.25*som4)/((0.5*som2)-(0.125*som3)));
1804     if (H*H-K>0.) kM1=H+sqrt((H)*(H)-(K)); else kM1=H;
1805     if (H*H-K>0.) km1=H-sqrt((H)*(H)-(K)); else km1=H;
1806    
1807     if ((km1 > 1.e-03)) liste_nodes_aretes_vives.ajouter(noeud_i);
1808     sol->ecrire(kM1,t,0);
1809     sol->ecrire(km1,t,1);
1810     }
1811     t++;
1812     }
1813    
1814     cout << "nb_noeuds_aretes_vives = " << liste_nodes_aretes_vives.get_nb() << endl;
1815    
1816     /// Projection des noeuds "features" dans le plan des noeuds nonmodifies
1817     vector<double> nouv_position_x;
1818     vector<double> nouv_position_y;
1819     vector<double> nouv_position_z;
1820     for(MG_NOEUD* noeud_i=liste_nodes_aretes_vives.get_premier(inode3);noeud_i;noeud_i=liste_nodes_aretes_vives.get_suivant(inode3))
1821     {
1822     double wij = 0.0;
1823     double wij_sommej = 0.0;
1824     OT_VECTEUR_3D v_temp(0.,0.,0.);
1825     OT_VECTEUR_3D v_i(noeud_i->get_x(),noeud_i->get_y(),noeud_i->get_z());
1826     TPL_MAP_ENTITE<MG_NOEUD*>::ITERATEUR in;
1827     for(int j=0;j<noeud_i->get_lien_triangle()->get_nb();j++)
1828     {
1829     MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
1830     MG_NOEUD* n1 = mgtri_j->get_noeud1();
1831     MG_NOEUD* n2 = mgtri_j->get_noeud2();
1832     MG_NOEUD* n3 = mgtri_j->get_noeud3();
1833     double cj_x = 0.333333333333333*(n1->get_x() + n2->get_x() + n3->get_x());
1834     double cj_y = 0.333333333333333*(n1->get_y() + n2->get_y() + n3->get_y());
1835     double cj_z = 0.333333333333333*(n1->get_z() + n2->get_z() + n3->get_z());
1836     OT_VECTEUR_3D cj(cj_x ,cj_y,cj_z);
1837     OT_VECTEUR_3D vi_cj(cj_x - noeud_i->get_x(),cj_y - noeud_i->get_y(),cj_z - noeud_i->get_z());
1838     wij=exp(-vi_cj.get_longueur());
1839     wij_sommej=wij_sommej+wij;
1840     v_temp = v_temp + (wij*cj);
1841     }
1842     v_i = v_temp/wij_sommej;
1843    
1844     double cj_x = 0.;
1845     double cj_y = 0.;
1846     double cj_z = 0.;
1847     OT_VECTEUR_3D normale(0.,0.,0.);
1848     for (int j = 0;j<noeud_i->get_lien_triangle()->get_nb();j++)
1849     {
1850     MG_TRIANGLE_PEAU* mgtri=NULL;
1851     MG_TRIANGLE_PEAU* mgtri_peau = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
1852     if (mgtri_peau->get_origine() != IMPOSE)
1853     {
1854     MG_NOEUD* no1=NULL;
1855     MG_NOEUD* no2=NULL;
1856     MG_NOEUD* no3=NULL;
1857     MG_NOEUD* na = mgtri_peau->get_noeud1();
1858     MG_NOEUD* nb = mgtri_peau->get_noeud2();
1859     MG_NOEUD* nc = mgtri_peau->get_noeud3();
1860     if ((na==noeud_i)) {no1=na;no2=nb;no3=nc;}
1861     if ((nb==noeud_i)) {no1=nb;no2=nc;no3=na;}
1862     if ((nc==noeud_i)) {no1=nc;no2=na;no3=nb;}
1863     if ((no2->get_nouveau_numero() == 1) && (no3->get_nouveau_numero() == 1))
1864     {
1865     cj_x = 0.333333333333333*(no1->get_x() + no2->get_x() + no3->get_x());
1866     cj_y = 0.333333333333333*(no1->get_y() + no2->get_y() + no3->get_y());
1867     cj_z = 0.333333333333333*(no1->get_z() + no2->get_z() + no3->get_z());
1868     normale = mgtri_peau->calcul_normal();
1869     }
1870     }
1871     }
1872     normale.norme();
1873     double a = normale.get_x();
1874     double b = normale.get_y();
1875     double c = normale.get_z();
1876     double d = -(a*cj_x + b*cj_y + c*cj_z);
1877     //double k = -(a*v_i.get_x() + b*v_i.get_y() + c*v_i.get_z() + d)/(a*a + b*b + c*c);
1878     double k = -(a*cj_x + b*cj_y + c*cj_z + d)/(a*a + b*b + c*c);
1879    
1880     nouv_position_x.push_back(v_i.get_x() + k*a);
1881     nouv_position_y.push_back(v_i.get_y() + k*b);
1882     nouv_position_z.push_back(v_i.get_z() + k*c);
1883     }
1884    
1885     /// Mise a jour finale de la position des noeuds
1886     int ind_noeud=0;
1887     for(MG_NOEUD* noeud_i=liste_nodes_aretes_vives.get_premier(inode3);noeud_i;noeud_i=liste_nodes_aretes_vives.get_suivant(inode3))
1888     {
1889     if ((noeud_i->get_origine() != IMPOSE))
1890     {
1891     noeud_i->change_x(nouv_position_x[ind_noeud]);
1892     noeud_i->change_y(nouv_position_y[ind_noeud]);
1893     noeud_i->change_z(nouv_position_z[ind_noeud]);
1894     ind_noeud++;
1895     }
1896     }
1897    
1898     /// Calcul du volume final
1899     double d3=0.;
1900     double v3=0.;
1901     for (MG_TRIANGLE* ttr=mg_mai->get_premier_triangle(it);ttr!=NULL;ttr=mg_mai->get_suivant_triangle(it))
1902     {
1903     MG_TRIANGLE_PEAU* tri=(MG_TRIANGLE_PEAU*)ttr;
1904     if(tri->get_origine()!=MAILLEUR_AUTO)
1905     {
1906     MG_NOEUD* no1=tri->get_noeud1();
1907     MG_NOEUD* no2=tri->get_noeud2();
1908     MG_NOEUD* no3=tri->get_noeud3();
1909     double *xyz1=no1->get_coord();
1910     double *xyz2=no2->get_coord();
1911     double *xyz3=no3->get_coord();
1912     OT_VECTEUR_3D vec1(xyz1,xyz2);
1913     OT_VECTEUR_3D vec2(xyz1,xyz3);
1914     OT_VECTEUR_3D pvec=vec2&vec1;
1915    
1916     d3=pvec.get_longueur();
1917     OT_VECTEUR_3D N =pvec/(pvec.get_longueur());
1918     OT_VECTEUR_3D F4=(1/6.)*(1/3.)*((xyz1+(1/6.)*vec1+(1/6.)*vec2)
1919     +(xyz1+(2/3.)*vec1+(1/6.)*vec2)
1920     +(xyz1+(1/6.)*vec1+(2/3.)*vec2));
1921     v3=v3+d3*N*F4;
1922     }
1923     }
1924     cout << "Volume final apres projection = " << v3 << endl;
1925     return (compteur);
1926     }
1927    
1928    
1929 francois 457 //---------------------------- Extract skin -------------------------------------------------------------------------
1930 francois 460 int MGOPT_POSTTRAITEMENT::extract_skin(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2,int &nbpeau,int &nbmaniare,int &nbmanino, int *mai2_id)
1931 cuillier 438 {
1932    
1933 francois 457 //etape 0 - On commence par mettre a zero tous les nouveau_numero des triangles et des noeuds du maillage
1934 francois 222 LISTE_MG_TRIANGLE::iterator it_tri;
1935     for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
1936     {
1937     mgtri->change_nouveau_numero(0);
1938 francois 224 mgtri->change_origine(MAILLEUR_AUTO);
1939 francois 222 }
1940     LISTE_MG_NOEUD::iterator it_noeud;
1941     for (MG_NOEUD* mgnoeud=mg_mai->get_premier_noeud(it_noeud);mgnoeud!=NULL;mgnoeud=mg_mai->get_suivant_noeud(it_noeud))
1942     {
1943     mgnoeud->change_nouveau_numero(0);
1944     }
1945    
1946 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
1947 picher 233 LISTE_MG_TETRA::iterator it_tetra;
1948     for (MG_TETRA* mgtet=mg_mai->get_premier_tetra(it_tetra);mgtet!=NULL;mgtet=mg_mai->get_suivant_tetra(it_tetra))
1949 francois 222 {
1950     int origine = mgtet->get_origine();
1951 francois 224 if (origine==IMPOSE)
1952 francois 222 {
1953 francois 224 mgtet->get_triangle1()->change_origine(IMPOSE);
1954     mgtet->get_triangle2()->change_origine(IMPOSE);
1955     mgtet->get_triangle3()->change_origine(IMPOSE);
1956     mgtet->get_triangle4()->change_origine(IMPOSE);
1957     }
1958     if (origine==OPTIMISE)
1959     {
1960     if (mgtet->get_triangle1()->get_origine()!=IMPOSE) mgtet->get_triangle1()->change_origine(OPTIMISE);
1961     if (mgtet->get_triangle2()->get_origine()!=IMPOSE) mgtet->get_triangle2()->change_origine(OPTIMISE);
1962     if (mgtet->get_triangle3()->get_origine()!=IMPOSE) mgtet->get_triangle3()->change_origine(OPTIMISE);
1963     if (mgtet->get_triangle4()->get_origine()!=IMPOSE) mgtet->get_triangle4()->change_origine(OPTIMISE);
1964     }
1965    
1966     if (((origine == OPTIMISE) && (etat[(OPTIMISE-1000)/10]==1) ) ||
1967     ((origine == IMPOSE) && (etat[(IMPOSE-1000)/10]==1) ) ||
1968     ((origine == MAILLEUR_AUTO) && (etat[(MAILLEUR_AUTO-1000)/10]==1) ) ||
1969     ((origine == TRIANGULATION) && (etat[(TRIANGULATION-1000)/10]==1) ) ||
1970     ((origine == MODIFICATION) && (etat[(MODIFICATION-1000)/10]==1) ) ||
1971     ((origine == DUPLIQUER) && (etat[(DUPLIQUER-1000)/10]==1) ) )
1972    
1973     {
1974 francois 222 int num1 = mgtet->get_triangle1()->get_nouveau_numero();
1975     int num2 = mgtet->get_triangle2()->get_nouveau_numero();
1976     int num3 = mgtet->get_triangle3()->get_nouveau_numero();
1977     int num4 = mgtet->get_triangle4()->get_nouveau_numero();
1978     num1++;
1979     num2++;
1980     num3++;
1981     num4++;
1982     mgtet->get_triangle1()->change_nouveau_numero(num1);
1983     mgtet->get_triangle2()->change_nouveau_numero(num2);
1984     mgtet->get_triangle3()->change_nouveau_numero(num3);
1985     mgtet->get_triangle4()->change_nouveau_numero(num4);
1986     }
1987     }
1988    
1989 francois 457 //etape 2 - On boucle l'ensemble des triangles identifies a l'etape 1 pour identifier les noeuds leur appartenant
1990 francois 222 for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
1991     {
1992     int num = mgtri->get_nouveau_numero();
1993     if (num == 1)
1994     {
1995     MG_NOEUD* noeud1 = mgtri->get_noeud1();
1996     MG_NOEUD* noeud2 = mgtri->get_noeud2();
1997     MG_NOEUD* noeud3 = mgtri->get_noeud3();
1998     noeud1->change_nouveau_numero(1);
1999     noeud2->change_nouveau_numero(1);
2000     noeud3->change_nouveau_numero(1);
2001 picher 248 if (mgtri->get_origine()==IMPOSE)
2002     {
2003     noeud1->change_origine(IMPOSE);
2004     noeud2->change_origine(IMPOSE);
2005     noeud3->change_origine(IMPOSE);
2006     }
2007 francois 222 }
2008     }
2009    
2010 francois 457 //etape 3 - On cree un nouveau maillage pour la peau
2011 francois 222 MG_MAILLAGE* mai2 = new MG_MAILLAGE(NULL);
2012     gest2.ajouter_mg_maillage(mai2);
2013    
2014 francois 457 //etape 4 - On boucle l'ensemble des noeuds identifies a l'etape 2 pour les recreer dans le second maillage
2015 francois 222 for (MG_NOEUD* mgnoeud=mg_mai->get_premier_noeud(it_noeud);mgnoeud!=NULL;mgnoeud=mg_mai->get_suivant_noeud(it_noeud))
2016     {
2017     int num = mgnoeud->get_nouveau_numero();
2018     if (num == 1)
2019     {
2020     double x = mgnoeud->get_x();
2021     double y = mgnoeud->get_y();
2022     double z = mgnoeud->get_z();
2023 francois 224 int origine=TRIANGULATION;
2024     if (mgnoeud->get_origine()==IMPOSE) origine=IMPOSE;
2025     MG_NOEUD* noeud1 = new MG_NOEUD(NULL,x,y,z,origine);
2026 francois 222 mai2->ajouter_mg_noeud(noeud1);
2027     mgnoeud->change_nouveau_numero(noeud1->get_id());
2028 francois 234 noeud1->change_nouveau_numero(mgnoeud->get_id());
2029 francois 222 }
2030     }
2031    
2032 francois 457 // etape 5 - On boucle l'ensemble des triangles identifies a l'etape 1 pour les recreer dans le maillage 2
2033 picher 233 for (MG_TETRA* mgtet=mg_mai->get_premier_tetra(it_tetra);mgtet!=NULL;mgtet=mg_mai->get_suivant_tetra(it_tetra))
2034 francois 222 {
2035 francois 224 int originetet=mgtet->get_origine();
2036     if (((originetet == OPTIMISE) && (etat[(OPTIMISE-1000)/10]==1) ) ||
2037     ((originetet == IMPOSE) && (etat[(IMPOSE-1000)/10]==1) ) ||
2038     ((originetet == MAILLEUR_AUTO) && (etat[(MAILLEUR_AUTO-1000)/10]==1) ) ||
2039     ((originetet == TRIANGULATION) && (etat[(TRIANGULATION-1000)/10]==1) ) ||
2040     ((originetet == MODIFICATION) && (etat[(MODIFICATION-1000)/10]==1) ) ||
2041     ((originetet == DUPLIQUER) && (etat[(DUPLIQUER-1000)/10]==1) ) )
2042 francois 222 {
2043 francois 224 MG_NOEUD* noeud1 = mgtet->get_noeud1();
2044     MG_NOEUD* noeud2 = mgtet->get_noeud2();
2045     MG_NOEUD* noeud3 = mgtet->get_noeud3();
2046     MG_NOEUD* noeud4 = mgtet->get_noeud4();
2047 francois 222 MG_NOEUD* node1 = mai2->get_mg_noeudid(noeud1->get_nouveau_numero());
2048     MG_NOEUD* node2 = mai2->get_mg_noeudid(noeud2->get_nouveau_numero());
2049     MG_NOEUD* node3 = mai2->get_mg_noeudid(noeud3->get_nouveau_numero());
2050 francois 224 MG_NOEUD* node4 = mai2->get_mg_noeudid(noeud4->get_nouveau_numero());
2051     MG_TRIANGLE* tri1=mgtet->get_triangle1();
2052     MG_TRIANGLE* tri2=mgtet->get_triangle2();
2053     MG_TRIANGLE* tri3=mgtet->get_triangle3();
2054     MG_TRIANGLE* tri4=mgtet->get_triangle4();
2055     if (tri1->get_nouveau_numero()==1)
2056     {
2057     int origine=TRIANGULATION;
2058     if (tri1->get_origine()==IMPOSE) origine=IMPOSE;
2059     MG_TRIANGLE_PEAU* tripeau = insere_triangle(NULL,node1,node2,node3,mai2,origine);
2060     tripeau->change_nouveau_numero(0);
2061     tri1->change_nouveau_numero(0);
2062     }
2063     if (tri2->get_nouveau_numero()==1)
2064     {
2065     int origine=TRIANGULATION;
2066     if (tri2->get_origine()==IMPOSE) origine=IMPOSE;
2067     MG_TRIANGLE_PEAU* tripeau = insere_triangle(NULL,node1,node4,node2,mai2,origine);
2068     tripeau->change_nouveau_numero(0);
2069     tri2->change_nouveau_numero(0);
2070     }
2071     if (tri3->get_nouveau_numero()==1)
2072     {
2073     int origine=TRIANGULATION;
2074     if (tri3->get_origine()==IMPOSE) origine=IMPOSE;
2075     MG_TRIANGLE_PEAU* tripeau = insere_triangle(NULL,node2,node4,node3,mai2,origine);
2076     tripeau->change_nouveau_numero(0);
2077     tri3->change_nouveau_numero(0);
2078     }
2079     if (tri4->get_nouveau_numero()==1)
2080     {
2081     int origine=TRIANGULATION;
2082     if (tri4->get_origine()==IMPOSE) origine=IMPOSE;
2083     MG_TRIANGLE_PEAU* tripeau = insere_triangle(NULL,node1,node3,node4,mai2,origine);
2084     tripeau->change_nouveau_numero(0);
2085     tri4->change_nouveau_numero(0);
2086     }
2087 francois 222 }
2088 francois 224 }
2089     // etape 6 recherche des vosins
2090     for (MG_TRIANGLE* mgtri=mai2->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mai2->get_suivant_triangle(it_tri))
2091     {
2092     MG_TRIANGLE_PEAU* tripeau=(MG_TRIANGLE_PEAU*)mgtri;
2093     MG_TRIANGLE_PEAU* voisin1=recherche_voisin(tripeau->get_noeud1(),tripeau->get_noeud2(),tripeau);
2094     MG_TRIANGLE_PEAU* voisin2=recherche_voisin(tripeau->get_noeud2(),tripeau->get_noeud3(),tripeau);
2095     MG_TRIANGLE_PEAU* voisin3=recherche_voisin(tripeau->get_noeud3(),tripeau->get_noeud1(),tripeau);
2096     tripeau->change_voisin1(voisin1);
2097     tripeau->change_voisin2(voisin2);
2098     tripeau->change_voisin3(voisin3);
2099     }
2100 francois 457 // etape 7 - On recherche les peaux
2101 francois 224 int fin;
2102     do
2103     {
2104     fin=1;
2105     for (MG_TRIANGLE* mgtri=mai2->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mai2->get_suivant_triangle(it_tri))
2106     {
2107     MG_TRIANGLE_PEAU *tripeau=(MG_TRIANGLE_PEAU*)mgtri;
2108     if (tripeau->get_nouveau_numero()==0)
2109     {
2110     fin=0;
2111     std::vector<MG_TRIANGLE_PEAU*> *peau=new std::vector<MG_TRIANGLE_PEAU*>;
2112     lst_peau.push_back(peau);
2113     tripeau->change_nouveau_numero(1);
2114     peau->push_back(tripeau);
2115     determine_peau(peau);
2116     }
2117     }
2118     }
2119     while (fin==0);
2120 francois 457 nbpeau=lst_peau.size();
2121 francois 224 //test de manifold
2122     LISTE_MG_SEGMENT::iterator itseg;
2123     for (MG_SEGMENT* seg=mai2->get_premier_segment(itseg);seg!=NULL;seg=mai2->get_suivant_segment(itseg))
2124     seg->change_nouveau_numero(0);
2125     TPL_MAP_ENTITE<MG_SEGMENT*> nonmanifoldarete;
2126     TPL_MAP_ENTITE<MG_NOEUD*> nonmanifoldnoeud;
2127 francois 234 TPL_MAP_ENTITE<MG_NOEUD*> nonmanifoldnoeuddepuisarete;
2128 francois 457 nbpeau=lst_peau.size();
2129 francois 224 for (int i=0;i<nbpeau;i++)
2130     {
2131     int nbtri=lst_peau[i]->size();
2132     for (int j=0;j<nbtri;j++)
2133     {
2134     MG_TRIANGLE_PEAU* tripeau=(*lst_peau[i])[j];
2135     tripeau->get_segment1()->change_nouveau_numero(tripeau->get_segment1()->get_nouveau_numero()+1);
2136     tripeau->get_segment2()->change_nouveau_numero(tripeau->get_segment2()->get_nouveau_numero()+1);
2137     tripeau->get_segment3()->change_nouveau_numero(tripeau->get_segment3()->get_nouveau_numero()+1);
2138     if (tripeau->get_segment1()->get_nouveau_numero()>2)
2139     nonmanifoldarete.ajouter(tripeau->get_segment1());
2140     if (tripeau->get_segment2()->get_nouveau_numero()>2)
2141     nonmanifoldarete.ajouter(tripeau->get_segment2());
2142     if (tripeau->get_segment3()->get_nouveau_numero()>2)
2143     nonmanifoldarete.ajouter(tripeau->get_segment3());
2144     }
2145     }
2146 picher 233
2147 francois 224 int nbnonmanifoldarete=nonmanifoldarete.get_nb();
2148     for (int i=0;i<nbnonmanifoldarete;i++)
2149     {
2150     MG_SEGMENT* seg=nonmanifoldarete.get(i);
2151     MG_NOEUD* n1=seg->get_noeud1();
2152     MG_NOEUD* n2=seg->get_noeud2();
2153 francois 234 nonmanifoldnoeuddepuisarete.ajouter(n1);
2154     nonmanifoldnoeuddepuisarete.ajouter(n2);
2155 francois 224 }
2156 francois 234 LISTE_MG_NOEUD::iterator itnoeud;
2157     for (MG_NOEUD* no=mai2->get_premier_noeud(itnoeud);no!=NULL;no=mai2->get_suivant_noeud(itnoeud))
2158     {
2159     if (nonmanifoldnoeuddepuisarete.existe(no)) continue;
2160     if (est_non_manifold(no)) nonmanifoldnoeud.ajouter(no);
2161     }
2162 francois 224
2163 francois 457 nbmaniare = nonmanifoldarete.get_nb();
2164     nbmanino = nonmanifoldnoeud.get_nb();
2165 picher 230
2166 francois 457 //etape 8 - Traitement des cas de non manifold
2167     //non manifold par arete
2168 picher 233 for (int i=0;i<nbnonmanifoldarete;i++)
2169     {
2170     MG_SEGMENT* segment=nonmanifoldarete.get(i);
2171 francois 234 MG_NOEUD* noeud1 = mg_mai->get_mg_noeudid(segment->get_noeud1()->get_nouveau_numero());
2172     MG_NOEUD* noeud2 = mg_mai->get_mg_noeudid(segment->get_noeud2()->get_nouveau_numero());
2173     int nb_tetra = noeud1->get_lien_tetra()->get_nb();
2174     for (int j=0;j<nb_tetra;j++)
2175 picher 233 {
2176 francois 234 MG_TETRA* mgtet =noeud1->get_lien_tetra()->get(j);
2177     int originetet=mgtet->get_origine();
2178     if (originetet == MAILLEUR_AUTO)
2179 picher 233 {
2180 francois 457 //On reactive le tetra si l'autre noeud du segment lui appartient aussi
2181 francois 234 MG_NOEUD* no1 = mgtet->get_noeud1();
2182     MG_NOEUD* no2 = mgtet->get_noeud2();
2183     MG_NOEUD* no3 = mgtet->get_noeud3();
2184     MG_NOEUD* no4 = mgtet->get_noeud4();
2185     if((no1 == noeud2) ||(no2 == noeud2) || (no3 == noeud2) || (no4 == noeud2))
2186     mgtet->change_origine(OPTIMISE);
2187 picher 233 }
2188     }
2189     }
2190    
2191     //non manifold par noeud
2192 picher 231 int nbnonmanifoldnoeud=nonmanifoldnoeud.get_nb();
2193     for (int i=0;i<nbnonmanifoldnoeud;i++)
2194     {
2195 francois 234 MG_NOEUD* noeud=mg_mai->get_mg_noeudid(nonmanifoldnoeud.get(i)->get_nouveau_numero());
2196     int nb_tetra = noeud->get_lien_tetra()->get_nb();
2197     for (int j = 0;j<nb_tetra;j++)
2198 francois 345 {
2199 francois 234 MG_TETRA* mgtet =noeud->get_lien_tetra()->get(j);
2200     int originetet=mgtet->get_origine();
2201     if (originetet == MAILLEUR_AUTO)
2202 picher 231 {
2203 francois 234 mgtet->change_origine(OPTIMISE);
2204 picher 231 }
2205     }
2206     }
2207 francois 234 *mai2_id = mai2->get_id();
2208     if ((nbnonmanifoldarete != 0) || (nbnonmanifoldnoeud != 0))
2209     {
2210     for (int i=0;i<lst_peau.size();i++)
2211     {
2212     delete lst_peau[i];
2213     }
2214     lst_peau.clear();
2215     gest2.supprimer_mg_maillageid(*mai2_id);
2216     return 0;
2217     }
2218 picher 230
2219 francois 234 return 1;
2220 francois 222 }
2221    
2222 francois 457 //---------------------------- Determine peau -------------------------------------------------------------------------
2223 francois 460 void MGOPT_POSTTRAITEMENT::determine_peau(std::vector<MG_TRIANGLE_PEAU*> * peau)
2224 francois 222 {
2225 francois 224 int num=0;
2226     while (num!=peau->size())
2227     {
2228     MG_TRIANGLE_PEAU* p=(*peau)[num];
2229     if (p->get_voisin1()->get_nouveau_numero()==0)
2230     {
2231     peau->push_back(p->get_voisin1());
2232     p->get_voisin1()->change_nouveau_numero(1);
2233     }
2234     if (p->get_voisin2()->get_nouveau_numero()==0)
2235     {
2236     peau->push_back(p->get_voisin2());
2237     p->get_voisin2()->change_nouveau_numero(1);
2238     }
2239     if (p->get_voisin3()->get_nouveau_numero()==0)
2240     {
2241     peau->push_back(p->get_voisin3());
2242     p->get_voisin3()->change_nouveau_numero(1);
2243     }
2244     num++;
2245     }
2246     }
2247    
2248 francois 457 //---------------------------- Insere triangle -------------------------------------------------------------------------
2249 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)
2250 francois 224 {
2251 francois 222 MG_TRIANGLE_PEAU* voisin1=NULL,*voisin2=NULL,*voisin3=NULL;
2252     MG_SEGMENT* mgsegment1=mg_maillage->get_mg_segment(mgnoeud1->get_id(),mgnoeud2->get_id());
2253     MG_SEGMENT* mgsegment2=mg_maillage->get_mg_segment(mgnoeud2->get_id(),mgnoeud3->get_id());
2254     MG_SEGMENT* mgsegment3=mg_maillage->get_mg_segment(mgnoeud3->get_id(),mgnoeud1->get_id());
2255     if (mgsegment1==NULL)
2256 francois 224 mgsegment1=mg_maillage->ajouter_mg_segment(topo,mgnoeud1,mgnoeud2,origine);
2257 francois 222 if (mgsegment2==NULL)
2258 francois 224 mgsegment2=mg_maillage->ajouter_mg_segment(topo,mgnoeud2,mgnoeud3,origine);
2259 francois 222 if (mgsegment3==NULL)
2260 francois 224 mgsegment3=mg_maillage->ajouter_mg_segment(topo,mgnoeud3,mgnoeud1,origine);
2261     MG_TRIANGLE_PEAU* mtriangle=new MG_TRIANGLE_PEAU(topo,mgnoeud1,mgnoeud2,mgnoeud3,mgsegment1,mgsegment2,mgsegment3,origine);
2262 francois 222 mg_maillage->ajouter_mg_triangle(mtriangle);
2263     return mtriangle;
2264     }
2265    
2266 francois 457 //---------------------------- Recherche voisin -------------------------------------------------------------------------
2267 francois 460 MG_TRIANGLE_PEAU* MGOPT_POSTTRAITEMENT::recherche_voisin(MG_NOEUD* mg_noeud1,MG_NOEUD* mg_noeud2,MG_TRIANGLE_PEAU* triref)
2268 francois 222 {
2269 francois 224 MG_TRIANGLE_PEAU* trisol=NULL;
2270     double angleref=4.*M_PI;
2271 francois 222 int nb1=mg_noeud1->get_lien_triangle()->get_nb();
2272     int nb2=mg_noeud2->get_lien_triangle()->get_nb();
2273     for (int i=0;i<nb1;i++)
2274     for (int j=0;j<nb2;j++)
2275 francois 224 if (mg_noeud1->get_lien_triangle()->get(i)==mg_noeud2->get_lien_triangle()->get(j))
2276     if ((MG_TRIANGLE_PEAU*)mg_noeud1->get_lien_triangle()->get(i)!=triref)
2277     {
2278     double angle=calcul_angle(triref,(MG_TRIANGLE_PEAU*)mg_noeud1->get_lien_triangle()->get(i));
2279     if (angle<angleref)
2280     {
2281     angleref=angle;
2282     trisol=(MG_TRIANGLE_PEAU*)mg_noeud1->get_lien_triangle()->get(i);
2283     }
2284     }
2285     return trisol;
2286 francois 222 }
2287 francois 223
2288 francois 460 int MGOPT_POSTTRAITEMENT::est_non_manifold(MG_NOEUD* no)
2289 francois 234 {
2290     static int compteur=0;
2291     compteur++;
2292     int nb_tri=no->get_lien_triangle()->get_nb();
2293     TPL_MAP_ENTITE<MG_TRIANGLE*> lst;
2294     for (int i=0;i<nb_tri;i++)
2295     lst.ajouter(no->get_lien_triangle()->get(i));
2296     MG_TRIANGLE_PEAU* premier_triangle=(MG_TRIANGLE_PEAU*)lst.get(0);
2297     lst.supprimer(premier_triangle);
2298     MG_TRIANGLE_PEAU* tricour=(MG_TRIANGLE_PEAU*)premier_triangle;
2299     int i=0;
2300     do
2301     {
2302     if (lst.existe(tricour->get_voisin1()) || ((tricour->get_voisin1()==premier_triangle)&& (i>1)))
2303     {
2304     tricour=tricour->get_voisin1();
2305     lst.supprimer(tricour);
2306     }
2307     else if (lst.existe(tricour->get_voisin2()) || ((tricour->get_voisin2()==premier_triangle)&& (i>1)))
2308     {
2309     tricour=tricour->get_voisin2();
2310     lst.supprimer(tricour);
2311     }
2312     else if (lst.existe(tricour->get_voisin3()) || ((tricour->get_voisin3()==premier_triangle)&& (i>1)))
2313     {
2314     tricour=tricour->get_voisin3();
2315     lst.supprimer(tricour);
2316     }
2317     i++;
2318     }
2319     while (tricour!=premier_triangle);
2320     if (lst.get_nb()>0)
2321     return 1;
2322     return 0;
2323     }
2324 francois 224
2325 francois 457 //---------------------------- Calcule angle -------------------------------------------------------------------------
2326 francois 460 double MGOPT_POSTTRAITEMENT::calcul_angle(MG_TRIANGLE_PEAU* ft1,MG_TRIANGLE_PEAU* ft2)
2327 francois 223 {
2328 francois 388 MG_NOEUD* noeud1=ft1->get_noeud1();
2329     MG_NOEUD* noeud2=ft1->get_noeud2();
2330     MG_NOEUD* noeud3=ft1->get_noeud3();
2331     MG_NOEUD* noeud4=ft2->get_noeud1();
2332     MG_NOEUD* noeud5=ft2->get_noeud2();
2333     MG_NOEUD* noeud6=ft2->get_noeud3();
2334     double angle=get_angle_par_noeud<MG_NOEUD*>(noeud1,noeud2,noeud3,noeud4,noeud5,noeud6);
2335     return angle;
2336 francois 223 }
2337 picher 230
2338 francois 457 //---------------------------- Ponderation gaussian -------------------------------------------------------------------------
2339 francois 460 double MGOPT_POSTTRAITEMENT::ponderation_gaussian(double s,double sigma)
2340 picher 230 {
2341     double w_s;
2342     w_s = exp(-(s*s)/(2.*sigma*sigma));
2343     return w_s;
2344     }
2345    
2346 francois 457 //---------------------------- Ponderation Laplacian -------------------------------------------------------------------------
2347 francois 460 double MGOPT_POSTTRAITEMENT::ponderation_laplacian(double s,double sigma)
2348 picher 230 {
2349     double w_s;
2350     w_s = exp(-(sqrt(2.)*fabs(s))/sigma);
2351     return w_s;
2352     }
2353    
2354 francois 457 //---------------------------- Ponderation elfallahford -------------------------------------------------------------------------
2355 francois 460 double MGOPT_POSTTRAITEMENT::ponderation_elfallahford(double s,double sigma)
2356 picher 230 {
2357     double w_s;
2358     w_s = 1./sqrt(1+pow((s/sigma),2));
2359     return w_s;
2360     }