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, 7 months ago) by nana
File size: 89172 byte(s)
Log Message:
Methodologie de lissage

File Contents

# Content
1 #include "gestionversion.h"
2 #include "mgopt_posttraitement.h"
3 #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 #include "mg_geometrie_outils.h"
9 #include "fem_maillage_outils.h"
10 #include "tpl_fonctions_generiques.h"
11 #include "ot_algorithme_geometrique.h"
12 #include "mg_export.h"
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <time.h>
16 #include <string.h>
17 #include <math.h>
18 #include <complex>
19 //---------------------------------------------------------------------------
20
21
22
23 MGOPT_POSTTRAITEMENT::MGOPT_POSTTRAITEMENT():affichageactif(0)
24 {
25 for (int i=0;i<9;i++) etat[i]=0;
26 params.ajouter("decoupage",0.,OT_PARAMETRES::DOUBLE,"0. découpage en conservant les mailles entieres 1. découpage par isodensite");
27 params.ajouter("seuil",0.5,OT_PARAMETRES::DOUBLE,"Valeur du seuil de densité pour les 2 découpages");
28 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 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 params.ajouter("chen2005_epsilon",0.01,OT_PARAMETRES::DOUBLE,"Critere de convergence du lissage de chen2005");
36 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 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 params.ajouter("chen2008_itermax",10.,OT_PARAMETRES::DOUBLE,"Nombre d'itérations maximales du lissage de chen2008");
40 params.ajouter("chen2008_epsilon",0.01,OT_PARAMETRES::DOUBLE,"Critere de convergence du lissage de chen2008");
41 params.ajouter("chen2008_sigma",0.1,OT_PARAMETRES::DOUBLE,"Écart type du filtre de lissage de chen2008");
42 params.ajouter("chen2008_gamma",1.,OT_PARAMETRES::DOUBLE,"Vitesse d'avancement de déplacement du lissage de chen2008");
43 params.ajouter("chen2008_filtre",1.,OT_PARAMETRES::DOUBLE,"Choix du filtre de lissage de chen2008 1. Gaussian 2.Laplacien 3.elfallahford");
44 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 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 }
49
50
51 MGOPT_POSTTRAITEMENT::~MGOPT_POSTTRAITEMENT()
52 {
53 for (int i=0;i<lst_peau.size();i++)
54 delete lst_peau[i];
55 }
56
57 void MGOPT_POSTTRAITEMENT::active_affichage(void (*fonc)(char*))
58 {
59 affiche=fonc;
60 affichageactif=1;
61 }
62
63
64
65 void MGOPT_POSTTRAITEMENT::posttraite(char *fichier)
66 {
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 void MGOPT_POSTTRAITEMENT::conserve(int origine)
81 {
82 etat[(origine-1000)/10]=1;
83 }
84
85
86 void MGOPT_POSTTRAITEMENT::copieorigine(FEM_MAILLAGE* mai)
87 {
88 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 {
91 MG_TETRA* mgtet=(MG_TETRA*)tet->get_mg_element_maillage();
92 mgtet->change_origine(mgtet->get_origine());
93 }
94 }
95
96
97 void MGOPT_POSTTRAITEMENT::gain_poids(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2)
98 {
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
131 void MGOPT_POSTTRAITEMENT::reactivation(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2)
132 {
133 cout << " Reactivation d'elements manquants sur aretes vives et faces planes" << endl;
134 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 if (compteur == 0) mgtet->change_origine(OPTIMISE);
174 }
175 }
176 }
177
178
179
180
181 MG_MAILLAGE* MGOPT_POSTTRAITEMENT::extract_skin_par_decoupage(FEM_SOLUTION* sol,double limit,MG_GESTIONNAIRE& gest2,std::string nom)
182 {
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 if (passe==1) no->change_solution(nume/deno); else no->change_solution(1.);
208 }
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 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 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 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 }
229 else
230 {
231 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 }
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 affiche((char*)" Decoupage des triangles non design sur la frontiere du volume");
420 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 return mgmai;
586 }
587
588
589 void MGOPT_POSTTRAITEMENT::suppression_peaux_isoles(MG_MAILLAGE* mgmai)
590 {
591 affiche((char*)"Suppression des peaux isolées");
592
593 char message[500];
594 for (int cas=0;cas<2;cas++)
595 {
596 if (cas==0) affiche((char*)" Analyse initiale des peaux");
597 if (cas==1) affiche((char*)" Analyse finale des peaux");
598 int nbisole=0;
599 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 nbisole++;
607 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 sprintf(message," %d peaux, %d non isoles, %d isoles",(int)lst_peau.size(),(int)lst_peau.size()-nbisole,nbisole);
615 affiche(message);
616 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 LISTE_MG_TRIANGLE::iterator itmg;
621 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
631 }
632
633
634 void MGOPT_POSTTRAITEMENT::oriente_tri(MG_TRIANGLE_PEAU* tri,double *xyz)
635 {
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 MG_NOEUD* MGOPT_POSTTRAITEMENT::get_noeud_peau(FEM_NOEUD* no,MG_MAILLAGE* mai)
652 {
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 int MGOPT_POSTTRAITEMENT::test_du_point_milieu(MG_NOEUD* no1,MG_NOEUD* no2,FEM_ELEMENT3* tet)
670 {
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 FEM_MAILLAGE_OUTILS ot;
678 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 return 0;
681 }
682
683
684
685 int MGOPT_POSTTRAITEMENT::interpole_segment(FEM_NOEUD* no1,FEM_NOEUD* no2,std::vector<MG_NOEUD*> *tab,double limit,MG_MAILLAGE* mai,int creation)
686 {
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 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 {
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 void MGOPT_POSTTRAITEMENT::lire_params(char *fichier)
770 {
771 params.lire(fichier);
772 }
773
774 void MGOPT_POSTTRAITEMENT::posttraite(FEM_SOLUTION* sol, MG_GESTIONNAIRE& gest2,char *nomparam)
775 {
776 if (nomparam!=NULL) lire_params(nomparam);
777 affiche((char*)"Extraction du maillage de surface");
778 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 int nana2015_debut=params.get_valeur("nana2015_debut");
800 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 int nana2015fait=0;
807 if (nana2015_debut==0) nana2015fait=1;
808 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 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 else iteration++;
870 if (chen2005fait==1)
871 if (chen2008fait==1)
872 if (jiao2012fait==1)
873 if (nana2015fait==1)
874 fin=1;
875 }
876 while (fin==0);
877 }
878
879
880 MG_MAILLAGE* MGOPT_POSTTRAITEMENT::extract_skin_maille_entiere(FEM_MAILLAGE* mai,MG_GESTIONNAIRE &gest2)
881 {
882 //Menu de la methode de lissage
883 affiche((char*)"Extraction du maillage de surface");
884 int coderesu = 0;
885 int mai2_id;
886 int imp=params.get_valeur("consimpose");
887 int opti=params.get_valeur("consoptimise");
888 int m_auto=params.get_valeur("consnooptimise");
889 if (opti==1) conserve(OPTIMISE);
890 if (imp==1) conserve(IMPOSE);
891 if (m_auto==1) conserve(MAILLEUR_AUTO);
892 copieorigine(mai);
893 MG_MAILLAGE* mg_mai = (MG_MAILLAGE*)mai->get_mg_maillage();
894 //gain_poids(mg_mai,gest2);
895 int reactiv=params.get_valeur("reactivation");
896 if (reactiv == 1)
897 {
898 reactivation(mg_mai,gest2);
899 }
900 affiche((char*)" Analyse des cas non manifold");
901 do
902 {
903 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 }
910 while (coderesu == 0);
911
912 MG_MAILLAGE* mg_mai2=gest2.get_mg_maillageid(mai2_id);
913
914 return mg_mai2;
915
916 }
917
918
919 void MGOPT_POSTTRAITEMENT::adapte_seuil(class FEM_MAILLAGE* fem,FEM_SOLUTION* solution)
920 {
921 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 {
926 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 }
933 }
934
935
936 //---------------------------- Lissage Chen 2005 Gilles Philippe -------------------------------------------------------------------------
937 int MGOPT_POSTTRAITEMENT::lissage_chen2005(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, double epsilon, double sigma, int iter_max)
938 {
939 //Methode de lissage inspiree de Chen(2005) par Gilles Philipe Picher Martel
940 double un_sur_pi = 1./M_PI;
941 int compteur = 0;
942 int fin = 0;
943
944
945 do
946 {
947 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales;
948 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales2;
949 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 normal_f_i.norme();
957 liste_normales2.ajouter(normal_f_i);
958 //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 double *phi_ij = new double[nb_voisins];
988 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 //2.1-On calcul l'angle entre normal_f_i et normal_f_j pour j allant de 1 a Nb_voisins
998 double prod_scalaire = normal_f_i*normal_f_j;
999 if (prod_scalaire > 1.)
1000 {
1001 prod_scalaire = 1.;
1002 }
1003 if (prod_scalaire < -1.)
1004 {
1005 prod_scalaire = -1.;
1006 }
1007 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 delete[] phi_ij;
1027 //4-On calcule une nouvelle normale pour chaque triangle
1028 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 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 //On calcule le centroide cj du triangle mgtri_j
1052 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 // w_ij_prime correspond a la somme des aires des triangles voisins du noeuds
1062 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 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 //5-On met a jour la position des noeuds
1070 v_i = v_i + v_temp/w_ij_prime;
1071 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 }
1079 //Critere d'arret de l'algorithme
1080 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 OT_VECTEUR_3D normal_f_i = liste_normales2.get(mgtri_i->get_nouveau_numero());
1086 OT_VECTEUR_3D normal_f_i_new = liste_normales.get(mgtri_i->get_nouveau_numero());
1087 double critere = 1. - normal_f_i*normal_f_i_new;
1088 if (critere <= epsilon) l++;
1089 }
1090 double tolerance = 0.01*nb_tri;
1091 if (nb_tri - l <= 0) fin = 1;
1092 compteur++;
1093 }
1094 while ((fin == 0) && (compteur < iter_max));
1095
1096 return compteur;
1097 }
1098
1099 //---------------------------- Lissage Jiao 2012 -------------------------------------------------------------------------
1100 int MGOPT_POSTTRAITEMENT::lissage_jiao2012(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, int iter_max)
1101 {
1102 // Lissage global avec methode de lissage inspiree de JIAO IMR2012 par Jean Christophe sept 2013
1103 int compteur = 0;
1104
1105 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 if (origine != IMPOSE)
1115 {
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 //On calcule le centroide cj du triangle mgtri_j
1125 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 if (origine != IMPOSE)
1151 {
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 return compteur;
1164 }
1165
1166 //---------------------------- Lissage Chen 2008 -------------------------------------------------------------------------
1167 int MGOPT_POSTTRAITEMENT::lissage_chen2008(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, double sigma, double gamma, double epsilon, int iter_max)
1168 {
1169 //Lissage global inspire de Chen(2008) corrige par Jean Christophe sept 2013
1170 double un_sur_pi = 1./M_PI;
1171 int compteur = 0;
1172 int fin = 0;
1173 compteur = 0;
1174
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 //2.1-On calcule l'angle entre normal_f_i et normal_f_j pour j allant de 1 a Nb_voisins
1232 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 //3.1-On calcule l'angle moyen phi_im
1249 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 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 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 //On calcule le centroide cj du triangle mgtri_j
1289 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 //5-On met a jour la position des noeuds
1301 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 if (origine != IMPOSE)
1314 {
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 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 return compteur;
1340
1341 }
1342
1343
1344 //---------------------------- 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 //---------------------------- Extract skin -------------------------------------------------------------------------
1930 int MGOPT_POSTTRAITEMENT::extract_skin(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2,int &nbpeau,int &nbmaniare,int &nbmanino, int *mai2_id)
1931 {
1932
1933 //etape 0 - On commence par mettre a zero tous les nouveau_numero des triangles et des noeuds du maillage
1934 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 mgtri->change_origine(MAILLEUR_AUTO);
1939 }
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 //etape 1 - On boucle ensuite tous les tetraedres pour ajouter un compteur du nombre de fois qu'un triangle appartient a 1 tetra
1947 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 {
1950 int origine = mgtet->get_origine();
1951 if (origine==IMPOSE)
1952 {
1953 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 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 //etape 2 - On boucle l'ensemble des triangles identifies a l'etape 1 pour identifier les noeuds leur appartenant
1990 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 if (mgtri->get_origine()==IMPOSE)
2002 {
2003 noeud1->change_origine(IMPOSE);
2004 noeud2->change_origine(IMPOSE);
2005 noeud3->change_origine(IMPOSE);
2006 }
2007 }
2008 }
2009
2010 //etape 3 - On cree un nouveau maillage pour la peau
2011 MG_MAILLAGE* mai2 = new MG_MAILLAGE(NULL);
2012 gest2.ajouter_mg_maillage(mai2);
2013
2014 //etape 4 - On boucle l'ensemble des noeuds identifies a l'etape 2 pour les recreer dans le second maillage
2015 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 int origine=TRIANGULATION;
2024 if (mgnoeud->get_origine()==IMPOSE) origine=IMPOSE;
2025 MG_NOEUD* noeud1 = new MG_NOEUD(NULL,x,y,z,origine);
2026 mai2->ajouter_mg_noeud(noeud1);
2027 mgnoeud->change_nouveau_numero(noeud1->get_id());
2028 noeud1->change_nouveau_numero(mgnoeud->get_id());
2029 }
2030 }
2031
2032 // etape 5 - On boucle l'ensemble des triangles identifies a l'etape 1 pour les recreer dans le maillage 2
2033 for (MG_TETRA* mgtet=mg_mai->get_premier_tetra(it_tetra);mgtet!=NULL;mgtet=mg_mai->get_suivant_tetra(it_tetra))
2034 {
2035 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 {
2043 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 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 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 }
2088 }
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 // etape 7 - On recherche les peaux
2101 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 nbpeau=lst_peau.size();
2121 //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 TPL_MAP_ENTITE<MG_NOEUD*> nonmanifoldnoeuddepuisarete;
2128 nbpeau=lst_peau.size();
2129 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
2147 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 nonmanifoldnoeuddepuisarete.ajouter(n1);
2154 nonmanifoldnoeuddepuisarete.ajouter(n2);
2155 }
2156 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
2163 nbmaniare = nonmanifoldarete.get_nb();
2164 nbmanino = nonmanifoldnoeud.get_nb();
2165
2166 //etape 8 - Traitement des cas de non manifold
2167 //non manifold par arete
2168 for (int i=0;i<nbnonmanifoldarete;i++)
2169 {
2170 MG_SEGMENT* segment=nonmanifoldarete.get(i);
2171 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 {
2176 MG_TETRA* mgtet =noeud1->get_lien_tetra()->get(j);
2177 int originetet=mgtet->get_origine();
2178 if (originetet == MAILLEUR_AUTO)
2179 {
2180 //On reactive le tetra si l'autre noeud du segment lui appartient aussi
2181 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 }
2188 }
2189 }
2190
2191 //non manifold par noeud
2192 int nbnonmanifoldnoeud=nonmanifoldnoeud.get_nb();
2193 for (int i=0;i<nbnonmanifoldnoeud;i++)
2194 {
2195 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 {
2199 MG_TETRA* mgtet =noeud->get_lien_tetra()->get(j);
2200 int originetet=mgtet->get_origine();
2201 if (originetet == MAILLEUR_AUTO)
2202 {
2203 mgtet->change_origine(OPTIMISE);
2204 }
2205 }
2206 }
2207 *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
2219 return 1;
2220 }
2221
2222 //---------------------------- Determine peau -------------------------------------------------------------------------
2223 void MGOPT_POSTTRAITEMENT::determine_peau(std::vector<MG_TRIANGLE_PEAU*> * peau)
2224 {
2225 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 //---------------------------- Insere triangle -------------------------------------------------------------------------
2249 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 {
2251 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 mgsegment1=mg_maillage->ajouter_mg_segment(topo,mgnoeud1,mgnoeud2,origine);
2257 if (mgsegment2==NULL)
2258 mgsegment2=mg_maillage->ajouter_mg_segment(topo,mgnoeud2,mgnoeud3,origine);
2259 if (mgsegment3==NULL)
2260 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 mg_maillage->ajouter_mg_triangle(mtriangle);
2263 return mtriangle;
2264 }
2265
2266 //---------------------------- Recherche voisin -------------------------------------------------------------------------
2267 MG_TRIANGLE_PEAU* MGOPT_POSTTRAITEMENT::recherche_voisin(MG_NOEUD* mg_noeud1,MG_NOEUD* mg_noeud2,MG_TRIANGLE_PEAU* triref)
2268 {
2269 MG_TRIANGLE_PEAU* trisol=NULL;
2270 double angleref=4.*M_PI;
2271 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 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 }
2287
2288 int MGOPT_POSTTRAITEMENT::est_non_manifold(MG_NOEUD* no)
2289 {
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
2325 //---------------------------- Calcule angle -------------------------------------------------------------------------
2326 double MGOPT_POSTTRAITEMENT::calcul_angle(MG_TRIANGLE_PEAU* ft1,MG_TRIANGLE_PEAU* ft2)
2327 {
2328 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 }
2337
2338 //---------------------------- Ponderation gaussian -------------------------------------------------------------------------
2339 double MGOPT_POSTTRAITEMENT::ponderation_gaussian(double s,double sigma)
2340 {
2341 double w_s;
2342 w_s = exp(-(s*s)/(2.*sigma*sigma));
2343 return w_s;
2344 }
2345
2346 //---------------------------- Ponderation Laplacian -------------------------------------------------------------------------
2347 double MGOPT_POSTTRAITEMENT::ponderation_laplacian(double s,double sigma)
2348 {
2349 double w_s;
2350 w_s = exp(-(sqrt(2.)*fabs(s))/sigma);
2351 return w_s;
2352 }
2353
2354 //---------------------------- Ponderation elfallahford -------------------------------------------------------------------------
2355 double MGOPT_POSTTRAITEMENT::ponderation_elfallahford(double s,double sigma)
2356 {
2357 double w_s;
2358 w_s = 1./sqrt(1+pow((s/sigma),2));
2359 return w_s;
2360 }