ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/aster/src/mgopt_posttraitement.cpp
Revision: 798
Committed: Wed Jun 1 14:41:30 2016 UTC (9 years, 2 months ago) by mckenzie
File size: 204146 byte(s)
Log Message:
ajout d'une nouvelle methode de lissage pour le post traitement de l'optimisation topologique.

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_face_element.h"
13 #include "mg_export.h"
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <time.h>
17 #include <string.h>
18 #include <math.h>
19 #include <complex>
20 //ajout pour pouvoir utiliser les fonction venat de mailleur_analyse.cpp
21 #include "mailleur_analyse.h"
22 #include "m3d_triangle.h"
23 #include "fct_taille.h"
24 #include "mg_segment.h"
25 //---------------------------------------------------------------------------
26
27
28
29 MGOPT_POSTTRAITEMENT::MGOPT_POSTTRAITEMENT():affichageactif(0)
30 {
31 for (int i=0;i<9;i++) etat[i]=0;
32 params.ajouter("decoupage",0.,OT_PARAMETRES::DOUBLE,"0. découpage en conservant les mailles entieres 1. découpage par isodensite");
33 params.ajouter("seuil",0.5,OT_PARAMETRES::DOUBLE,"Valeur du seuil de densité pour les 2 découpages");
34 params.ajouter("nomdensextra","densiteextra.sol",OT_PARAMETRES::STRING,"Nom du fichier comportant la solution de la densité extrapolé au noeud");
35 params.ajouter("consimpose",1.,OT_PARAMETRES::DOUBLE,"0. Maillage non design non inclus dans le decoupage par mailles entieres 1. Maillage design inclus");
36 params.ajouter("consoptimise",1.,OT_PARAMETRES::DOUBLE,"0. Maillage optimise non inclus dans le decoupage par mailles entieres 1. Maillage optimise inclus");
37 params.ajouter("consnooptimise",0.,OT_PARAMETRES::DOUBLE,"0. Maillage non optimise non inclus dans le decoupage par mailles entieres 1. Maillage non optimise inclus");
38 params.ajouter("reactivation",1.,OT_PARAMETRES::DOUBLE,"1. Reactivation de mailles isolées sur le long des aretes 0. non reactivation");
39 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");
40 params.ajouter("chen2005_itermax",10.,OT_PARAMETRES::DOUBLE,"Nombre d'itérations maximales du lissage de chen2005");
41 params.ajouter("chen2005_epsilon",0.01,OT_PARAMETRES::DOUBLE,"Critere de convergence du lissage de chen2005");
42 params.ajouter("chen2005_sigma",0.1,OT_PARAMETRES::DOUBLE,"Écart type du filtre de lissage de chen2005");
43 params.ajouter("chen2005_filtre",1.,OT_PARAMETRES::DOUBLE,"Choix du filtre de lissage de chen2005 1. Gaussian 2.Laplacien 3.elfallahford");
44 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");
45 params.ajouter("chen2008_itermax",10.,OT_PARAMETRES::DOUBLE,"Nombre d'itérations maximales du lissage de chen2008");
46 params.ajouter("chen2008_epsilon",0.01,OT_PARAMETRES::DOUBLE,"Critere de convergence du lissage de chen2008");
47 params.ajouter("chen2008_sigma",0.1,OT_PARAMETRES::DOUBLE,"Écart type du filtre de lissage de chen2008");
48 params.ajouter("chen2008_gamma",1.,OT_PARAMETRES::DOUBLE,"Vitesse d'avancement de déplacement du lissage de chen2008");
49 params.ajouter("chen2008_filtre",1.,OT_PARAMETRES::DOUBLE,"Choix du filtre de lissage de chen2008 1. Gaussian 2.Laplacien 3.elfallahford");
50 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");
51 params.ajouter("jiao2012_itermax",10.,OT_PARAMETRES::DOUBLE,"Nombre d'itérations maximales du lissage de jioa2012");
52 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");
53 params.ajouter("nana2015_itermax",200.,OT_PARAMETRES::DOUBLE,"Nombre d'itérations maximales du lissage de nana2015");
54 params.ajouter("taubin_debut",0.,OT_PARAMETRES::DOUBLE,"Numero d'itération du debut d'application du lissage de taubin1995 0. méthode non utilisee");
55 params.ajouter("taubin1995_lambda",0.33,OT_PARAMETRES::DOUBLE,"Paramète lambda, la valeur doit être positive");
56 params.ajouter("taubin1995_nu",-0.34,OT_PARAMETRES::DOUBLE,"Paramète nu, la valeur doit être negative et respecter 0<lambda<(-nu)");
57 params.ajouter("taubin1995_epsilon", 0.01000, OT_PARAMETRES::DOUBLE,"Critere de convergence du lissage de chen2008");
58 params.ajouter("taubin1995_sigma", 0.10000, OT_PARAMETRES::DOUBLE,"Écart type du filtre de lissage de chen2008");
59 params.ajouter("taubin1995_gamma_", 1.0, OT_PARAMETRES::DOUBLE,"Vitesse d'avancement de déplacement du lissage de chen2008");
60 params.ajouter("taubin1995_filtre", 1.0, OT_PARAMETRES::DOUBLE,"Choix du filtre de lissage de chen2008 1. Gaussian 2.Laplacien 3.elfallahford");
61 params.ajouter("taubin1995_itertaubmax",100.,OT_PARAMETRES::DOUBLE,"Nombre d'itérations maximales de la partie taubin du lissage de taubin1995");
62 params.ajouter("taubin1995_itermax",100.,OT_PARAMETRES::DOUBLE,"Nombre d'itérations maximales de la partie chen 2008 du lissage de taubin1995");
63 }
64
65
66 MGOPT_POSTTRAITEMENT::~MGOPT_POSTTRAITEMENT()
67 {
68 for (int i=0;i<lst_peau.size();i++)
69 delete lst_peau[i];
70 }
71
72 void MGOPT_POSTTRAITEMENT::active_affichage(void (*fonc)(char*))
73 {
74 affiche=fonc;
75 affichageactif=1;
76 }
77
78
79
80 void MGOPT_POSTTRAITEMENT::posttraite(char *fichier)
81 {
82 affiche((char*)"");
83 affiche((char*)"***********************************************************");
84 affiche((char*)"Post-traitement d'un calcul d'optimisation de topologie");
85 affiche((char*)"***********************************************************");
86 affiche((char*)"");
87 affiche((char*)"");
88 affiche((char*)"");
89 affiche((char*)"Écriture d'un fichier de parametres par défaut");
90 params.enregistrer(fichier);
91 }
92
93
94
95 void MGOPT_POSTTRAITEMENT::conserve(int origine)
96 {
97 etat[(origine-1000)/10]=1;
98 }
99
100
101 void MGOPT_POSTTRAITEMENT::copieorigine(FEM_MAILLAGE* mai)
102 {
103 LISTE_FEM_ELEMENT3::iterator it_tetra;
104 for (FEM_ELEMENT3* tet=mai->get_premier_element3(it_tetra);tet!=NULL;tet=mai->get_suivant_element3(it_tetra))
105 {
106 MG_TETRA* mgtet=(MG_TETRA*)tet->get_mg_element_maillage();
107 mgtet->change_origine(mgtet->get_origine());
108 }
109 }
110
111
112 void MGOPT_POSTTRAITEMENT::gain_poids(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2)
113 {
114 LISTE_MG_TETRA::iterator it_tetra;
115 double volume_initial = 0.;
116 double volume_final = 0.;
117 for (MG_TETRA* mgtet=mg_mai->get_premier_tetra(it_tetra);mgtet!=NULL;mgtet=mg_mai->get_suivant_tetra(it_tetra))
118 {
119 int originetet=mgtet->get_origine();
120 MG_NOEUD* noeud1 = mgtet->get_noeud1();
121 double x1 = noeud1->get_x();
122 double y1 = noeud1->get_y();
123 double z1 = noeud1->get_z();
124 MG_NOEUD* noeud2 = mgtet->get_noeud2();
125 double x2 = noeud2->get_x();
126 double y2 = noeud2->get_y();
127 double z2 = noeud2->get_z();
128 MG_NOEUD* noeud3 = mgtet->get_noeud3();
129 double x3 = noeud3->get_x();
130 double y3 = noeud3->get_y();
131 double z3 = noeud3->get_z();
132 MG_NOEUD* noeud4 = mgtet->get_noeud4();
133 double x4 = noeud4->get_x();
134 double y4 = noeud4->get_y();
135 double z4 = noeud4->get_z();
136 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));
137 volume_tet = volume_tet/6.;
138 volume_initial = volume_initial + volume_tet;
139 if (originetet != MAGIC::ORIGINE::MAILLEUR_AUTO)
140 {
141 volume_final = volume_final + volume_tet;
142 }
143 }
144 }
145
146 void MGOPT_POSTTRAITEMENT::reactivation(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2)
147 {
148 cout << " Reactivation d'elements manquants sur aretes vives et faces planes" << endl;
149 LISTE_MG_TETRA::iterator it_tetra;
150 for (MG_TETRA* mgtet=mg_mai->get_premier_tetra(it_tetra);mgtet!=NULL;mgtet=mg_mai->get_suivant_tetra(it_tetra))
151 {
152 int originetet=mgtet->get_origine();
153 int compteur = 0;
154 if (originetet == MAGIC::ORIGINE::MAILLEUR_AUTO)
155 {
156 MG_TRIANGLE* tri1 = mgtet->get_triangle1();
157 MG_TRIANGLE* tri2 = mgtet->get_triangle2();
158 MG_TRIANGLE* tri3 = mgtet->get_triangle3();
159 MG_TRIANGLE* tri4 = mgtet->get_triangle4();
160 int nb_tet1 = tri1->get_lien_tetra()->get_nb();
161 for (int k = 0;k<nb_tet1;k++)
162 {
163 MG_TETRA* tet1 = tri1->get_lien_tetra()->get(k);
164 int ori1 = tet1->get_origine();
165 if ((tet1 != mgtet) && (ori1 == MAGIC::ORIGINE::MAILLEUR_AUTO)) compteur++;
166 }
167 int nb_tet2 = tri2->get_lien_tetra()->get_nb();
168 for (int k = 0;k<nb_tet2;k++)
169 {
170 MG_TETRA* tet2 = tri2->get_lien_tetra()->get(k);
171 int ori2 = tet2->get_origine();
172 if ((tet2 != mgtet) && (ori2 == MAGIC::ORIGINE::MAILLEUR_AUTO)) compteur++;
173 }
174 int nb_tet3 = tri3->get_lien_tetra()->get_nb();
175 for (int k = 0;k<nb_tet3;k++)
176 {
177 MG_TETRA* tet3 = tri3->get_lien_tetra()->get(k);
178 int ori3 = tet3->get_origine();
179 if ((tet3 != mgtet) && (ori3 == MAGIC::ORIGINE::MAILLEUR_AUTO)) compteur++;
180 }
181 int nb_tet4 = tri4->get_lien_tetra()->get_nb();
182 for (int k = 0;k<nb_tet4;k++)
183 {
184 MG_TETRA* tet4 = tri4->get_lien_tetra()->get(k);
185 int ori4 = tet4->get_origine();
186 if ((tet4 != mgtet) && (ori4 == MAGIC::ORIGINE::MAILLEUR_AUTO)) compteur++;
187 }
188 if (compteur == 0) mgtet->change_origine(MAGIC::ORIGINE::OPTIMISE);
189 }
190 }
191 }
192
193
194
195
196 MG_MAILLAGE* MGOPT_POSTTRAITEMENT::extract_skin_par_decoupage(FEM_SOLUTION* sol,double limit,MG_GESTIONNAIRE& gest2,std::string nom)
197 {
198 affiche((char*)"Extraction de l'enveloppe par découpage");
199 sol->active_solution(0);
200 FEM_MAILLAGE* mai=sol->get_maillage();
201 affiche((char*)" Extrapolation de la densité aux noeuds");
202 LISTE_FEM_NOEUD::iterator it;
203 for (FEM_NOEUD* no=mai->get_premier_noeud(it);no!=NULL;no=mai->get_suivant_noeud(it))
204 {
205 double nume=0.;
206 double deno=0.;
207 int nb=no->get_lien_element3()->get_nb();
208 int passe=0;
209 for (int i=0;i<nb;i++)
210 {
211 FEM_ELEMENT3* tet=no->get_lien_element3()->get(i);
212 if (tet->get_mg_element_maillage()->get_origine()!=MAGIC::ORIGINE::IMPOSE)
213 {
214 double jac[9];
215 int col,ligne;
216 double volume=tet->get_jacobien(jac,jac,ligne,col,1.);
217 passe=1;
218 nume=nume+tet->get_solution()*volume;
219 deno=deno+volume;
220 }
221 }
222 if (passe==1) no->change_solution(nume/deno); else no->change_solution(1.);
223 }
224 if (nom!="")
225 {
226 affiche((char*)" Enregistrement de la densité aux noeuds");
227 MG_GESTIONNAIRE *gest=mai->get_mg_maillage()->get_gestionnaire();
228 std::string chemin=nom+".sol";
229 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);
230 gest->ajouter_fem_solution(femdens);
231 femdens->change_legende(0,"Densite");
232 LISTE_FEM_ELEMENT3::iterator it3;
233 int i=0;
234 for (FEM_ELEMENT3* tet=mai->get_premier_element3(it3);tet!=NULL;tet=mai->get_suivant_element3(it3))
235 {
236 MG_TETRA* tet2=(MG_TETRA*)tet->get_mg_element_maillage();
237 if (tet2->get_origine()==MAGIC::ORIGINE::IMPOSE)
238 {
239 femdens->ecrire(1.,i,0,0);
240 femdens->ecrire(1.,i,0,1);
241 femdens->ecrire(1.,i,0,2);
242 femdens->ecrire(1.,i,0,3);
243 }
244 else
245 {
246 femdens->ecrire(tet->get_fem_noeud(0)->get_solution(),i,0,0);
247 femdens->ecrire(tet->get_fem_noeud(1)->get_solution(),i,0,1);
248 femdens->ecrire(tet->get_fem_noeud(2)->get_solution(),i,0,2);
249 femdens->ecrire(tet->get_fem_noeud(3)->get_solution(),i,0,3);
250 }
251 i++;
252 }
253 MG_EXPORT exp;
254 exp.gmsh(mai,nom);
255 gest->supprimer_fem_solution(gest->get_nb_fem_solution()-1);
256 }
257 gest2.vide();
258 MG_GEOMETRIE* geo=new MG_GEOMETRIE((char*)"VIRTUEL",(char*)"VIRTUEL");
259 geo->change_valeur_unite(mai->get_mg_geometrie()->get_valeur_unite());
260 gest2.ajouter_mg_geometrie(geo);
261 MG_FACE_ELEMENT* face=new MG_FACE_ELEMENT();
262 geo->ajouter_mg_face(face);
263 MG_MAILLAGE* mgmai=new MG_MAILLAGE(geo);
264 gest2.ajouter_mg_maillage(mgmai);
265
266 MG_MAILLAGE* mgfem=mai->get_mg_maillage();
267 LISTE_MG_TRIANGLE::iterator itmg;
268 for (MG_TRIANGLE* tri=mgfem->get_premier_triangle(itmg);tri!=NULL;tri=mgfem->get_suivant_triangle(itmg))
269 tri->change_nouveau_numero(0);
270 affiche((char*)" Decoupage des tetra optimises");
271 LISTE_FEM_ELEMENT3::iterator it3;
272 for (FEM_ELEMENT3* tet=mai->get_premier_element3(it3);tet!=NULL;tet=mai->get_suivant_element3(it3))
273 {
274 MG_TETRA* tet2=(MG_TETRA*)tet->get_mg_element_maillage();
275 if (tet2->get_origine()==MAGIC::ORIGINE::IMPOSE)
276 {
277 tet2->get_triangle1()->change_origine(MAGIC::ORIGINE::IMPOSE);
278 tet2->get_triangle2()->change_origine(MAGIC::ORIGINE::IMPOSE);
279 tet2->get_triangle3()->change_origine(MAGIC::ORIGINE::IMPOSE);
280 tet2->get_triangle4()->change_origine(MAGIC::ORIGINE::IMPOSE);
281 tet2->get_noeud1()->change_solution(tet->get_fem_noeud(0)->get_solution());
282 tet2->get_noeud2()->change_solution(tet->get_fem_noeud(1)->get_solution());
283 tet2->get_noeud3()->change_solution(tet->get_fem_noeud(2)->get_solution());
284 tet2->get_noeud4()->change_solution(tet->get_fem_noeud(3)->get_solution());
285 tet2->get_noeud1()->change_nouveau_numero(tet->get_fem_noeud(0)->get_id());
286 tet2->get_noeud2()->change_nouveau_numero(tet->get_fem_noeud(1)->get_id());
287 tet2->get_noeud3()->change_nouveau_numero(tet->get_fem_noeud(2)->get_id());
288 tet2->get_noeud4()->change_nouveau_numero(tet->get_fem_noeud(3)->get_id());
289 if (tet2->get_triangle1()->get_nouveau_numero()==0)
290 tet2->get_triangle1()->change_nouveau_numero(tet2->get_noeud4()->get_id());
291 else
292 tet2->get_triangle1()->change_nouveau_numero(-1);
293 if (tet2->get_triangle2()->get_nouveau_numero()==0)
294 tet2->get_triangle2()->change_nouveau_numero(tet2->get_noeud3()->get_id());
295 else
296 tet2->get_triangle2()->change_nouveau_numero(-1);
297 if (tet2->get_triangle3()->get_nouveau_numero()==0)
298 tet2->get_triangle3()->change_nouveau_numero(tet2->get_noeud1()->get_id());
299 else
300 tet2->get_triangle3()->change_nouveau_numero(-1);
301 if (tet2->get_triangle4()->get_nouveau_numero()==0)
302 tet2->get_triangle4()->change_nouveau_numero(tet2->get_noeud2()->get_id());
303 else
304 tet2->get_triangle4()->change_nouveau_numero(-1);
305 }
306 }
307
308 TPL_LISTE_ENTITE<MG_TRIANGLE*> tri_impose_interne;
309 for (MG_TRIANGLE* tri=mgfem->get_premier_triangle(itmg);tri!=NULL;tri=mgfem->get_suivant_triangle(itmg))
310 {
311 if (tri->get_origine()==MAGIC::ORIGINE::IMPOSE)
312 if (tri->get_lien_topologie()->get_dimension()==3)
313 if (tri->get_nouveau_numero()>0)
314 tri_impose_interne.ajouter(tri);
315 }
316 for (FEM_ELEMENT3* tet=mai->get_premier_element3(it3);tet!=NULL;tet=mai->get_suivant_element3(it3))
317 {
318 if (tet->get_mg_element_maillage()->get_origine()!=MAGIC::ORIGINE::IMPOSE)
319 {
320 FEM_NOEUD* no1=tet->get_fem_noeud(0);
321 FEM_NOEUD* no2=tet->get_fem_noeud(1);
322 FEM_NOEUD* no3=tet->get_fem_noeud(2);
323 FEM_NOEUD* no4=tet->get_fem_noeud(3);
324 std::vector<MG_NOEUD*> tab;
325 interpole_segment(mai,no1,no2,&tab,limit,mgmai);
326 interpole_segment(mai,no1,no3,&tab,limit,mgmai);
327 interpole_segment(mai,no1,no4,&tab,limit,mgmai);
328 interpole_segment(mai,no2,no3,&tab,limit,mgmai);
329 interpole_segment(mai,no2,no4,&tab,limit,mgmai);
330 interpole_segment(mai,no3,no4,&tab,limit,mgmai);
331 int nb=tab.size();
332 FEM_NOEUD* noext;
333 if (nb>0)
334 {
335 if (no1->get_solution()<limit) noext=no1;
336 if (no2->get_solution()<limit) noext=no2;
337 if (no3->get_solution()<limit) noext=no3;
338 if (no4->get_solution()<limit) noext=no4;
339 }
340 if (nb==3)
341 {
342 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[1],tab[2],mgmai,MAGIC::ORIGINE::TRIANGULATION);
343 oriente_tri(tri,noext->get_coord());
344 }
345 if (nb==4)
346 {
347 if (test_du_point_milieu(tab[0],tab[1],tet)==1)
348 {
349 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[1],tab[2],mgmai,MAGIC::ORIGINE::TRIANGULATION);
350 MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[0],tab[1],tab[3],mgmai,MAGIC::ORIGINE::TRIANGULATION);
351 oriente_tri(tri,noext->get_coord());
352 oriente_tri(tri2,noext->get_coord());
353 }
354 else if (test_du_point_milieu(tab[0],tab[2],tet)==1)
355 {
356 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[2],tab[1],mgmai,MAGIC::ORIGINE::TRIANGULATION);
357 MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[0],tab[2],tab[3],mgmai,MAGIC::ORIGINE::TRIANGULATION);
358 oriente_tri(tri,noext->get_coord());
359 oriente_tri(tri2,noext->get_coord());}
360 else if (test_du_point_milieu(tab[0],tab[3],tet)==1)
361 {
362 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[3],tab[1],mgmai,MAGIC::ORIGINE::TRIANGULATION);
363 MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[0],tab[3],tab[2],mgmai,MAGIC::ORIGINE::TRIANGULATION);
364 oriente_tri(tri,noext->get_coord());
365 oriente_tri(tri2,noext->get_coord());}
366 else if (test_du_point_milieu(tab[1],tab[2],tet)==1)
367 {
368 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[1],tab[2],tab[0],mgmai,MAGIC::ORIGINE::TRIANGULATION);
369 MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[1],tab[2],tab[3],mgmai,MAGIC::ORIGINE::TRIANGULATION);
370 oriente_tri(tri,noext->get_coord());
371 oriente_tri(tri2,noext->get_coord());
372 }
373 else if (test_du_point_milieu(tab[1],tab[3],tet)==1)
374 {
375 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[1],tab[3],tab[0],mgmai,MAGIC::ORIGINE::TRIANGULATION);
376 MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[1],tab[3],tab[2],mgmai,MAGIC::ORIGINE::TRIANGULATION);
377 oriente_tri(tri,noext->get_coord());
378 oriente_tri(tri2,noext->get_coord());}
379 else
380 {
381 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[2],tab[3],tab[0],mgmai,MAGIC::ORIGINE::TRIANGULATION);
382 MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[2],tab[3],tab[1],mgmai,MAGIC::ORIGINE::TRIANGULATION);
383 oriente_tri(tri,noext->get_coord());
384 oriente_tri(tri2,noext->get_coord());
385 }
386
387 }
388 }
389 }
390 affiche((char*)" Decoupage des triangles non design interne au volume");
391 for (int i=0;i<tri_impose_interne.get_nb();i++)
392 {
393 MG_TRIANGLE* tri=tri_impose_interne.get(i);
394 MG_NOEUD* no1=tri->get_noeud1();
395 MG_NOEUD* no2=tri->get_noeud2();
396 MG_NOEUD* no3=tri->get_noeud3();
397 std::vector<MG_NOEUD*> tab;
398 int num1=-1;
399 int num2=-1;
400 int num3=-1;
401 if (no1->get_solution()<limit)
402 {
403 MG_NOEUD* no=get_noeud_peau(mai->get_fem_noeudid(no1->get_nouveau_numero()),mgmai);
404 tab.push_back(no);
405 num1=1;
406 }
407 if (no2->get_solution()<limit)
408 {
409 MG_NOEUD* no=get_noeud_peau(mai->get_fem_noeudid(no2->get_nouveau_numero()),mgmai);
410 tab.push_back(no);
411 num2=1;
412 }
413 if (no3->get_solution()<limit)
414 {
415 MG_NOEUD* no=get_noeud_peau(mai->get_fem_noeudid(no3->get_nouveau_numero()),mgmai);
416 tab.push_back(no);
417 num3=1;
418 }
419 if (num1*num2<0) interpole_segment(mai,mai->get_fem_noeudid(no1->get_nouveau_numero()),mai->get_fem_noeudid(no2->get_nouveau_numero()),&tab,limit,mgmai);
420 if (num1*num3<0) interpole_segment(mai,mai->get_fem_noeudid(no1->get_nouveau_numero()),mai->get_fem_noeudid(no3->get_nouveau_numero()),&tab,limit,mgmai);
421 if (num2*num3<0) interpole_segment(mai,mai->get_fem_noeudid(no2->get_nouveau_numero()),mai->get_fem_noeudid(no3->get_nouveau_numero()),&tab,limit,mgmai);
422 MG_NOEUD* noint=mgfem->get_mg_noeudid(tri->get_nouveau_numero());
423 int nb=tab.size();
424 if (nb==3)
425 {
426 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[1],tab[2],mgmai,MAGIC::ORIGINE::IMPOSE);
427 oriente_tri(tri,noint->get_coord());
428 tri->inverse_sens();
429 }
430 if (nb==4)
431 {
432 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[1],tab[2],mgmai,MAGIC::ORIGINE::IMPOSE);
433 MG_TRIANGLE_PEAU* tri2=insere_triangle(NULL,tab[1],tab[2],tab[3],mgmai,MAGIC::ORIGINE::IMPOSE);
434 oriente_tri(tri,noint->get_coord());
435 tri->inverse_sens();
436 oriente_tri(tri2,noint->get_coord());
437 tri2->inverse_sens();
438 }
439 }
440 affiche((char*)" Decoupage des triangles sur la frontiere du volume");
441 LISTE_FEM_ELEMENT2::iterator it2;
442 for (FEM_ELEMENT2* tri=mai->get_premier_element2(it2);tri!=NULL;tri=mai->get_suivant_element2(it2))
443 {
444 std::vector<MG_NOEUD*> tab;
445 FEM_NOEUD *no1=tri->get_fem_noeud(0);
446 FEM_NOEUD *no2=tri->get_fem_noeud(1);
447 FEM_NOEUD *no3=tri->get_fem_noeud(2);
448 int ori=((MG_FACE*)tri->get_lien_topologie())->get_mg_coface(0)->get_orientation();
449 OT_VECTEUR_3D n1n2(no1->get_coord(),no2->get_coord());
450 OT_VECTEUR_3D n1n3(no1->get_coord(),no3->get_coord());
451 OT_VECTEUR_3D nor=n1n3&n1n2;
452 double xyzext[3];
453 xyzext[0]=no1->get_x()+nor.get_x()*ori;
454 xyzext[1]=no1->get_y()+nor.get_y()*ori;
455 xyzext[2]=no1->get_z()+nor.get_z()*ori;
456 if (tri->get_mg_element_maillage()->get_origine()==MAGIC::ORIGINE::IMPOSE)
457 {
458 MG_NOEUD *mgno1=get_noeud_peau(no1,mgmai);
459 MG_NOEUD *mgno2=get_noeud_peau(no2,mgmai);
460 MG_NOEUD *mgno3=get_noeud_peau(no3,mgmai);
461 int num1=interpole_segment(mai,no1,no2,&tab,limit,mgmai,0);
462 int num2=interpole_segment(mai,no1,no3,&tab,limit,mgmai,0);
463 int num3=interpole_segment(mai,no2,no3,&tab,limit,mgmai,0);
464 int nb=tab.size();
465 if (nb==0)
466 {
467 MG_TRIANGLE_PEAU* tri=insere_triangle(face,mgno1,mgno2,mgno3,mgmai,MAGIC::ORIGINE::IMPOSE);
468 oriente_tri(tri,xyzext);
469 }
470 if (nb==1)
471 {
472 if (num1==1)
473 {
474 MG_TRIANGLE_PEAU* tri=insere_triangle(face,mgno1,mgno3,tab[0],mgmai,MAGIC::ORIGINE::IMPOSE);
475 MG_TRIANGLE_PEAU* tri2=insere_triangle(face,mgno2,mgno3,tab[0],mgmai,MAGIC::ORIGINE::IMPOSE);
476 oriente_tri(tri,xyzext);
477 oriente_tri(tri2,xyzext);
478 }
479 if (num2==1)
480 {
481 MG_TRIANGLE_PEAU* tri=insere_triangle(face,mgno1,mgno2,tab[0],mgmai,MAGIC::ORIGINE::IMPOSE);
482 MG_TRIANGLE_PEAU* tri2=insere_triangle(face,mgno2,mgno3,tab[0],mgmai,MAGIC::ORIGINE::IMPOSE);
483 oriente_tri(tri,xyzext);
484 oriente_tri(tri2,xyzext);
485 }
486 if (num3==1)
487 {
488 MG_TRIANGLE_PEAU* tri=insere_triangle(face,mgno1,mgno2,tab[0],mgmai,MAGIC::ORIGINE::IMPOSE);
489 MG_TRIANGLE_PEAU* tri2=insere_triangle(face,mgno1,mgno3,tab[0],mgmai,MAGIC::ORIGINE::IMPOSE);
490 oriente_tri(tri,xyzext);
491 oriente_tri(tri2,xyzext);
492 }
493 }
494 if (nb==2)
495 {
496 if (num1==0)
497 {
498 MG_TRIANGLE_PEAU* tri=insere_triangle(face,mgno1,mgno2,tab[0],mgmai,MAGIC::ORIGINE::IMPOSE);
499 MG_TRIANGLE_PEAU* tri2=insere_triangle(face,mgno2,tab[0],tab[1],mgmai,MAGIC::ORIGINE::IMPOSE);
500 MG_TRIANGLE_PEAU* tri3=insere_triangle(face,mgno3,tab[0],tab[1],mgmai,MAGIC::ORIGINE::IMPOSE);
501 oriente_tri(tri,xyzext);
502 oriente_tri(tri2,xyzext);
503 oriente_tri(tri3,xyzext);
504 }
505 if (num2==0)
506 {
507 MG_TRIANGLE_PEAU* tri=insere_triangle(face,mgno1,mgno3,tab[0],mgmai,MAGIC::ORIGINE::IMPOSE);
508 MG_TRIANGLE_PEAU* tri2=insere_triangle(face,mgno3,tab[0],tab[1],mgmai,MAGIC::ORIGINE::IMPOSE);
509 MG_TRIANGLE_PEAU* tri3=insere_triangle(face,mgno2,tab[0],tab[1],mgmai,MAGIC::ORIGINE::IMPOSE);
510 oriente_tri(tri,xyzext);
511 oriente_tri(tri2,xyzext);
512 oriente_tri(tri3,xyzext);
513 }
514 if (num2==0)
515 {
516 MG_TRIANGLE_PEAU* tri=insere_triangle(face,mgno2,mgno3,tab[0],mgmai,MAGIC::ORIGINE::IMPOSE);
517 MG_TRIANGLE_PEAU* tri2=insere_triangle(face,mgno3,tab[0],tab[1],mgmai,MAGIC::ORIGINE::IMPOSE);
518 MG_TRIANGLE_PEAU* tri3=insere_triangle(face,mgno1,tab[0],tab[1],mgmai,MAGIC::ORIGINE::IMPOSE);
519 oriente_tri(tri,xyzext);
520 oriente_tri(tri2,xyzext);
521 oriente_tri(tri3,xyzext);
522 }
523 }
524 }
525 else if ((no1->get_solution()>=limit) && (no2->get_solution()>=limit) && (no3->get_solution()>=limit))
526 {
527 MG_NOEUD *mgno1=get_noeud_peau(no1,mgmai);
528 MG_NOEUD *mgno2=get_noeud_peau(no2,mgmai);
529 MG_NOEUD *mgno3=get_noeud_peau(no3,mgmai);
530 MG_TRIANGLE_PEAU* tri=insere_triangle(face,mgno1,mgno2,mgno3,mgmai,MAGIC::ORIGINE::TRIANGULATION);
531 oriente_tri(tri,xyzext);
532 }
533 else if (!((no1->get_solution()<limit) && (no2->get_solution()<limit) && (no3->get_solution()<limit)))
534 {
535 std::vector<MG_NOEUD*> tab;
536 int num1=-1;
537 int num2=-1;
538 int num3=-1;
539 if (no1->get_solution()>=limit)
540 {
541 MG_NOEUD* no=get_noeud_peau(no1,mgmai);
542 tab.push_back(no);
543 num1=1;
544 }
545 if (no2->get_solution()>=limit)
546 {
547 MG_NOEUD* no=get_noeud_peau(no2,mgmai);
548 tab.push_back(no);
549 num2=1;
550 }
551 if (no3->get_solution()>=limit)
552 {
553 MG_NOEUD* no=get_noeud_peau(no3,mgmai);
554 tab.push_back(no);
555 num3=1;
556 }
557 if (num1*num2<0) interpole_segment(mai,no1,no2,&tab,limit,mgmai);
558 if (num1*num3<0) interpole_segment(mai,no1,no3,&tab,limit,mgmai);
559 if (num2*num3<0) interpole_segment(mai,no2,no3,&tab,limit,mgmai);
560 int nb=tab.size();
561 if (nb==3)
562 {
563 MG_TRIANGLE_PEAU* tri=insere_triangle(face,tab[0],tab[1],tab[2],mgmai,MAGIC::ORIGINE::TRIANGULATION);
564 oriente_tri(tri,xyzext);
565 }
566 if (nb==4)
567 {
568 MG_TRIANGLE_PEAU* tri=insere_triangle(face,tab[0],tab[1],tab[2],mgmai,MAGIC::ORIGINE::TRIANGULATION);
569 MG_TRIANGLE_PEAU* tri2=insere_triangle(face,tab[1],tab[2],tab[3],mgmai,MAGIC::ORIGINE::TRIANGULATION);
570 oriente_tri(tri,xyzext);
571 oriente_tri(tri2,xyzext);
572 }
573 }
574 }
575 LISTE_MG_TRIANGLE::iterator it_tri;
576 for (MG_TRIANGLE* mgtri=mgmai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mgmai->get_suivant_triangle(it_tri))
577 {
578 MG_TRIANGLE_PEAU* tripeau=(MG_TRIANGLE_PEAU*)mgtri;
579 MG_TRIANGLE_PEAU* voisin1=recherche_voisin(tripeau->get_noeud1(),tripeau->get_noeud2(),tripeau);
580 MG_TRIANGLE_PEAU* voisin2=recherche_voisin(tripeau->get_noeud2(),tripeau->get_noeud3(),tripeau);
581 MG_TRIANGLE_PEAU* voisin3=recherche_voisin(tripeau->get_noeud3(),tripeau->get_noeud1(),tripeau);
582 tripeau->change_voisin1(voisin1);
583 tripeau->change_voisin2(voisin2);
584 tripeau->change_voisin3(voisin3);
585 tripeau->change_nouveau_numero(0);
586 }
587 int fin;
588 do
589 {
590 fin=1;
591 for (MG_TRIANGLE* mgtri=mgmai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mgmai->get_suivant_triangle(it_tri))
592 {
593 MG_TRIANGLE_PEAU *tripeau=(MG_TRIANGLE_PEAU*)mgtri;
594 if (tripeau->get_nouveau_numero()==0)
595 {
596 fin=0;
597 std::vector<MG_TRIANGLE_PEAU*> *peau=new std::vector<MG_TRIANGLE_PEAU*>;
598 lst_peau.push_back(peau);
599 tripeau->change_nouveau_numero(1);
600 peau->push_back(tripeau);
601 determine_peau(peau);
602 }
603 }
604 }
605 while (fin==0);
606 return mgmai;
607 }
608
609
610 void MGOPT_POSTTRAITEMENT::suppression_peaux_isoles(MG_MAILLAGE* mgmai)
611 {
612 affiche((char*)"Suppression des peaux isolées");
613
614 char message[500];
615 for (int cas=0;cas<2;cas++)
616 {
617 if (cas==0) affiche((char*)" Analyse initiale des peaux");
618 if (cas==1) affiche((char*)" Analyse finale des peaux");
619 int nbisole=0;
620 for (int i=0;i<lst_peau.size();i++)
621 {
622 int isole=1;
623 for (int j=0;j<lst_peau[i]->size();j++)
624 if ((*lst_peau[i])[j]->get_origine()==MAGIC::ORIGINE::IMPOSE) {isole=0;break;}
625 if (isole==1)
626 {
627 nbisole++;
628 for (int j=0;j<lst_peau[i]->size();j++)
629 {
630 mgmai->supprimer_mg_triangleid((*lst_peau[i])[j]->get_id());
631 }
632 lst_peau[i]->clear();
633 }
634 }
635 sprintf(message," %d peaux, %d non isoles, %d isoles",(int)lst_peau.size(),(int)lst_peau.size()-nbisole,nbisole);
636 affiche(message);
637 for (std::vector<std::vector<MG_TRIANGLE_PEAU*> *>::iterator j=lst_peau.end()-1;j>lst_peau.begin();j--)
638 if ((*j)->size()==0)
639 lst_peau.erase(j);
640 }
641 LISTE_MG_TRIANGLE::iterator itmg;
642 for (MG_TRIANGLE* tri=mgmai->get_premier_triangle(itmg);tri!=NULL;tri=mgmai->get_suivant_triangle(itmg))
643 {
644 if (tri->get_origine()==MAGIC::ORIGINE::IMPOSE)
645 {
646 tri->get_noeud1()->change_origine(MAGIC::ORIGINE::IMPOSE);
647 tri->get_noeud2()->change_origine(MAGIC::ORIGINE::IMPOSE);
648 tri->get_noeud3()->change_origine(MAGIC::ORIGINE::IMPOSE);
649 }
650 }
651
652 }
653
654
655 void MGOPT_POSTTRAITEMENT::oriente_tri(MG_TRIANGLE_PEAU* tri,double *xyz)
656 {
657 MG_NOEUD* no1=tri->get_noeud1();
658 MG_NOEUD* no2=tri->get_noeud2();
659 MG_NOEUD* no3=tri->get_noeud3();
660 OT_VECTEUR_3D n1n2(no1->get_coord(),no2->get_coord());
661 OT_VECTEUR_3D n1n3(no1->get_coord(),no3->get_coord());
662 OT_VECTEUR_3D normal=n1n2&n1n3;
663 OT_VECTEUR_3D dir(no1->get_coord(),xyz);
664 dir.norme();
665 normal.norme();
666 double ps=normal*dir;
667 if (ps<0) tri->inverse_sens();
668 }
669
670
671
672 MG_NOEUD* MGOPT_POSTTRAITEMENT::get_noeud_peau(FEM_NOEUD* no,MG_MAILLAGE* mai)
673 {
674 static std::map<std::string,MG_NOEUD*> correspond;
675 unsigned long id=no->get_id();
676 char message[255];
677 sprintf(message,"_%lu_",id);
678 std::string key=message;
679 MG_NOEUD* mgno=correspond[key];
680 if (mgno==NULL)
681 {
682 int origine=MAGIC::ORIGINE::TRIANGULATION;
683 if (((MG_NOEUD*)no->get_mg_element_maillage())->get_lien_topologie()->get_dimension()==1) origine=MAGIC::ORIGINE::TRIANGULATION_ARETE;
684 mgno=new MG_NOEUD(NULL,no->get_x(),no->get_y(),no->get_z(),origine);
685 mai->ajouter_mg_noeud(mgno);
686 correspond[key]=mgno;
687 }
688 return mgno;
689 }
690
691
692 int MGOPT_POSTTRAITEMENT::test_du_point_milieu(MG_NOEUD* no1,MG_NOEUD* no2,FEM_ELEMENT3* tet)
693 {
694 double *xyz1=no1->get_coord();
695 double *xyz2=no2->get_coord();
696 double xyz[3];
697 xyz[0]=0.5*(xyz1[0]+xyz2[0]);
698 xyz[1]=0.5*(xyz1[1]+xyz2[1]);
699 xyz[2]=0.5*(xyz1[2]+xyz2[2]);
700 FEM_MAILLAGE_OUTILS ot;
701 if (((ot.estdansletetra(tet,xyz[0],xyz[1],xyz[2])>>1)&1)==1) return 1;
702 //if (((MG_MAILLAGE_OUTILS::estdansletetra(tet,xyz[0],xyz[1],xyz[2])>>1)&1)==1) return 1;
703 return 0;
704 }
705
706
707
708 int MGOPT_POSTTRAITEMENT::interpole_segment(FEM_MAILLAGE* fem,FEM_NOEUD* no1,FEM_NOEUD* no2,std::vector<MG_NOEUD*> *tab,double limit,MG_MAILLAGE* mai,int creation)
709 {
710 static std::map<std::string,MG_NOEUD*> correspond;
711 unsigned long id1=no1->get_id();
712 unsigned long id2=no2->get_id();
713 char message[255];
714 sprintf(message,"_%lu_%lu_",id1,id2);
715 std::string key1=message;
716 sprintf(message,"_%lu_%lu_",id2,id1);
717 std::string key2=message;
718 double sol1=no1->get_solution();
719 double sol2=no2->get_solution();
720 MG_NOEUD* n1=(MG_NOEUD*)no1->get_mg_element_maillage();
721 MG_NOEUD* n2=(MG_NOEUD*)no2->get_mg_element_maillage();
722 MG_SEGMENT *seg=fem->get_mg_maillage()->get_mg_segment(n1->get_id(),n2->get_id());
723 int origine=MAGIC::ORIGINE::TRIANGULATION;
724 if (seg->get_lien_topologie()->get_dimension()==2) origine=MAGIC::ORIGINE::TRIANGULATION_ARETE;
725 if (seg->get_lien_topologie()->get_dimension()==1) origine=MAGIC::ORIGINE::TRIANGULATION_ARETE;
726
727 if (fabs(sol1-limit)<0.0000001)
728 {
729 sprintf(message,"%lu",id1);
730 std::string key=message;
731 MG_NOEUD* no=correspond[key];
732 if (no==NULL)
733 {
734 double *xyz1=no1->get_coord();
735 no=new MG_NOEUD(NULL,xyz1[0],xyz1[1],xyz1[2],origine);
736 mai->ajouter_mg_noeud(no);
737 correspond[key]=no;
738 }
739 int present=0;
740 for (int i=0;i<tab->size();i++)
741 if ((*tab)[i]==no) present=1;
742 if (present==0)
743 {
744 tab->push_back(no);
745 return 1;
746 }
747 else return 0;
748 }
749 if (fabs(sol2-limit)<0.0000001)
750 {
751 sprintf(message,"%lu",id2);
752 std::string key=message;
753 MG_NOEUD* no=correspond[key];
754 if (no==NULL)
755 {
756 double *xyz2=no2->get_coord();
757 no=new MG_NOEUD(NULL,xyz2[0],xyz2[1],xyz2[2],origine);
758 mai->ajouter_mg_noeud(no);
759 correspond[key]=no;
760 }
761 int present=0;
762 for (int i=0;i<tab->size();i++)
763 if ((*tab)[i]==no) present=1;
764 if (present==0)
765 {
766 tab->push_back(no);
767 return 1;
768 }
769 else return 0;
770
771 }
772
773 if (((sol1<limit) && (sol2>limit))||((sol1>limit) && (sol2<limit)))
774 {
775 MG_NOEUD* no=correspond[key1];
776 if (no==NULL) no=correspond[key2];
777 if ((no==NULL) && (creation==1))
778 {
779 double t=(limit-sol1)/(sol2-sol1);
780 double xyz[3];
781 double *xyz1=no1->get_coord();
782 double *xyz2=no2->get_coord();
783 xyz[0]=xyz1[0]+t*(xyz2[0]-xyz1[0]);
784 xyz[1]=xyz1[1]+t*(xyz2[1]-xyz1[1]);
785 xyz[2]=xyz1[2]+t*(xyz2[2]-xyz1[2]);
786 no=new MG_NOEUD(NULL,xyz[0],xyz[1],xyz[2],origine);
787 mai->ajouter_mg_noeud(no);
788 correspond[key1]=no;
789 }
790 if (no!=NULL)
791 {
792 tab->push_back(no);
793 return 1;
794 }
795 }
796 return 0;
797 }
798
799 void MGOPT_POSTTRAITEMENT::lire_params(char *fichier)
800 {
801 params.lire(fichier);
802 }
803
804 void MGOPT_POSTTRAITEMENT::posttraite(FEM_SOLUTION* sol, MG_GESTIONNAIRE& gest2,char *nomparam)
805 {
806 if (nomparam!=NULL) lire_params(nomparam);
807 affiche((char*)"Extraction du maillage de surface");
808 FEM_MAILLAGE* fem=sol->get_maillage();
809 int decoup=params.get_valeur("decoupage");
810 MG_MAILLAGE* mgmai;
811 if (decoup==0)
812 {
813 affiche((char*)" Découpage par mailles 3D entieres");
814 adapte_seuil(fem,sol);
815 mgmai=extract_skin_maille_entiere(fem,gest2);
816 }
817 if (decoup==1)
818 {
819 affiche((char*)" Découpage par isodensité");
820 double seuil=params.get_valeur("seuil");
821 std::string nomfich=params.get_nom("nomdensextra");
822 mgmai=extract_skin_par_decoupage(sol,seuil,gest2,nomfich.c_str());
823 }
824 suppression_peaux_isoles(mgmai);
825 affiche((char*)"Procedure de lissage");
826 int chen2005_debut=params.get_valeur("chen2005_debut");
827 int chen2008_debut=params.get_valeur("chen2008_debut");
828 int jiao2012_debut=params.get_valeur("jiao2012_debut");
829 int nana2015_debut=params.get_valeur("nana2015_debut");
830 int taubin1995_debut=params.get_valeur("taubin1995_debut");
831 int chen2005fait=0;
832 if (chen2005_debut==0) chen2005fait=1;
833 int chen2008fait=0;
834 if (chen2008_debut==0) chen2008fait=1;
835 int jiao2012fait=0;
836 if (jiao2012_debut==0) jiao2012fait=1;
837 int nana2015fait=0;
838 if (nana2015_debut==0) nana2015fait=1;
839 int taubin1995fait=0;
840 if (taubin1995_debut==0) taubin1995fait=1;
841
842 int fin=0;
843 int iteration=1;
844 do
845 {
846 if ((iteration>=chen2005_debut) && (chen2005fait==0))
847 {
848 char message[300];
849 sprintf(message, " Iteration %d : lissage de Chen 2005",iteration);
850 affiche(message);
851 double epsilon=params.get_valeur("chen2005_epsilon");
852 double sigma=params.get_valeur("chen2005_sigma");
853 int iter_max=params.get_valeur("chen2005_itermax");
854 int nbiter=lissage_chen2005(mgmai,gest2,epsilon,sigma,iter_max);
855 if (nbiter==iter_max) sprintf(message," Arrêt de la procédure de lissage de Chen2005 après %d itérations",nbiter);
856 else sprintf(message," Convergence de la procédure de lissage de Chen2005 après %d itérations",nbiter);
857 affiche(message);
858 chen2005fait=1;
859 iteration=iteration+nbiter;
860 }
861 else if ((iteration>=chen2008_debut) && (chen2008fait==0))
862 {
863 char message[300];
864 sprintf(message, " Iteration %d : lissage de Chen 2008",iteration);
865 affiche(message);
866 double epsilon=params.get_valeur("chen2008_epsilon");
867 double sigma=params.get_valeur("chen2008_sigma");
868 double gamma=params.get_valeur("chen2008_gamma");
869 int iter_max=params.get_valeur("chen2008_itermax");
870 int nbiter=lissage_chen2008(mgmai,gest2,sigma,gamma,epsilon,iter_max);
871 if (nbiter==iter_max) sprintf(message," Arrêt de la procédure de lissage de Chen2008 après %d itérations",nbiter);
872 else sprintf(message," Convergence de la procédure de lissage de Chen2008 après %d itérations",nbiter);
873 affiche(message);
874 chen2008fait=1;
875 iteration=iteration+nbiter;
876 }
877 else if ((iteration>=jiao2012_debut) && (jiao2012fait==0))
878 {
879 char message[300];
880 sprintf(message, " Iteration %d : lissage de Jiao 2012",iteration);
881 affiche(message);
882 int iter_max=params.get_valeur("jiao2012_itermax");
883 int nbiter=lissage_jiao2012(mgmai,gest2,iter_max);
884 if (nbiter==iter_max) sprintf(message," Arrêt de la procédure de lissage de Jiao2012 après %d itérations",nbiter);
885 else sprintf(message," Convergence de la procédure de lissage de Jiao2012 après %d itérations",nbiter);
886 affiche(message);
887 jiao2012fait=1;
888 iteration=iteration+nbiter;
889 }
890 else if ((iteration>=nana2015_debut) && (nana2015fait==0))
891 {
892 char message[300];
893 sprintf(message, " Iteration %d : lissage de Nana 2015",iteration);
894 affiche(message);
895 int iter_max=params.get_valeur("nana2015_itermax");
896 int nbiter=lissage_nana2015(mgmai,gest2,iter_max);
897 if (nbiter==iter_max) sprintf(message," Arrêt de la procédure de lissage de nana2015 après %d itérations",nbiter);
898 else sprintf(message," Convergence de la procédure de lissage de nana2015 après %d itérations",nbiter);
899 affiche(message);
900 nana2015fait=1;
901 iteration=iteration+nbiter;
902 }
903 else if ((iteration>=taubin1995_debut) && (taubin1995fait==0))
904 {
905 char message[300];
906 sprintf(message, "Lissage de Taubin 1995");
907 affiche(message);
908 double lambda=params.get_valeur("taubin1995_lambda");
909 double nu=params.get_valeur("taubin1995_nu");
910 double epsilon=params.get_valeur("taubin1995_epsilon");
911 double sigma=params.get_valeur("taubin1995_sigma");
912 double gamma_ =params.get_valeur("taubin1995_sigma");
913 int filtre=params.get_valeur("taubin1995_filtre");
914 int iter_max=params.get_valeur("taubin1995_itermax");
915 int itr_taubin=params.get_valeur("taubin1995_itertaubmax");
916 int nbiter=lissage_taubin1995(mgmai,gest2,lambda,nu,epsilon,sigma,gamma_,filtre, iter_max, itr_taubin);
917 if (nbiter==iter_max) sprintf(message," Arrêt de la procédure de lissage de taubin1995 après %d itérations",nbiter);
918 else sprintf(message," Convergence de la procédure de lissage de taubin1995 après %d itérations",nbiter);
919 affiche(message);
920 taubin1995fait=1;
921 iteration=iteration+nbiter;
922 }
923 else iteration++;
924 if (chen2005fait==1)
925 if (chen2008fait==1)
926 if (jiao2012fait==1)
927 if (nana2015fait==1)
928 if (taubin1995fait==1)
929 fin=1;
930 }
931 while (fin==0);
932
933
934 }
935
936
937 MG_MAILLAGE* MGOPT_POSTTRAITEMENT::extract_skin_maille_entiere(FEM_MAILLAGE* mai,MG_GESTIONNAIRE &gest2)
938 {
939 //Menu de la methode de lissage
940 affiche((char*)"Extraction du maillage de surface");
941 int coderesu = 0;
942 int mai2_id;
943 int imp=params.get_valeur("consimpose");
944 int opti=params.get_valeur("consoptimise");
945 int m_auto=params.get_valeur("consnooptimise");
946 if (opti==1) conserve(MAGIC::ORIGINE::OPTIMISE);
947 if (imp==1) conserve(MAGIC::ORIGINE::IMPOSE);
948 if (m_auto==1) conserve(MAGIC::ORIGINE::MAILLEUR_AUTO);
949 copieorigine(mai);
950 MG_MAILLAGE* mg_mai = (MG_MAILLAGE*)mai->get_mg_maillage();
951 //gain_poids(mg_mai,gest2);
952 int reactiv=params.get_valeur("reactivation");
953 if (reactiv == 1)
954 {
955 reactivation(mg_mai,gest2);
956 }
957 affiche((char*)" Analyse des cas non manifold");
958 do
959 {
960 int nbmaniare,nbmanino,nbpeau;
961 coderesu = extract_skin(mg_mai,gest2,nbpeau,nbmaniare,nbmanino,&mai2_id);
962 char message[500];
963 sprintf(message," %d peaux. %d manifold par arete. %d manifold par noeud",nbpeau,nbmaniare,nbmanino);
964 affiche(message);
965 // gain_poids(mg_mai,gest2);
966 }
967 while (coderesu == 0);
968
969 MG_MAILLAGE* mg_mai2=gest2.get_mg_maillageid(mai2_id);
970
971 return mg_mai2;
972
973 }
974
975
976 void MGOPT_POSTTRAITEMENT::adapte_seuil(class FEM_MAILLAGE* fem,FEM_SOLUTION* solution)
977 {
978 double seuil=params.get_valeur("seuil");
979 solution->active_solution(0);
980 LISTE_FEM_ELEMENT3::iterator it;
981 for (FEM_ELEMENT3 *tet=fem->get_premier_element3(it);tet!=NULL;tet=fem->get_suivant_element3(it))
982 {
983 if (((MG_TETRA*)tet->get_mg_element_maillage())->get_origine()!=MAGIC::ORIGINE::IMPOSE)
984 if (tet->get_solution()>seuil)
985 ((MG_TETRA*)tet->get_mg_element_maillage())->change_origine(MAGIC::ORIGINE::OPTIMISE);
986 else
987 ((MG_TETRA*)tet->get_mg_element_maillage())->change_origine(MAGIC::ORIGINE::MAILLEUR_AUTO);
988
989 }
990 }
991
992
993 //---------------------------- Lissage Chen 2005 Gilles Philippe -------------------------------------------------------------------------
994 int MGOPT_POSTTRAITEMENT::lissage_chen2005(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, double epsilon, double sigma, int iter_max)
995 {
996 //Methode de lissage inspiree de Chen(2005) par Gilles Philipe Picher Martel
997 double un_sur_pi = 1./M_PI;
998 int compteur = 0;
999 int fin = 0;
1000
1001
1002 do
1003 {
1004 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales;
1005 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales2;
1006 TPL_LISTE_ENTITE<double> liste_wij;
1007 LISTE_MG_TRIANGLE::iterator it_tri;
1008 int k = 0; //pour identifier les triangles pour liste_normales et liste_wij
1009 for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
1010 {
1011 MG_TRIANGLE_PEAU* mgtri_i = (MG_TRIANGLE_PEAU*)mgtri;
1012 OT_VECTEUR_3D normal_f_i = mgtri_i->calcul_normal();
1013 normal_f_i.norme();
1014 liste_normales2.ajouter(normal_f_i);
1015 //Remplissage de la liste des voisins du triangle i
1016 TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*> liste_voisins;
1017 MG_NOEUD* noeud1 = mgtri_i->get_noeud1();
1018 double nb_voisins1 = noeud1->get_lien_triangle()->get_nb();
1019 for (int j = 0;j<nb_voisins1;j++)
1020 {
1021 MG_TRIANGLE_PEAU* mgtri_1 = (MG_TRIANGLE_PEAU*) noeud1->get_lien_triangle()->get(j);
1022 liste_voisins.ajouter(mgtri_1);
1023 }
1024 MG_NOEUD* noeud2 = mgtri_i->get_noeud2();
1025 double nb_voisins2 = noeud2->get_lien_triangle()->get_nb();
1026 for (int j = 0;j<nb_voisins2;j++)
1027 {
1028 MG_TRIANGLE_PEAU* mgtri_2 = (MG_TRIANGLE_PEAU*) noeud2->get_lien_triangle()->get(j);
1029 liste_voisins.ajouter(mgtri_2);
1030 }
1031 MG_NOEUD* noeud3 = mgtri_i->get_noeud3();
1032 double nb_voisins3 = noeud3->get_lien_triangle()->get_nb();
1033 for (int j = 0;j<nb_voisins3;j++)
1034 {
1035 MG_TRIANGLE_PEAU* mgtri_3 = (MG_TRIANGLE_PEAU*) noeud3->get_lien_triangle()->get(j);
1036 liste_voisins.ajouter(mgtri_3);
1037 }
1038 liste_voisins.supprimer(mgtri_i);
1039 int nb_voisins = liste_voisins.get_nb();
1040 double w_ij = 1./nb_voisins;
1041 double phi_i_min = 10.;
1042 double s_i = 0.0;
1043 double phi_im = 0.0;
1044 double *phi_ij = new double[nb_voisins];
1045 OT_VECTEUR_3D normal_f_i_mean(0.,0.,0.);
1046 OT_VECTEUR_3D eta_i(0.,0.,0.);
1047 TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*>::ITERATEUR it;
1048 int j = 0;
1049 for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
1050 {
1051 OT_VECTEUR_3D normal_f_j = mgtri_j->calcul_normal();
1052 //1-Calculer la normale moyenne pour chaque triangle
1053 normal_f_i_mean = normal_f_i_mean + w_ij*normal_f_j;
1054 //2.1-On calcul l'angle entre normal_f_i et normal_f_j pour j allant de 1 a Nb_voisins
1055 double prod_scalaire = normal_f_i*normal_f_j;
1056 if (prod_scalaire > 1.)
1057 {
1058 prod_scalaire = 1.;
1059 }
1060 if (prod_scalaire < -1.)
1061 {
1062 prod_scalaire = -1.;
1063 }
1064 phi_ij[j] = acos(prod_scalaire)*un_sur_pi;
1065 //2.2-On trouve le plus petit des angles et la normale heta_i correspondante
1066 if (phi_ij[j] < phi_i_min)
1067 {
1068 phi_i_min = phi_ij[j];
1069 eta_i = normal_f_j;
1070 }
1071 //3.1-On calcul l'angle moyen phi_im
1072 phi_im = phi_im + w_ij*phi_ij[j];
1073 j++;
1074 }
1075 normal_f_i_mean.norme();
1076 j = 0;
1077 for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
1078 {
1079 //3.2-Calcul de s_i selon la variance
1080 s_i = s_i + w_ij*pow((phi_ij[j] - phi_im),2);
1081 j++;
1082 }
1083 delete[] phi_ij;
1084 //4-On calcule une nouvelle normale pour chaque triangle
1085 double pond;
1086 int num=params.get_valeur("chen2005_filtre");
1087 if (num==1) pond=ponderation_gaussian(s_i,sigma);
1088 else if (num==2) pond=ponderation_laplacian(s_i,sigma);
1089 else if (num==3) pond=ponderation_elfallahford(s_i,sigma);
1090 OT_VECTEUR_3D normal_f_i_new = pond*normal_f_i_mean + (1. - pond)*eta_i;
1091 normal_f_i_new.norme();
1092 liste_normales.ajouter(normal_f_i_new);
1093 liste_wij.ajouter(w_ij);
1094 mgtri->change_nouveau_numero(k);
1095 k++;
1096 }
1097
1098 LISTE_MG_NOEUD::iterator it_no;
1099 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1100 {
1101 int nb_voisins_j = noeud_i->get_lien_triangle()->get_nb();
1102 double w_ij_prime = 0.0;
1103 OT_VECTEUR_3D v_temp(0.,0.,0.);
1104 OT_VECTEUR_3D v_i(noeud_i->get_x(),noeud_i->get_y(),noeud_i->get_z());
1105 for(int j=0;j<nb_voisins_j;j++)
1106 {
1107 MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
1108 //On calcule le centroide cj du triangle mgtri_j
1109 MG_NOEUD* n1 = mgtri_j->get_noeud1();
1110 MG_NOEUD* n2 = mgtri_j->get_noeud2();
1111 MG_NOEUD* n3 = mgtri_j->get_noeud3();
1112 double cj_x = 0.333333333333333*(n1->get_x() + n2->get_x() + n3->get_x());
1113 double cj_y = 0.333333333333333*(n1->get_y() + n2->get_y() + n3->get_y());
1114 double cj_z = 0.333333333333333*(n1->get_z() + n2->get_z() + n3->get_z());
1115 //On forme le vecteur vi_cj
1116 OT_VECTEUR_3D vi_cj(cj_x - noeud_i->get_x(),cj_y - noeud_i->get_y(),cj_z - noeud_i->get_z());
1117 OT_VECTEUR_3D normal_f_i_new = liste_normales.get(mgtri_j->get_nouveau_numero());
1118 // w_ij_prime correspond a la somme des aires des triangles voisins du noeuds
1119 OT_VECTEUR_3D AB(n2->get_x() - n1->get_x(),n2->get_y() - n1->get_y(),n2->get_z() - n1->get_z());
1120 OT_VECTEUR_3D AC(n3->get_x() - n1->get_x(),n3->get_y() - n1->get_y(),n3->get_z() - n1->get_z());
1121 OT_VECTEUR_3D prodvect = AB&AC;
1122 double w_ij = 0.5*prodvect.get_longueur();
1123 w_ij_prime = w_ij_prime + w_ij;
1124 v_temp = v_temp + w_ij*(vi_cj*normal_f_i_new)*normal_f_i_new;
1125 }
1126 //5-On met a jour la position des noeuds
1127 v_i = v_i + v_temp/w_ij_prime;
1128 int origine = noeud_i->get_origine();
1129 if (origine != MAGIC::ORIGINE::IMPOSE)
1130 {
1131 noeud_i->change_x(v_i.get_x());
1132 noeud_i->change_y(v_i.get_y());
1133 noeud_i->change_z(v_i.get_z());
1134 }
1135 }
1136 //Critere d'arret de l'algorithme
1137 int l=0;
1138 int nb_tri = mg_mai->get_nb_mg_triangle();
1139 for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
1140 {
1141 MG_TRIANGLE_PEAU* mgtri_i = (MG_TRIANGLE_PEAU*)mgtri;
1142 OT_VECTEUR_3D normal_f_i = liste_normales2.get(mgtri_i->get_nouveau_numero());
1143 OT_VECTEUR_3D normal_f_i_new = liste_normales.get(mgtri_i->get_nouveau_numero());
1144 double critere = 1. - normal_f_i*normal_f_i_new;
1145 if (critere <= epsilon) l++;
1146 }
1147 double tolerance = 0.01*nb_tri;
1148 if (nb_tri - l <= 0) fin = 1;
1149 compteur++;
1150 }
1151 while ((fin == 0) && (compteur < iter_max));
1152
1153 return compteur;
1154 }
1155
1156 //---------------------------- Lissage Jiao 2012 -------------------------------------------------------------------------
1157 int MGOPT_POSTTRAITEMENT::lissage_jiao2012(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, int iter_max)
1158 {
1159 // Lissage global avec methode de lissage inspiree de JIAO IMR2012 par Jean Christophe sept 2013
1160 int compteur = 0;
1161
1162 do
1163 {
1164 vector<double> nouv_position_x;
1165 vector<double> nouv_position_y;
1166 vector<double> nouv_position_z;
1167 LISTE_MG_NOEUD::iterator it_no;
1168 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1169 {
1170 int origine = noeud_i->get_origine();
1171 if (origine != MAGIC::ORIGINE::IMPOSE)
1172 {
1173 int nb_voisins_j = noeud_i->get_lien_triangle()->get_nb();
1174 double wij = 0.0;
1175 double wij_sommej = 0.0;
1176 OT_VECTEUR_3D v_temp(0.,0.,0.);
1177 OT_VECTEUR_3D v_i(noeud_i->get_x(),noeud_i->get_y(),noeud_i->get_z());
1178 for(int j=0;j<nb_voisins_j;j++)
1179 {
1180 MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
1181 //On calcule le centroide cj du triangle mgtri_j
1182 MG_NOEUD* n1 = mgtri_j->get_noeud1();
1183 MG_NOEUD* n2 = mgtri_j->get_noeud2();
1184 MG_NOEUD* n3 = mgtri_j->get_noeud3();
1185 double cj_x = 0.333333333333333*(n1->get_x() + n2->get_x() + n3->get_x());
1186 double cj_y = 0.333333333333333*(n1->get_y() + n2->get_y() + n3->get_y());
1187 double cj_z = 0.333333333333333*(n1->get_z() + n2->get_z() + n3->get_z());
1188 //On forme le vecteur vi_cj et le vecteur cj
1189 OT_VECTEUR_3D cj(cj_x ,cj_y,cj_z);
1190 OT_VECTEUR_3D vi_cj(cj_x - noeud_i->get_x(),cj_y - noeud_i->get_y(),cj_z - noeud_i->get_z());
1191 wij=vi_cj.get_longueur();
1192 wij_sommej=wij_sommej+wij;
1193 v_temp = v_temp + (wij*cj);
1194 }
1195 //5-On calcule la nouvelle position des noeuds et on affecte au tableau temporaire
1196 v_i =v_temp/wij_sommej;
1197 nouv_position_x.push_back(v_i.get_x());
1198 nouv_position_y.push_back(v_i.get_y());
1199 nouv_position_z.push_back(v_i.get_z());
1200 }
1201 }
1202 //On actualise la position des noeuds
1203 int ind_noeud=0;
1204 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1205 {
1206 int origine = noeud_i->get_origine();
1207 if (origine != MAGIC::ORIGINE::IMPOSE)
1208 {
1209 noeud_i->change_x(nouv_position_x[ind_noeud]);
1210 noeud_i->change_y(nouv_position_y[ind_noeud]);
1211 noeud_i->change_z(nouv_position_z[ind_noeud]);
1212 ind_noeud++;
1213 }
1214 }
1215 //Critere d'arret de l'algorithme
1216 compteur++;
1217 }
1218 while (compteur < iter_max);
1219
1220 return compteur;
1221 }
1222
1223 //---------------------------- Lissage Chen 2008 -------------------------------------------------------------------------
1224 int MGOPT_POSTTRAITEMENT::lissage_chen2008(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, double sigma, double gamma, double epsilon, int iter_max)
1225 {
1226 //Lissage global inspire de Chen(2008) corrige par Jean Christophe sept 2013
1227 double un_sur_pi = 1./M_PI;
1228 int compteur = 0;
1229 int fin = 0;
1230 compteur = 0;
1231
1232 do
1233 {
1234 vector<double> nouv_position_x;
1235 vector<double> nouv_position_y;
1236 vector<double> nouv_position_z;
1237 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales;
1238 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales2;
1239 TPL_LISTE_ENTITE<double> liste_wij;
1240 LISTE_MG_TRIANGLE::iterator it_tri;
1241 int k = 0; //pour identifier les triangles pour liste_normales et liste_wij
1242 for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
1243 {
1244 MG_TRIANGLE_PEAU* mgtri_i = (MG_TRIANGLE_PEAU*)mgtri;
1245 OT_VECTEUR_3D normal_f_i = mgtri_i->calcul_normal();
1246 normal_f_i.norme();
1247 liste_normales2.ajouter(normal_f_i);
1248 //Remplissage de la liste des voisins du triangle i
1249 TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*> liste_voisins;
1250 MG_NOEUD* noeud1 = mgtri_i->get_noeud1();
1251 double nb_voisins1 = noeud1->get_lien_triangle()->get_nb();
1252 for (int j = 0;j<nb_voisins1;j++)
1253 {
1254 MG_TRIANGLE_PEAU* mgtri_1 = (MG_TRIANGLE_PEAU*) noeud1->get_lien_triangle()->get(j);
1255 liste_voisins.ajouter(mgtri_1);
1256 }
1257 MG_NOEUD* noeud2 = mgtri_i->get_noeud2();
1258 double nb_voisins2 = noeud2->get_lien_triangle()->get_nb();
1259 for (int j = 0;j<nb_voisins2;j++)
1260 {
1261 MG_TRIANGLE_PEAU* mgtri_2 = (MG_TRIANGLE_PEAU*) noeud2->get_lien_triangle()->get(j);
1262 liste_voisins.ajouter(mgtri_2);
1263 }
1264 MG_NOEUD* noeud3 = mgtri_i->get_noeud3();
1265 double nb_voisins3 = noeud3->get_lien_triangle()->get_nb();
1266 for (int j = 0;j<nb_voisins3;j++)
1267 {
1268 MG_TRIANGLE_PEAU* mgtri_3 = (MG_TRIANGLE_PEAU*) noeud3->get_lien_triangle()->get(j);
1269 liste_voisins.ajouter(mgtri_3);
1270 }
1271 liste_voisins.supprimer(mgtri_i);
1272 int nb_voisins = liste_voisins.get_nb();
1273 double w_ij = 1./nb_voisins;
1274 double phi_i_min = 10.;
1275 double s_i = 0.0;
1276 double phi_im = 0.0;
1277 double *phi_ij = new double[nb_voisins];
1278 OT_VECTEUR_3D normal_f_i_mean(0.,0.,0.);
1279 normal_f_i_mean = normal_f_i;
1280 OT_VECTEUR_3D eta_i(0.,0.,0.);
1281 TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*>::ITERATEUR it;
1282 int j = 0;
1283 for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
1284 {
1285 OT_VECTEUR_3D normal_f_j = mgtri_j->calcul_normal();
1286 //1-Calculer la normale moyenne pour chaque triangle
1287 normal_f_i_mean = normal_f_i_mean + normal_f_j;
1288 //2.1-On calcule l'angle entre normal_f_i et normal_f_j pour j allant de 1 a Nb_voisins
1289 double prod_scalaire = normal_f_i*normal_f_j;
1290 if (prod_scalaire > 1.)
1291 {
1292 prod_scalaire = 1.;
1293 }
1294 if (prod_scalaire < -1.)
1295 {
1296 prod_scalaire = -1.;
1297 }
1298 phi_ij[j] = acos(prod_scalaire)*un_sur_pi;
1299 //2.2-On trouve le plus petit des angles et la normale heta_i correspondante
1300 if (phi_ij[j] < phi_i_min)
1301 {
1302 phi_i_min = phi_ij[j];
1303 eta_i = normal_f_j;
1304 }
1305 //3.1-On calcule l'angle moyen phi_im
1306 phi_im = phi_im + w_ij*phi_ij[j];
1307 j++;
1308 }
1309 normal_f_i_mean.norme();
1310 j = 0;
1311 for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
1312 {
1313 //3.2-Calcul de s_i selon la variance
1314 s_i = s_i + w_ij*pow((phi_ij[j] - phi_im),2);
1315 j++;
1316 }
1317 delete[] phi_ij;
1318 //4-On calcule une nouvelle normale pour chaque triangle
1319 double pond;
1320 int num=params.get_valeur("chen2008_filtre");
1321 if (num==1) pond=ponderation_gaussian(s_i,sigma);
1322 else if (num==2) pond=ponderation_laplacian(s_i,sigma);
1323 else if (num==3) pond=ponderation_elfallahford(s_i,sigma);
1324 OT_VECTEUR_3D normal_f_i_new = pond*normal_f_i_mean + (1. - pond)*eta_i;
1325 normal_f_i_new.norme();
1326 liste_normales.ajouter(normal_f_i_new);
1327 liste_wij.ajouter(w_ij);
1328 mgtri->change_nouveau_numero(k);
1329 k++;
1330 }
1331
1332 LISTE_MG_NOEUD::iterator it_no;
1333 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1334 {
1335 int origine = noeud_i->get_origine();
1336 if (origine != MAGIC::ORIGINE::IMPOSE)
1337 {
1338 int nb_voisins_j = noeud_i->get_lien_triangle()->get_nb();
1339 double w_ij_prime = 0.0;
1340 OT_VECTEUR_3D v_temp(0.,0.,0.);
1341 OT_VECTEUR_3D v_i(noeud_i->get_x(),noeud_i->get_y(),noeud_i->get_z());
1342 for(int j=0;j<nb_voisins_j;j++)
1343 {
1344 MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
1345 //On calcule le centroide cj du triangle mgtri_j
1346 MG_NOEUD* n1 = mgtri_j->get_noeud1();
1347 MG_NOEUD* n2 = mgtri_j->get_noeud2();
1348 MG_NOEUD* n3 = mgtri_j->get_noeud3();
1349 double cj_x = 0.333333333333333*(n1->get_x() + n2->get_x() + n3->get_x());
1350 double cj_y = 0.333333333333333*(n1->get_y() + n2->get_y() + n3->get_y());
1351 double cj_z = 0.333333333333333*(n1->get_z() + n2->get_z() + n3->get_z());
1352 //On forme le vecteur vi_cj
1353 OT_VECTEUR_3D vi_cj(cj_x - noeud_i->get_x(),cj_y - noeud_i->get_y(),cj_z - noeud_i->get_z());
1354 OT_VECTEUR_3D normal_f_i_new = liste_normales.get(mgtri_j->get_nouveau_numero());
1355 v_temp = v_temp + (vi_cj*normal_f_i_new)*normal_f_i_new;
1356 }
1357 //5-On met a jour la position des noeuds
1358 v_i = v_i + (gamma/(2*nb_voisins_j))*v_temp;
1359 nouv_position_x.push_back(v_i.get_x());
1360 nouv_position_y.push_back(v_i.get_y());
1361 nouv_position_z.push_back(v_i.get_z());
1362 }
1363 }
1364
1365 //On actualise la position des noeuds
1366 int ind_noeud=0;
1367 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1368 {
1369 int origine = noeud_i->get_origine();
1370 if (origine != MAGIC::ORIGINE::IMPOSE)
1371 {
1372 noeud_i->change_x(nouv_position_x[ind_noeud]);
1373 noeud_i->change_y(nouv_position_y[ind_noeud]);
1374 noeud_i->change_z(nouv_position_z[ind_noeud]);
1375 ind_noeud++;
1376 }
1377 }
1378
1379 //Critere d'arret de l'algorithme
1380 int l=0;
1381 int nb_tri = mg_mai->get_nb_mg_triangle();
1382 for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
1383 {
1384 MG_TRIANGLE_PEAU* mgtri_i = (MG_TRIANGLE_PEAU*)mgtri;
1385 OT_VECTEUR_3D normal_f_i = liste_normales2.get(mgtri_i->get_nouveau_numero());
1386 OT_VECTEUR_3D normal_f_i_new = liste_normales.get(mgtri_i->get_nouveau_numero());
1387 double critere = 1. - normal_f_i*normal_f_i_new;
1388 if (critere <= epsilon) l++;
1389 }
1390 double tolerance = 0.01*nb_tri;
1391 if (nb_tri - l <= 0) fin = 1;
1392 compteur++;
1393 }
1394 while ((fin == 0) && (compteur < iter_max));
1395
1396 return compteur;
1397
1398 }
1399
1400
1401 //---------------------------- Lissage Nana 2015 -------------------------------------------------------------------------
1402 int MGOPT_POSTTRAITEMENT::lissage_nana2015(MG_MAILLAGE* mg_mai, MG_GESTIONNAIRE& gest2, int iter_max)
1403 {
1404 // Lissage par la methode Nana(2015) par Alexandre Nana janvier 2015
1405 int fin = 0;
1406 int compteur = 0;
1407
1408 /// Calcul du volume initial
1409 double d1=0.;
1410 double v1=0.;
1411 LISTE_MG_TRIANGLE::iterator it;
1412 for (MG_TRIANGLE* ttr=mg_mai->get_premier_triangle(it);ttr!=NULL;ttr=mg_mai->get_suivant_triangle(it))
1413 {
1414 MG_TRIANGLE_PEAU* tri=(MG_TRIANGLE_PEAU*)ttr;
1415 if(tri->get_origine()!=MAGIC::ORIGINE::MAILLEUR_AUTO)
1416 {
1417 MG_NOEUD* no1=tri->get_noeud1();
1418 MG_NOEUD* no2=tri->get_noeud2();
1419 MG_NOEUD* no3=tri->get_noeud3();
1420 double *xyz1=no1->get_coord();
1421 double *xyz2=no2->get_coord();
1422 double *xyz3=no3->get_coord();
1423 OT_VECTEUR_3D vec1(xyz1,xyz2);
1424 OT_VECTEUR_3D vec2(xyz1,xyz3);
1425 OT_VECTEUR_3D pvec=vec2&vec1;
1426
1427 d1=pvec.get_longueur(); // En fait surface=pvec.get_longueur()/2. et det=2*surface
1428 OT_VECTEUR_3D N=pvec/(pvec.get_longueur());
1429 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}
1430 +(xyz1+(2/3.)*vec1+(1/6.)*vec2)
1431 +(xyz1+(1/6.)*vec1+(2/3.)*vec2));
1432 v1=v1+d1*N*F;
1433 }
1434 }
1435 cout << "Volume avant lissage = " << v1 << endl;
1436
1437
1438 /// detection du "bruit"
1439 double kM1=0.;
1440 double km1=0.;
1441 TPL_MAP_ENTITE<MG_NOEUD*> liste_nodes_bruit;
1442 TPL_MAP_ENTITE<MG_NOEUD*> liste_nodes_non_modifies;
1443 TPL_MAP_ENTITE<MG_NOEUD*> liste_nodes_aretes_vives;
1444 TPL_MAP_ENTITE<MG_NOEUD*>::ITERATEUR inode;
1445 TPL_MAP_ENTITE<MG_NOEUD*>::ITERATEUR inode2;
1446 TPL_MAP_ENTITE<MG_NOEUD*>::ITERATEUR inode3;
1447
1448
1449 LISTE_MG_NOEUD::iterator it_no;
1450 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1451 {
1452 if ((noeud_i->get_origine() != MAGIC::ORIGINE::IMPOSE))
1453 {
1454 TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*> liste_map_triangle;
1455 TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*>::ITERATEUR it;
1456 TPL_LISTE_ENTITE<MG_TRIANGLE_PEAU*> liste_tpl_triangle;
1457
1458 for (int k=0;k<noeud_i->get_lien_triangle()->get_nb();k++)
1459 {
1460 MG_TRIANGLE_PEAU* tri1= (MG_TRIANGLE_PEAU*)noeud_i->get_lien_triangle()->get(k);
1461 liste_map_triangle.ajouter(tri1);
1462 }
1463
1464 MG_TRIANGLE_PEAU* tri2=liste_map_triangle.get_premier(it);
1465 MG_NOEUD* na=tri2->get_noeud1();
1466 MG_NOEUD* nb=tri2->get_noeud2();
1467 MG_NOEUD* nc=tri2->get_noeud3();
1468 MG_NOEUD* n1=NULL;
1469 MG_NOEUD* n2=NULL;
1470 MG_NOEUD* n3=NULL;
1471
1472 if (na==noeud_i) {n1=na;n2=nb;n3=nc;}
1473 if (nb==noeud_i) {n1=nb;n2=nc;n3=na;}
1474 if (nc==noeud_i) {n1=nc;n2=na;n3=nb;}
1475
1476 liste_tpl_triangle.ajouter(tri2);
1477
1478 while (liste_map_triangle.get_nb()!=liste_tpl_triangle.get_nb())
1479 for (MG_TRIANGLE_PEAU* tri=liste_map_triangle.get_premier(it);tri;tri=liste_map_triangle.get_suivant(it))
1480 {
1481 if (tri!=tri2)
1482 {
1483 MG_NOEUD* noa=tri->get_noeud1();
1484 MG_NOEUD* nob=tri->get_noeud2();
1485 MG_NOEUD* noc=tri->get_noeud3();
1486 MG_NOEUD* n4=NULL;
1487 MG_NOEUD* n5=NULL;
1488 MG_NOEUD* n6=NULL;
1489
1490 if (noa==noeud_i) {n4=noa;n5=nob;n6=noc;}
1491 if (nob==noeud_i) {n4=nob;n5=noc;n6=noa;}
1492 if (noc==noeud_i) {n4=noc;n5=noa;n6=nob;}
1493
1494 if (n1==n4)
1495 if (n3==n5)
1496 {
1497 liste_tpl_triangle.ajouter(tri);
1498 n1=n4;
1499 n2=n5;
1500 n3=n6;
1501 if (liste_map_triangle.get_nb()==liste_tpl_triangle.get_nb()) break;
1502 }
1503 }
1504 }
1505
1506 double K=0.;
1507 double H=0.;
1508
1509 double beta=0.;
1510 double surface=0.;
1511 double som1=0.;
1512 double som2=0.;
1513 double som3=0.;
1514 double som4=0.;
1515
1516 for (int i=0;i<liste_tpl_triangle.get_nb();i++)
1517 {
1518 MG_TRIANGLE_PEAU* tri00=NULL;
1519 MG_TRIANGLE_PEAU* tri01=NULL;
1520
1521 if (!(i==(liste_tpl_triangle.get_nb()-1))) {tri00=liste_tpl_triangle.get(i);tri01=liste_tpl_triangle.get(i+1);}
1522 if (i==(liste_tpl_triangle.get_nb()-1)) {tri00=liste_tpl_triangle.get(i);tri01=tri2;}
1523
1524 MG_NOEUD* noeud1=NULL;
1525 MG_NOEUD* noeud2=NULL;
1526 MG_NOEUD* noeud3=NULL;
1527 MG_NOEUD* noeud4=NULL;
1528 MG_NOEUD* noeud5=NULL;
1529 MG_NOEUD* noeud6=NULL;
1530
1531 MG_NOEUD* nd1=tri00->get_noeud1();
1532 MG_NOEUD* nd2=tri00->get_noeud2();
1533 MG_NOEUD* nd3=tri00->get_noeud3();
1534 MG_NOEUD* nd4=tri01->get_noeud1();
1535 MG_NOEUD* nd5=tri01->get_noeud2();
1536 MG_NOEUD* nd6=tri01->get_noeud3();
1537
1538 if (nd1==noeud_i) {noeud1=nd1;noeud2=nd2;noeud3=nd3;}
1539 if (nd2==noeud_i) {noeud1=nd2;noeud2=nd3;noeud3=nd1;}
1540 if (nd3==noeud_i) {noeud1=nd3;noeud2=nd1;noeud3=nd2;}
1541 if (nd4==noeud_i) {noeud4=nd4;noeud5=nd5;noeud6=nd6;}
1542 if (nd5==noeud_i) {noeud4=nd5;noeud5=nd6;noeud6=nd4;}
1543 if (nd6==noeud_i) {noeud4=nd6;noeud5=nd4;noeud6=nd5;}
1544
1545 double *xyz1=noeud1->get_coord();
1546 double *xyz2=noeud2->get_coord();
1547 double *xyz3=noeud3->get_coord();
1548 double *xyz4=noeud4->get_coord();
1549 double *xyz5=noeud5->get_coord();
1550 double *xyz6=noeud6->get_coord();
1551
1552 OT_VECTEUR_3D vec1(xyz1,xyz2);
1553 OT_VECTEUR_3D vec2(xyz1,xyz3);
1554 OT_VECTEUR_3D vec3(xyz2,xyz3);
1555 OT_VECTEUR_3D vec4(xyz4,xyz5);
1556 OT_VECTEUR_3D vec5(xyz4,xyz6);
1557 OT_VECTEUR_3D vec6(xyz5,xyz6);
1558
1559
1560 // COURBURE GAUSSIENNE
1561 // Calcul de alpha (i) de chaque triangle lié au noeud
1562 double cosalpha=((vec1*vec2)/(vec1.get_longueur()*vec2.get_longueur()));
1563 double alpha=acos(cosalpha);
1564 double cotalpha=(cosalpha/sin(alpha));
1565 som1=som1+alpha;
1566 // Calcul Aire triangle 1
1567 OT_VECTEUR_3D pvec1=vec1&vec2;
1568 surface=0.5*pvec1.get_longueur();
1569 som2=som2+surface;
1570 // Calcul de I = longueur de l'arête opposée à l'angle alpha
1571 double I=vec3.get_longueur();
1572 som3=som3+(I*I*cotalpha);
1573 // COURBURE MOYENNE
1574 // Calcul de la longueur de l'arête commune au deux triangles adjacents ftr et fnd
1575 double L=vec2.get_longueur();
1576 // Calcul de beta, l'angle entre les normales de 2 triangles adjacents
1577 beta=M_PI-calcul_angle(tri00,tri01);
1578 som4=som4+(beta*L);
1579 }
1580
1581 // Courbure de Gauss, moyenne, max et min
1582 K=((2.*M_PI-som1)/((0.5*som2)-(0.125*som3)));
1583 H=((0.25*som4)/((0.5*som2)-(0.125*som3)));
1584 if (H*H-K>0.) kM1=H+sqrt((H)*(H)-(K)); else kM1=H;
1585 if (H*H-K>0.) km1=H-sqrt((H)*(H)-(K)); else km1=H;
1586
1587 if ((fabs(kM1)>1.e-06) && (fabs(km1)>1.e-06))
1588 liste_nodes_bruit.ajouter(noeud_i);
1589 }
1590 }
1591 cout << "nb_noeuds_bruit = " << liste_nodes_bruit.get_nb() << endl;
1592
1593
1594 do
1595 {
1596 /// Lissage Laplacien des noeuds bruites
1597 vector<double> nouv_position_x;
1598 vector<double> nouv_position_y;
1599 vector<double> nouv_position_z;
1600 for(MG_NOEUD* noeud_i=liste_nodes_bruit.get_premier(inode);noeud_i;noeud_i=liste_nodes_bruit.get_suivant(inode))
1601 {
1602 int nb_voisins_j = noeud_i->get_lien_triangle()->get_nb();
1603 double wij = 0.0;
1604 double wij_sommej = 0.0;
1605 OT_VECTEUR_3D v_temp(0.,0.,0.);
1606 OT_VECTEUR_3D v_i(noeud_i->get_x(),noeud_i->get_y(),noeud_i->get_z());
1607 for(int j=0;j<nb_voisins_j;j++)
1608 {
1609 MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
1610 //On calcule le centroide cj du triangle mgtri_j
1611 MG_NOEUD* n1 = mgtri_j->get_noeud1();
1612 MG_NOEUD* n2 = mgtri_j->get_noeud2();
1613 MG_NOEUD* n3 = mgtri_j->get_noeud3();
1614 double cj_x = 0.333333333333333*(n1->get_x() + n2->get_x() + n3->get_x());
1615 double cj_y = 0.333333333333333*(n1->get_y() + n2->get_y() + n3->get_y());
1616 double cj_z = 0.333333333333333*(n1->get_z() + n2->get_z() + n3->get_z());
1617 //On forme le vecteur vi_cj et le vecteur cj
1618 OT_VECTEUR_3D cj(cj_x ,cj_y,cj_z);
1619 OT_VECTEUR_3D vi_cj(cj_x - noeud_i->get_x(),cj_y - noeud_i->get_y(),cj_z - noeud_i->get_z());
1620 wij=vi_cj.get_longueur();
1621 wij_sommej=wij_sommej+wij;
1622 v_temp = v_temp + (wij*cj);
1623 }
1624 v_i =v_temp/wij_sommej;
1625
1626 /*
1627 OT_VECTEUR_3D v_temp(0.,0.,0.);
1628 OT_VECTEUR_3D v_i(noeud_i->get_x(),noeud_i->get_y(),noeud_i->get_z());
1629 TPL_MAP_ENTITE<MG_NOEUD*> listenoeud;
1630 TPL_MAP_ENTITE<MG_NOEUD*>::ITERATEUR in;
1631 for(int j=0;j<noeud_i->get_lien_triangle()->get_nb();j++)
1632 {
1633 MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
1634 MG_NOEUD* n1 = mgtri_j->get_noeud1();
1635 MG_NOEUD* n2 = mgtri_j->get_noeud2();
1636 MG_NOEUD* n3 = mgtri_j->get_noeud3();
1637 listenoeud.ajouter(n1);
1638 listenoeud.ajouter(n2);
1639 listenoeud.ajouter(n3);
1640 }
1641 listenoeud.supprimer(noeud_i);
1642 for (MG_NOEUD* no=listenoeud.get_premier(in);no;no=listenoeud.get_suivant(in))
1643 v_temp=v_temp+no->get_coord();
1644
1645 v_i = v_temp/listenoeud.get_nb();
1646 for (MG_NOEUD* no=listenoeud.get_premier(in);no;no=listenoeud.get_suivant(in))
1647 listenoeud.supprimer(no);
1648 */
1649
1650 nouv_position_x.push_back(v_i.get_x());
1651 nouv_position_y.push_back(v_i.get_y());
1652 nouv_position_z.push_back(v_i.get_z());
1653 }
1654
1655
1656 /// Mise a jour de la position des noeuds
1657 int ind_noeud=0;
1658 for(MG_NOEUD* noeud_i=liste_nodes_bruit.get_premier(inode);noeud_i;noeud_i=liste_nodes_bruit.get_suivant(inode))
1659 {
1660 noeud_i->change_x(nouv_position_x[ind_noeud]);
1661 noeud_i->change_y(nouv_position_y[ind_noeud]);
1662 noeud_i->change_z(nouv_position_z[ind_noeud]);
1663 ind_noeud++;
1664 }
1665
1666
1667 /// Calcul du volume apres chaque iteration
1668 double d2=0.;
1669 double v2=0.;
1670 for (MG_TRIANGLE* ttr=mg_mai->get_premier_triangle(it);ttr!=NULL;ttr=mg_mai->get_suivant_triangle(it))
1671 {
1672 MG_TRIANGLE_PEAU* tri=(MG_TRIANGLE_PEAU*)ttr;
1673 if(tri->get_origine()!=MAGIC::ORIGINE::MAILLEUR_AUTO)
1674 {
1675 MG_NOEUD* no1=tri->get_noeud1();
1676 MG_NOEUD* no2=tri->get_noeud2();
1677 MG_NOEUD* no3=tri->get_noeud3();
1678 double *xyz1=no1->get_coord();
1679 double *xyz2=no2->get_coord();
1680 double *xyz3=no3->get_coord();
1681 OT_VECTEUR_3D vec1(xyz1,xyz2);
1682 OT_VECTEUR_3D vec2(xyz1,xyz3);
1683 OT_VECTEUR_3D pvec=vec2&vec1;
1684
1685 d2=pvec.get_longueur();
1686 OT_VECTEUR_3D N =pvec/(pvec.get_longueur());
1687 OT_VECTEUR_3D F3=(1/6.)*(1/3.)*((xyz1+(1/6.)*vec1+(1/6.)*vec2)
1688 +(xyz1+(2/3.)*vec1+(1/6.)*vec2)
1689 +(xyz1+(1/6.)*vec1+(2/3.)*vec2));
1690 v2=v2+d2*N*F3;
1691 }
1692 }
1693 //cout << v2 << endl;
1694
1695 /// Critere d'arret volumique
1696 if ((fabs(v1) - fabs(v2)) < -1000.) fin=1;
1697 if (((fabs(v1) - fabs(v2)) < -1000.) || (compteur == iter_max-1)) cout << "Volume apres lissage = " << v2 << endl;
1698 compteur++;
1699 }
1700
1701 while ((fin == 0) && (compteur < iter_max));
1702
1703
1704 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1705 if ((noeud_i->get_origine() != MAGIC::ORIGINE::IMPOSE))
1706 {
1707 noeud_i->change_solution(0.);
1708 noeud_i->change_nouveau_numero(0);
1709 }
1710
1711 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1712 for(MG_NOEUD* noeud=liste_nodes_bruit.get_premier(inode);noeud;noeud=liste_nodes_bruit.get_suivant(inode))
1713 if ((noeud_i->get_origine() != MAGIC::ORIGINE::IMPOSE) && (noeud_i != noeud))
1714 {
1715 liste_nodes_non_modifies.ajouter(noeud_i);
1716 noeud_i->change_nouveau_numero(1);
1717 }
1718
1719 cout << "nb_noeuds_intact = " << liste_nodes_non_modifies.get_nb() << endl;
1720
1721 /// Detection des noeuds "features"
1722 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);
1723 gest2.ajouter_mg_solution(sol);
1724 sol->change_legende(0,"courbure_max");
1725 sol->change_legende(1,"courbure_min");
1726 int t=0;
1727 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1728 {
1729 if ((noeud_i->get_origine() != MAGIC::ORIGINE::IMPOSE))
1730 {
1731 TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*> liste_map_triangle;
1732 TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*>::ITERATEUR it;
1733 TPL_LISTE_ENTITE<MG_TRIANGLE_PEAU*> liste_tpl_triangle;
1734
1735 for (int k=0;k<noeud_i->get_lien_triangle()->get_nb();k++)
1736 {
1737 MG_TRIANGLE_PEAU* tri1= (MG_TRIANGLE_PEAU*)noeud_i->get_lien_triangle()->get(k);
1738 liste_map_triangle.ajouter(tri1);
1739 }
1740
1741 MG_TRIANGLE_PEAU* tri2=liste_map_triangle.get_premier(it);
1742 MG_NOEUD* na=tri2->get_noeud1();
1743 MG_NOEUD* nb=tri2->get_noeud2();
1744 MG_NOEUD* nc=tri2->get_noeud3();
1745 MG_NOEUD* n1=NULL;
1746 MG_NOEUD* n2=NULL;
1747 MG_NOEUD* n3=NULL;
1748
1749 if (na==noeud_i) {n1=na;n2=nb;n3=nc;}
1750 if (nb==noeud_i) {n1=nb;n2=nc;n3=na;}
1751 if (nc==noeud_i) {n1=nc;n2=na;n3=nb;}
1752
1753 liste_tpl_triangle.ajouter(tri2);
1754
1755 while (liste_map_triangle.get_nb()!=liste_tpl_triangle.get_nb())
1756 for (MG_TRIANGLE_PEAU* tri=liste_map_triangle.get_premier(it);tri;tri=liste_map_triangle.get_suivant(it))
1757 {
1758 if (tri!=tri2)
1759 {
1760 MG_NOEUD* noa=tri->get_noeud1();
1761 MG_NOEUD* nob=tri->get_noeud2();
1762 MG_NOEUD* noc=tri->get_noeud3();
1763 MG_NOEUD* n4=NULL;
1764 MG_NOEUD* n5=NULL;
1765 MG_NOEUD* n6=NULL;
1766
1767 if (noa==noeud_i) {n4=noa;n5=nob;n6=noc;}
1768 if (nob==noeud_i) {n4=nob;n5=noc;n6=noa;}
1769 if (noc==noeud_i) {n4=noc;n5=noa;n6=nob;}
1770
1771 if (n1==n4)
1772 if (n3==n5)
1773 {
1774 liste_tpl_triangle.ajouter(tri);
1775 n1=n4;
1776 n2=n5;
1777 n3=n6;
1778 if (liste_map_triangle.get_nb()==liste_tpl_triangle.get_nb()) break;
1779 }
1780 }
1781 }
1782
1783 double K=0.;
1784 double H=0.;
1785
1786 double beta=0.;
1787 double surface=0.;
1788 double som1=0.;
1789 double som2=0.;
1790 double som3=0.;
1791 double som4=0.;
1792
1793 for (int i=0;i<liste_tpl_triangle.get_nb();i++)
1794 {
1795 MG_TRIANGLE_PEAU* tri00=NULL;
1796 MG_TRIANGLE_PEAU* tri01=NULL;
1797
1798 if (!(i==(liste_tpl_triangle.get_nb()-1))) {tri00=liste_tpl_triangle.get(i);tri01=liste_tpl_triangle.get(i+1);}
1799 if (i==(liste_tpl_triangle.get_nb()-1)) {tri00=liste_tpl_triangle.get(i);tri01=tri2;}
1800
1801 MG_NOEUD* noeud1=NULL;
1802 MG_NOEUD* noeud2=NULL;
1803 MG_NOEUD* noeud3=NULL;
1804 MG_NOEUD* noeud4=NULL;
1805 MG_NOEUD* noeud5=NULL;
1806 MG_NOEUD* noeud6=NULL;
1807
1808 MG_NOEUD* nd1=tri00->get_noeud1();
1809 MG_NOEUD* nd2=tri00->get_noeud2();
1810 MG_NOEUD* nd3=tri00->get_noeud3();
1811 MG_NOEUD* nd4=tri01->get_noeud1();
1812 MG_NOEUD* nd5=tri01->get_noeud2();
1813 MG_NOEUD* nd6=tri01->get_noeud3();
1814
1815 if (nd1==noeud_i) {noeud1=nd1;noeud2=nd2;noeud3=nd3;}
1816 if (nd2==noeud_i) {noeud1=nd2;noeud2=nd3;noeud3=nd1;}
1817 if (nd3==noeud_i) {noeud1=nd3;noeud2=nd1;noeud3=nd2;}
1818 if (nd4==noeud_i) {noeud4=nd4;noeud5=nd5;noeud6=nd6;}
1819 if (nd5==noeud_i) {noeud4=nd5;noeud5=nd6;noeud6=nd4;}
1820 if (nd6==noeud_i) {noeud4=nd6;noeud5=nd4;noeud6=nd5;}
1821
1822 double *xyz1=noeud1->get_coord();
1823 double *xyz2=noeud2->get_coord();
1824 double *xyz3=noeud3->get_coord();
1825 double *xyz4=noeud4->get_coord();
1826 double *xyz5=noeud5->get_coord();
1827 double *xyz6=noeud6->get_coord();
1828
1829 OT_VECTEUR_3D vec1(xyz1,xyz2);
1830 OT_VECTEUR_3D vec2(xyz1,xyz3);
1831 OT_VECTEUR_3D vec3(xyz2,xyz3);
1832 OT_VECTEUR_3D vec4(xyz4,xyz5);
1833 OT_VECTEUR_3D vec5(xyz4,xyz6);
1834 OT_VECTEUR_3D vec6(xyz5,xyz6);
1835
1836
1837 // COURBURE GAUSSIENNE
1838 // Calcul de alpha (i) de chaque triangle lié au noeud
1839 double cosalpha=((vec1*vec2)/(vec1.get_longueur()*vec2.get_longueur()));
1840 double alpha=acos(cosalpha);
1841 double cotalpha=(cosalpha/sin(alpha));
1842 som1=som1+alpha;
1843 // Calcul Aire triangle 1
1844 OT_VECTEUR_3D pvec1=vec1&vec2;
1845 surface=0.5*pvec1.get_longueur();
1846 som2=som2+surface;
1847 // Calcul de I = longueur de l'arête opposée à l'angle alpha
1848 double I=vec3.get_longueur();
1849 som3=som3+(I*I*cotalpha);
1850 // COURBURE MOYENNE
1851 // Calcul de la longueur de l'arête commune au deux triangles adjacents ftr et fnd
1852 double L=vec2.get_longueur();
1853 // Calcul de beta, l'angle entre les normales de 2 triangles adjacents
1854 beta=M_PI-calcul_angle(tri00,tri01);
1855 som4=som4+(beta*L);
1856 }
1857
1858 // Courbure de Gauss
1859 K=((2.*M_PI-som1)/((0.5*som2)-(0.125*som3)));
1860 H=((0.25*som4)/((0.5*som2)-(0.125*som3)));
1861 if (H*H-K>0.) kM1=H+sqrt((H)*(H)-(K)); else kM1=H;
1862 if (H*H-K>0.) km1=H-sqrt((H)*(H)-(K)); else km1=H;
1863
1864 if ((km1 > 1.e-03)) liste_nodes_aretes_vives.ajouter(noeud_i);
1865 sol->ecrire(kM1,t,0);
1866 sol->ecrire(km1,t,1);
1867 }
1868 t++;
1869 }
1870
1871 cout << "nb_noeuds_aretes_vives = " << liste_nodes_aretes_vives.get_nb() << endl;
1872
1873 /// Projection des noeuds "features" dans le plan des noeuds nonmodifies
1874 vector<double> nouv_position_x;
1875 vector<double> nouv_position_y;
1876 vector<double> nouv_position_z;
1877 for(MG_NOEUD* noeud_i=liste_nodes_aretes_vives.get_premier(inode3);noeud_i;noeud_i=liste_nodes_aretes_vives.get_suivant(inode3))
1878 {
1879 double wij = 0.0;
1880 double wij_sommej = 0.0;
1881 OT_VECTEUR_3D v_temp(0.,0.,0.);
1882 OT_VECTEUR_3D v_i(noeud_i->get_x(),noeud_i->get_y(),noeud_i->get_z());
1883 TPL_MAP_ENTITE<MG_NOEUD*>::ITERATEUR in;
1884 for(int j=0;j<noeud_i->get_lien_triangle()->get_nb();j++)
1885 {
1886 MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
1887 MG_NOEUD* n1 = mgtri_j->get_noeud1();
1888 MG_NOEUD* n2 = mgtri_j->get_noeud2();
1889 MG_NOEUD* n3 = mgtri_j->get_noeud3();
1890 double cj_x = 0.333333333333333*(n1->get_x() + n2->get_x() + n3->get_x());
1891 double cj_y = 0.333333333333333*(n1->get_y() + n2->get_y() + n3->get_y());
1892 double cj_z = 0.333333333333333*(n1->get_z() + n2->get_z() + n3->get_z());
1893 OT_VECTEUR_3D cj(cj_x ,cj_y,cj_z);
1894 OT_VECTEUR_3D vi_cj(cj_x - noeud_i->get_x(),cj_y - noeud_i->get_y(),cj_z - noeud_i->get_z());
1895 wij=exp(-vi_cj.get_longueur());
1896 wij_sommej=wij_sommej+wij;
1897 v_temp = v_temp + (wij*cj);
1898 }
1899 v_i = v_temp/wij_sommej;
1900
1901 double cj_x = 0.;
1902 double cj_y = 0.;
1903 double cj_z = 0.;
1904 OT_VECTEUR_3D normale(0.,0.,0.);
1905 for (int j = 0;j<noeud_i->get_lien_triangle()->get_nb();j++)
1906 {
1907 MG_TRIANGLE_PEAU* mgtri=NULL;
1908 MG_TRIANGLE_PEAU* mgtri_peau = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
1909 if (mgtri_peau->get_origine() != MAGIC::ORIGINE::IMPOSE)
1910 {
1911 MG_NOEUD* no1=NULL;
1912 MG_NOEUD* no2=NULL;
1913 MG_NOEUD* no3=NULL;
1914 MG_NOEUD* na = mgtri_peau->get_noeud1();
1915 MG_NOEUD* nb = mgtri_peau->get_noeud2();
1916 MG_NOEUD* nc = mgtri_peau->get_noeud3();
1917 if ((na==noeud_i)) {no1=na;no2=nb;no3=nc;}
1918 if ((nb==noeud_i)) {no1=nb;no2=nc;no3=na;}
1919 if ((nc==noeud_i)) {no1=nc;no2=na;no3=nb;}
1920 if ((no2->get_nouveau_numero() == 1) && (no3->get_nouveau_numero() == 1))
1921 {
1922 cj_x = 0.333333333333333*(no1->get_x() + no2->get_x() + no3->get_x());
1923 cj_y = 0.333333333333333*(no1->get_y() + no2->get_y() + no3->get_y());
1924 cj_z = 0.333333333333333*(no1->get_z() + no2->get_z() + no3->get_z());
1925 normale = mgtri_peau->calcul_normal();
1926 }
1927 }
1928 }
1929 normale.norme();
1930 double a = normale.get_x();
1931 double b = normale.get_y();
1932 double c = normale.get_z();
1933 double d = -(a*cj_x + b*cj_y + c*cj_z);
1934 //double k = -(a*v_i.get_x() + b*v_i.get_y() + c*v_i.get_z() + d)/(a*a + b*b + c*c);
1935 double k = -(a*cj_x + b*cj_y + c*cj_z + d)/(a*a + b*b + c*c);
1936
1937 nouv_position_x.push_back(v_i.get_x() + k*a);
1938 nouv_position_y.push_back(v_i.get_y() + k*b);
1939 nouv_position_z.push_back(v_i.get_z() + k*c);
1940 }
1941
1942 /// Mise a jour finale de la position des noeuds
1943 int ind_noeud=0;
1944 for(MG_NOEUD* noeud_i=liste_nodes_aretes_vives.get_premier(inode3);noeud_i;noeud_i=liste_nodes_aretes_vives.get_suivant(inode3))
1945 {
1946 if ((noeud_i->get_origine() != MAGIC::ORIGINE::IMPOSE))
1947 {
1948 noeud_i->change_x(nouv_position_x[ind_noeud]);
1949 noeud_i->change_y(nouv_position_y[ind_noeud]);
1950 noeud_i->change_z(nouv_position_z[ind_noeud]);
1951 ind_noeud++;
1952 }
1953 }
1954
1955 /// Calcul du volume final
1956 double d3=0.;
1957 double v3=0.;
1958 for (MG_TRIANGLE* ttr=mg_mai->get_premier_triangle(it);ttr!=NULL;ttr=mg_mai->get_suivant_triangle(it))
1959 {
1960 MG_TRIANGLE_PEAU* tri=(MG_TRIANGLE_PEAU*)ttr;
1961 if(tri->get_origine()!=MAGIC::ORIGINE::MAILLEUR_AUTO)
1962 {
1963 MG_NOEUD* no1=tri->get_noeud1();
1964 MG_NOEUD* no2=tri->get_noeud2();
1965 MG_NOEUD* no3=tri->get_noeud3();
1966 double *xyz1=no1->get_coord();
1967 double *xyz2=no2->get_coord();
1968 double *xyz3=no3->get_coord();
1969 OT_VECTEUR_3D vec1(xyz1,xyz2);
1970 OT_VECTEUR_3D vec2(xyz1,xyz3);
1971 OT_VECTEUR_3D pvec=vec2&vec1;
1972
1973 d3=pvec.get_longueur();
1974 OT_VECTEUR_3D N =pvec/(pvec.get_longueur());
1975 OT_VECTEUR_3D F4=(1/6.)*(1/3.)*((xyz1+(1/6.)*vec1+(1/6.)*vec2)
1976 +(xyz1+(2/3.)*vec1+(1/6.)*vec2)
1977 +(xyz1+(1/6.)*vec1+(2/3.)*vec2));
1978 v3=v3+d3*N*F4;
1979 }
1980 }
1981 cout << "Volume final apres projection = " << v3 << endl;
1982 return (compteur);
1983 }
1984
1985 //---------------------------- Cycle Taubin 1995-------------------------------------------------------------------------
1986 int MGOPT_POSTTRAITEMENT::cycle_taubin1995(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, double lambda, double nu_)
1987 {
1988
1989 /////partie lambda du lissage
1990 vector<double> nouv_position_x;
1991 vector<double> nouv_position_y;
1992 vector<double> nouv_position_z;
1993 LISTE_MG_NOEUD::iterator it_no;
1994 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
1995 {
1996 int origine = noeud_i->get_origine();
1997 if ((origine != MAGIC::ORIGINE::IMPOSE)&& (noeud_i->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&& (origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&&(noeud_i->get_lien_topologie()==NULL))///////////////////////////////////////////////////////////////////////////////
1998 {
1999 int nb_voisins_j = noeud_i->get_lien_triangle()->get_nb();
2000 double delta_x = 0.0;
2001 double delta_y = 0.0;
2002 double delta_z = 0.0;
2003
2004
2005 double v_x_done[nb_voisins_j];
2006 double v_y_done[nb_voisins_j];
2007 double v_z_done[nb_voisins_j];
2008 double v_i_x = 0.0;
2009 double v_i_y = 0.0;
2010 double v_i_z = 0.0;
2011
2012 for(int j=0;j<nb_voisins_j;j++)
2013 {
2014 if (j==0)
2015 {
2016 for (int jj=0;jj<nb_voisins_j;jj++)
2017 {
2018 v_x_done[jj] = 0.0;
2019 v_y_done[jj] = 0.0;
2020 v_z_done[jj] = 0.0;
2021 }
2022 }
2023
2024
2025 MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
2026 MG_NOEUD* v_1 = mgtri_j->get_noeud1();
2027 MG_NOEUD* v_2 = mgtri_j->get_noeud2();
2028 MG_NOEUD* v_3 = mgtri_j->get_noeud3();
2029 double v_x = noeud_i->get_x();//v_1->get_x();
2030 double v_y = noeud_i->get_y();//v_1->get_y();
2031 double v_z = noeud_i->get_z();//v_1->get_z();
2032 double v_1_x = v_1->get_x();
2033 double v_1_y = v_1->get_y();
2034 double v_1_z = v_1->get_z();
2035 double v_2_x = v_2->get_x();
2036 double v_2_y = v_2->get_y();
2037 double v_2_z = v_2->get_z();
2038 double v_3_x = v_3->get_x();
2039 double v_3_y = v_3->get_y();
2040 double v_3_z = v_3->get_z();
2041
2042 if (((v_1_x == v_x)&&(v_1_y == v_y)&&(v_1_y == v_y)) && (((v_2_x!=v_x_done[0])&&(v_2_y!=v_y_done[0])&&(v_2_z!=v_z_done[0]))||((v_2_x!=v_x_done[1])&&(v_2_y!=v_y_done[1])&&(v_2_z!=v_z_done[1]))||((v_2_x!=v_x_done[2])&&(v_2_y!=v_y_done[2])&&(v_2_z!=v_z_done[2]))||((v_2_x!=v_x_done[3])&&(v_2_y!=v_y_done[3])&&(v_2_z!=v_z_done[3]))||((v_2_x!=v_x_done[4])&&(v_2_y!=v_y_done[4])&&(v_2_z!=v_z_done[4]))||((v_2_x!=v_x_done[5])&&(v_2_y!=v_y_done[5])&&(v_2_z!=v_z_done[5]))||((v_2_x!=v_x_done[6])&&(v_2_y!=v_y_done[6])&&(v_2_z!=v_z_done[6]))||((v_2_x!=v_x_done[7])&&(v_2_y!=v_y_done[7])&&(v_2_z!=v_z_done[7]))||((v_2_x!=v_x_done[8])&&(v_2_y!=v_y_done[8])&&(v_2_z!=v_z_done[8]))||((v_2_x!=v_x_done[9])&&(v_2_y!=v_y_done[9])&&(v_2_z!=v_z_done[9]))))
2043 {
2044 v_i_x = v_2_x;
2045 v_i_y = v_2_y;
2046 v_i_z = v_2_z;
2047 }
2048 else if (((v_3_x == v_x)&&(v_3_y == v_y)&&(v_3_y == v_y)) && (((v_1_x!=v_x_done[0])&&(v_1_y!=v_y_done[0])&&(v_1_z!=v_z_done[0]))||((v_1_x!=v_x_done[1])&&(v_1_y!=v_y_done[1])&&(v_1_z!=v_z_done[1]))||((v_1_x!=v_x_done[2])&&(v_1_y!=v_y_done[2])&&(v_1_z!=v_z_done[2]))||((v_1_x!=v_x_done[3])&&(v_1_y!=v_y_done[3])&&(v_1_z!=v_z_done[3]))||((v_1_x!=v_x_done[4])&&(v_1_y!=v_y_done[4])&&(v_1_z!=v_z_done[4]))||((v_1_x!=v_x_done[5])&&(v_1_y!=v_y_done[5])&&(v_1_z!=v_z_done[5]))||((v_1_x!=v_x_done[6])&&(v_1_y!=v_y_done[6])&&(v_1_z!=v_z_done[6]))||((v_1_x!=v_x_done[7])&&(v_1_y!=v_y_done[7])&&(v_1_z!=v_z_done[7]))||((v_1_x!=v_x_done[8])&&(v_1_y!=v_y_done[8])&&(v_1_z!=v_z_done[8]))||((v_1_x!=v_x_done[9])&&(v_1_y!=v_y_done[9])&&(v_1_z!=v_z_done[9]))))
2049 {
2050 v_i_x = v_1_x;
2051 v_i_y = v_1_y;
2052 v_i_z = v_1_z;
2053 }
2054 else
2055 {
2056 v_i_x = v_3_x;
2057 v_i_y = v_3_y;
2058 v_i_z = v_3_z;
2059 }
2060
2061 v_x_done[j] = v_i_x;
2062 v_y_done[j] = v_i_y;
2063 v_z_done[j] = v_i_z;
2064
2065 double multiplicateur = (1.0/nb_voisins_j);
2066 delta_x = delta_x+(multiplicateur*(v_i_x-v_x));
2067 delta_y = delta_y+(multiplicateur*(v_i_y-v_y));
2068 delta_z = delta_z+(multiplicateur*(v_i_z-v_z));
2069
2070 }
2071 double i_x =noeud_i->get_x();
2072 double i_y =noeud_i->get_y();
2073 double i_z =noeud_i->get_z();
2074 double x_prime = (i_x)+(lambda*delta_x);
2075 double y_prime = (i_y)+(lambda*delta_y);
2076 double z_prime = (i_z)+(lambda*delta_z);
2077
2078 //5-On calcule la nouvelle position des noeuds et on affecte au tableau temporaire
2079 OT_VECTEUR_3D v_premier (x_prime,y_prime,z_prime);
2080 nouv_position_x.push_back(v_premier.get_x());
2081 nouv_position_y.push_back(v_premier.get_y());
2082 nouv_position_z.push_back(v_premier.get_z());
2083 }
2084 }
2085 //On actualise la position des noeuds
2086 int ind_noeud=0;
2087 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
2088 {
2089 int origine = noeud_i->get_origine();
2090 if ((origine != MAGIC::ORIGINE::IMPOSE)&& (noeud_i->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&& (origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&&(noeud_i->get_lien_topologie()==NULL))///////////////////////////////////////////////////////////////////////////////
2091 {
2092 noeud_i->change_x(nouv_position_x[ind_noeud]);
2093 noeud_i->change_y(nouv_position_y[ind_noeud]);
2094 noeud_i->change_z(nouv_position_z[ind_noeud]);
2095 ind_noeud++;
2096 }
2097 }
2098
2099
2100 //partie nu du lissage
2101 vector<double> nouv_position2_x;
2102 vector<double> nouv_position2_y;
2103 vector<double> nouv_position2_z;
2104 for (MG_NOEUD* noeud_i2=mg_mai->get_premier_noeud(it_no);noeud_i2!=NULL;noeud_i2=mg_mai->get_suivant_noeud(it_no))
2105 {
2106 int origine = noeud_i2->get_origine();
2107 if ((origine != MAGIC::ORIGINE::IMPOSE)&& (noeud_i2->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&& (origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&&(noeud_i2->get_lien_topologie()==NULL))///////////////////////////////////////////////////////////////////////////////
2108 {
2109 int nb_voisins_j = noeud_i2->get_lien_triangle()->get_nb();
2110 double delta_x = 0.0;
2111 double delta_y = 0.0;
2112 double delta_z = 0.0;
2113 double v_x_done[10];
2114 double v_y_done[10];
2115 double v_z_done[10];
2116 double v_i_x = 0.0;
2117 double v_i_y = 0.0;
2118 double v_i_z = 0.0;
2119
2120 for(int j=0;j<nb_voisins_j;j++)
2121 {
2122 if (j==0)
2123 {
2124 for (int jj=0;jj<10;jj++)
2125 {
2126 v_x_done[jj] = 0.0;
2127 v_y_done[jj] = 0.0;
2128 v_z_done[jj] = 0.0;
2129 }
2130 }
2131
2132
2133 MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i2->get_lien_triangle()->get(j);
2134 MG_NOEUD* v_1 = mgtri_j->get_noeud1();
2135 MG_NOEUD* v_2 = mgtri_j->get_noeud2();
2136 MG_NOEUD* v_3 = mgtri_j->get_noeud3();
2137 double v_x = noeud_i2->get_x();//v_1->get_x();
2138 double v_y = noeud_i2->get_y();//v_1->get_y();
2139 double v_z = noeud_i2->get_z();//v_1->get_z();
2140 double v_1_x = v_1->get_x();
2141 double v_1_y = v_1->get_y();
2142 double v_1_z = v_1->get_z();
2143 double v_2_x = v_2->get_x();
2144 double v_2_y = v_2->get_y();
2145 double v_2_z = v_2->get_z();
2146 double v_3_x = v_3->get_x();
2147 double v_3_y = v_3->get_y();
2148 double v_3_z = v_3->get_z();
2149
2150 if (((v_1_x == v_x)&&(v_1_y == v_y)&&(v_1_y == v_y)) && (((v_2_x!=v_x_done[0])&&(v_2_y!=v_y_done[0])&&(v_2_z!=v_z_done[0]))||((v_2_x!=v_x_done[1])&&(v_2_y!=v_y_done[1])&&(v_2_z!=v_z_done[1]))||((v_2_x!=v_x_done[2])&&(v_2_y!=v_y_done[2])&&(v_2_z!=v_z_done[2]))||((v_2_x!=v_x_done[3])&&(v_2_y!=v_y_done[3])&&(v_2_z!=v_z_done[3]))||((v_2_x!=v_x_done[4])&&(v_2_y!=v_y_done[4])&&(v_2_z!=v_z_done[4]))||((v_2_x!=v_x_done[5])&&(v_2_y!=v_y_done[5])&&(v_2_z!=v_z_done[5]))||((v_2_x!=v_x_done[6])&&(v_2_y!=v_y_done[6])&&(v_2_z!=v_z_done[6]))||((v_2_x!=v_x_done[7])&&(v_2_y!=v_y_done[7])&&(v_2_z!=v_z_done[7]))||((v_2_x!=v_x_done[8])&&(v_2_y!=v_y_done[8])&&(v_2_z!=v_z_done[8]))||((v_2_x!=v_x_done[9])&&(v_2_y!=v_y_done[9])&&(v_2_z!=v_z_done[9]))))
2151 {
2152 v_i_x = v_2_x;
2153 v_i_y = v_2_y;
2154 v_i_z = v_2_z;
2155 }
2156 else if (((v_3_x == v_x)&&(v_3_y == v_y)&&(v_3_y == v_y)) && (((v_1_x!=v_x_done[0])&&(v_1_y!=v_y_done[0])&&(v_1_z!=v_z_done[0]))||((v_1_x!=v_x_done[1])&&(v_1_y!=v_y_done[1])&&(v_1_z!=v_z_done[1]))||((v_1_x!=v_x_done[2])&&(v_1_y!=v_y_done[2])&&(v_1_z!=v_z_done[2]))||((v_1_x!=v_x_done[3])&&(v_1_y!=v_y_done[3])&&(v_1_z!=v_z_done[3]))||((v_1_x!=v_x_done[4])&&(v_1_y!=v_y_done[4])&&(v_1_z!=v_z_done[4]))||((v_1_x!=v_x_done[5])&&(v_1_y!=v_y_done[5])&&(v_1_z!=v_z_done[5]))||((v_1_x!=v_x_done[6])&&(v_1_y!=v_y_done[6])&&(v_1_z!=v_z_done[6]))||((v_1_x!=v_x_done[7])&&(v_1_y!=v_y_done[7])&&(v_1_z!=v_z_done[7]))||((v_1_x!=v_x_done[8])&&(v_1_y!=v_y_done[8])&&(v_1_z!=v_z_done[8]))||((v_1_x!=v_x_done[9])&&(v_1_y!=v_y_done[9])&&(v_1_z!=v_z_done[9]))))
2157 {
2158 v_i_x = v_1_x;
2159 v_i_y = v_1_y;
2160 v_i_z = v_1_z;
2161 }
2162 else
2163 {
2164 v_i_x = v_3_x;
2165 v_i_y = v_3_y;
2166 v_i_z = v_3_z;
2167 }
2168
2169 v_x_done[j] = v_i_x;
2170 v_y_done[j] = v_i_y;
2171 v_z_done[j] = v_i_z;
2172
2173 double multiplicateur = (1.0/nb_voisins_j);
2174 delta_x = delta_x+(multiplicateur*(v_i_x-v_x));
2175 delta_y = delta_y+(multiplicateur*(v_i_y-v_y));
2176 delta_z = delta_z+(multiplicateur*(v_i_z-v_z));
2177
2178 }
2179 double i_x =noeud_i2->get_x();
2180 double i_y =noeud_i2->get_y();
2181 double i_z =noeud_i2->get_z();
2182 double x_prime = (i_x)+(nu_*delta_x);
2183 double y_prime = (i_y)+(nu_*delta_y);
2184 double z_prime = (i_z)+(nu_*delta_z);
2185
2186 //5-On calcule la nouvelle position des noeuds et on affecte au tableau temporaire
2187 OT_VECTEUR_3D v_premier (x_prime,y_prime,z_prime);
2188 nouv_position2_x.push_back(v_premier.get_x());
2189 nouv_position2_y.push_back(v_premier.get_y());
2190 nouv_position2_z.push_back(v_premier.get_z());
2191 }
2192 }
2193 //On actualise la position des noeuds
2194 int ind_noeud2=0;
2195 for (MG_NOEUD* noeud_i2=mg_mai->get_premier_noeud(it_no);noeud_i2!=NULL;noeud_i2=mg_mai->get_suivant_noeud(it_no))
2196 {
2197 int origine = noeud_i2->get_origine();
2198 if ((origine != MAGIC::ORIGINE::IMPOSE)&& ( noeud_i2->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&& (origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&&( noeud_i2->get_lien_topologie()==NULL))/////////////////////////////////////////////////////////////////////////////
2199 {
2200 noeud_i2->change_x(nouv_position2_x[ind_noeud2]);
2201 noeud_i2->change_y(nouv_position2_y[ind_noeud2]);
2202 noeud_i2->change_z(nouv_position2_z[ind_noeud2]);
2203 ind_noeud2++;
2204 }
2205 }
2206 return (1);
2207
2208 }
2209
2210 //---------------------------- Varience/Ecart type/ pour Taubin 1995-------------------------------------------------------------------------
2211 double MGOPT_POSTTRAITEMENT::varience_taubin1995(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2,int affichage)
2212 {
2213 char mess[300];
2214 int ecart_type = 0;
2215 double s_i = 0.0;
2216 double phi_im = 0.0;
2217 double ecart_type_i = 0.;
2218 ecart_type = 0;
2219 do
2220 {
2221
2222 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales;
2223 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales2;
2224 TPL_LISTE_ENTITE<double> liste_wij;
2225 LISTE_MG_TRIANGLE::iterator it_tri;
2226 int k = 0; //pour identifier les triangles pour liste_normales et liste_wij
2227 for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
2228 {
2229 MG_TRIANGLE_PEAU* mgtri_i = (MG_TRIANGLE_PEAU*)mgtri;
2230 OT_VECTEUR_3D normal_f_i = mgtri_i->calcul_normal();
2231 normal_f_i.norme();
2232 liste_normales2.ajouter(normal_f_i);
2233 //Remplissage de la liste des voisins du triangle i
2234 TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*> liste_voisins;
2235 MG_NOEUD* noeud1 = mgtri_i->get_noeud1();
2236 double nb_voisins1 = noeud1->get_lien_triangle()->get_nb();
2237 for (int j = 0;j<nb_voisins1;j++)
2238 {
2239 MG_TRIANGLE_PEAU* mgtri_1 = (MG_TRIANGLE_PEAU*) noeud1->get_lien_triangle()->get(j);
2240 liste_voisins.ajouter(mgtri_1);
2241 }
2242 MG_NOEUD* noeud2 = mgtri_i->get_noeud2();
2243 double nb_voisins2 = noeud2->get_lien_triangle()->get_nb();
2244 for (int j = 0;j<nb_voisins2;j++)
2245 {
2246 MG_TRIANGLE_PEAU* mgtri_2 = (MG_TRIANGLE_PEAU*) noeud2->get_lien_triangle()->get(j);
2247 liste_voisins.ajouter(mgtri_2);
2248 }
2249 MG_NOEUD* noeud3 = mgtri_i->get_noeud3();
2250 double nb_voisins3 = noeud3->get_lien_triangle()->get_nb();
2251 for (int j = 0;j<nb_voisins3;j++)
2252 {
2253 MG_TRIANGLE_PEAU* mgtri_3 = (MG_TRIANGLE_PEAU*) noeud3->get_lien_triangle()->get(j);
2254 liste_voisins.ajouter(mgtri_3);
2255 }
2256 liste_voisins.supprimer(mgtri_i);
2257 int nb_voisins = liste_voisins.get_nb();
2258 double w_ij = 1./nb_voisins;
2259 double phi_i_min = 10.;
2260 s_i = 0.0;
2261 phi_im = 0.0;
2262 double *phi_ij = new double[nb_voisins];
2263 OT_VECTEUR_3D normal_f_i_mean(0.,0.,0.);
2264 normal_f_i_mean = normal_f_i;
2265 OT_VECTEUR_3D eta_i(0.,0.,0.);
2266 TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*>::ITERATEUR it;
2267 int j = 0;
2268 double un_sur_pi = 1./M_PI;
2269 for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
2270 {
2271 OT_VECTEUR_3D normal_f_j = mgtri_j->calcul_normal();
2272 //1-Calculer la normale moyenne pour chaque triangle
2273 normal_f_i_mean = normal_f_i_mean + normal_f_j;
2274 //2.1-On calcule l'angle entre normal_f_i et normal_f_j pour j allant de 1 a Nb_voisins
2275 double prod_scalaire = normal_f_i*normal_f_j;
2276 if (prod_scalaire > 1.)
2277 {
2278 prod_scalaire = 1.;
2279 }
2280 if (prod_scalaire < -1.)
2281 {
2282 prod_scalaire = -1.;
2283 }
2284 phi_ij[j] = acos(prod_scalaire)*un_sur_pi;
2285 //2.2-On trouve le plus petit des angles et la normale heta_i correspondante
2286 if (phi_ij[j] < phi_i_min)
2287 {
2288 phi_i_min = phi_ij[j];
2289 eta_i = normal_f_j;
2290 }
2291 //3.1-On calcule l'angle moyen phi_im
2292 phi_im = phi_im + w_ij*phi_ij[j];
2293 j++;
2294 }
2295 normal_f_i_mean.norme();
2296 j = 0;
2297 for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
2298 {
2299 //3.2-Calcul de s_i selon la variance
2300 s_i = s_i + w_ij*pow((phi_ij[j] - phi_im),2);
2301 j++;
2302 }
2303 delete[] phi_ij;
2304 }
2305 ecart_type_i = sqrt(s_i);
2306 if (affichage == 1)
2307 {
2308 sprintf(mess," Moyenne des normes des triangles de la surface : %f",phi_im); affiche(mess);
2309 sprintf(mess," Varience des normes des triangles de la surface : %f",s_i); affiche(mess);
2310 sprintf(mess," Ecart type des normes des triangles de la surface : %f",ecart_type_i); affiche(mess);
2311 }
2312 ecart_type = 1;
2313 }
2314 while (ecart_type == 0);
2315 ecart_type = 0;//reinitialisation d'ecart_type pour la prochainepasse
2316
2317 }
2318
2319
2320 //---------------------------- Lissage Taubin 1995 Bryan Mckenzie 2016-------------------------------------------------------------------------
2321 int MGOPT_POSTTRAITEMENT::lissage_taubin1995(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, double lambda, double nu, double epsilon,double sigma,double gamma_,int filtre, int iter_max, int itr_taubin)
2322 {
2323 // Lissage global avec methode de lissage inspiree de Taubin 1995 et Chen 2008 par Bryan McKenzie
2324
2325
2326 //sauvegarde des differents position de noeuds pour conservation des position
2327 vector<double> coord_x;
2328 vector<double> coord_y;
2329 vector<double> coord_z;
2330 vector<double> vecteur_original;
2331 LISTE_MG_NOEUD::iterator it_no;
2332 int ii=0;
2333 for (MG_NOEUD* noeud=mg_mai->get_premier_noeud(it_no);noeud!=NULL;noeud=mg_mai->get_suivant_noeud(it_no))
2334 {
2335 MG_NOEUD* tri=(MG_NOEUD*)noeud;
2336 if(tri->get_origine()!=MAGIC::ORIGINE::MAILLEUR_AUTO)
2337 {
2338 coord_x.push_back(noeud->get_x());
2339 coord_y.push_back(noeud->get_y());
2340 coord_z.push_back(noeud->get_z());
2341 vecteur_original.push_back(sqrt(coord_x[ii]*coord_x[ii] + coord_y[ii]*coord_y[ii] + coord_z[ii]*coord_z[ii]));
2342 ii++;
2343 }
2344
2345 }
2346
2347
2348
2349 char mess[300];
2350 sprintf(mess, "Depart Taubin1995"); affiche(mess);
2351 double v_initial = 0.0;
2352 double v_final = 0.0;
2353 double v_taubin = 0.0;
2354 double v_taubin_prime = 0.0;
2355 double d_initial = 0.0;
2356 double d_final = 0.0;
2357 double d_taubin = 0.0;
2358 double nu_ = nu;
2359 double sigma_ = sigma;//variable utiliser pour sassuré que la pièce ne grossie pas dan taubin_chen 2
2360 int ecart_type = 0;
2361 double s_i = 0.0;
2362 double phi_im = 0.0;
2363 double ecart_type_i = 0.;
2364 int compteur_triangle_retourne =0;
2365 int compteur_total = 0;
2366 int compteur_taubin_initial = 0;
2367 int compteur_chen = 0;
2368 int compteur_taubin_chen = 0;
2369 int compteur_taubin_final = 0;
2370 int compteur_temp = 0;
2371 int compteur_taubin2D = 0;
2372 int triangle_final_retourne =0;
2373 int iter_taubin = itr_taubin;
2374
2375
2376
2377 int activationPI = 1; // variable qui active l'adjustement du volume dans taubin1995
2378 int activationPI2 = 1; // variable qui active l'adjustement du volume dans taubin_chen
2379 double condition_de_varience = 1000.0; //variable de sortie pour les prenières iteration taubin pour s'assuré que la surface a une certaine surface lisse
2380 int taubin_premiere_passe = 0;
2381
2382 /// Calcul du volume initial
2383 LISTE_MG_TRIANGLE::iterator it;
2384 for (MG_TRIANGLE* ttr=mg_mai->get_premier_triangle(it);ttr!=NULL;ttr=mg_mai->get_suivant_triangle(it))
2385 {
2386 MG_TRIANGLE_PEAU* tri=(MG_TRIANGLE_PEAU*)ttr;
2387 //if(tri->get_origine()!=MAGIC::ORIGINE::MAILLEUR_AUTO) // volume total sinon le volume total moins une constante
2388 {
2389 MG_NOEUD* no1=tri->get_noeud1();
2390 MG_NOEUD* no2=tri->get_noeud2();
2391 MG_NOEUD* no3=tri->get_noeud3();
2392 double *xyz1=no1->get_coord();
2393 double *xyz2=no2->get_coord();
2394 double *xyz3=no3->get_coord();
2395 OT_VECTEUR_3D vec1(xyz1,xyz2);
2396 OT_VECTEUR_3D vec2(xyz1,xyz3);
2397 OT_VECTEUR_3D pvec=vec2&vec1;
2398
2399 d_initial=pvec.get_longueur(); // En fait surface=pvec.get_longueur()/2. et det=2*surface
2400 OT_VECTEUR_3D N=pvec/(pvec.get_longueur());
2401 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}
2402 +(xyz1+(2/3.)*vec1+(1/6.)*vec2)
2403 +(xyz1+(1/6.)*vec1+(2/3.)*vec2));
2404 v_initial=v_initial+d_initial*N*F;
2405 }
2406
2407 }
2408
2409
2410
2411 //******************parti taubin pur***********************************//
2412
2413
2414
2415 //calcule de la varience et l'écart type pour la surface du maillaige au début
2416 double varience = varience_taubin1995(mg_mai,gest2,1);
2417
2418 /*
2419 ecart_type = 0;
2420 do
2421 {
2422
2423 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales;
2424 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales2;
2425 TPL_LISTE_ENTITE<double> liste_wij;
2426 LISTE_MG_TRIANGLE::iterator it_tri;
2427 int k = 0; //pour identifier les triangles pour liste_normales et liste_wij
2428 for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
2429 {
2430 MG_TRIANGLE_PEAU* mgtri_i = (MG_TRIANGLE_PEAU*)mgtri;
2431 OT_VECTEUR_3D normal_f_i = mgtri_i->calcul_normal();
2432 normal_f_i.norme();
2433 liste_normales2.ajouter(normal_f_i);
2434 //Remplissage de la liste des voisins du triangle i
2435 TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*> liste_voisins;
2436 MG_NOEUD* noeud1 = mgtri_i->get_noeud1();
2437 double nb_voisins1 = noeud1->get_lien_triangle()->get_nb();
2438 for (int j = 0;j<nb_voisins1;j++)
2439 {
2440 MG_TRIANGLE_PEAU* mgtri_1 = (MG_TRIANGLE_PEAU*) noeud1->get_lien_triangle()->get(j);
2441 liste_voisins.ajouter(mgtri_1);
2442 }
2443 MG_NOEUD* noeud2 = mgtri_i->get_noeud2();
2444 double nb_voisins2 = noeud2->get_lien_triangle()->get_nb();
2445 for (int j = 0;j<nb_voisins2;j++)
2446 {
2447 MG_TRIANGLE_PEAU* mgtri_2 = (MG_TRIANGLE_PEAU*) noeud2->get_lien_triangle()->get(j);
2448 liste_voisins.ajouter(mgtri_2);
2449 }
2450 MG_NOEUD* noeud3 = mgtri_i->get_noeud3();
2451 double nb_voisins3 = noeud3->get_lien_triangle()->get_nb();
2452 for (int j = 0;j<nb_voisins3;j++)
2453 {
2454 MG_TRIANGLE_PEAU* mgtri_3 = (MG_TRIANGLE_PEAU*) noeud3->get_lien_triangle()->get(j);
2455 liste_voisins.ajouter(mgtri_3);
2456 }
2457 liste_voisins.supprimer(mgtri_i);
2458 int nb_voisins = liste_voisins.get_nb();
2459 double w_ij = 1./nb_voisins;
2460 double phi_i_min = 10.;
2461 s_i = 0.0;
2462 phi_im = 0.0;
2463 double *phi_ij = new double[nb_voisins];
2464 OT_VECTEUR_3D normal_f_i_mean(0.,0.,0.);
2465 normal_f_i_mean = normal_f_i;
2466 OT_VECTEUR_3D eta_i(0.,0.,0.);
2467 TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*>::ITERATEUR it;
2468 int j = 0;
2469 double un_sur_pi = 1./M_PI;
2470 for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
2471 {
2472 OT_VECTEUR_3D normal_f_j = mgtri_j->calcul_normal();
2473 //1-Calculer la normale moyenne pour chaque triangle
2474 normal_f_i_mean = normal_f_i_mean + normal_f_j;
2475 //2.1-On calcule l'angle entre normal_f_i et normal_f_j pour j allant de 1 a Nb_voisins
2476 double prod_scalaire = normal_f_i*normal_f_j;
2477 if (prod_scalaire > 1.)
2478 {
2479 prod_scalaire = 1.;
2480 }
2481 if (prod_scalaire < -1.)
2482 {
2483 prod_scalaire = -1.;
2484 }
2485 phi_ij[j] = acos(prod_scalaire)*un_sur_pi;
2486 //2.2-On trouve le plus petit des angles et la normale heta_i correspondante
2487 if (phi_ij[j] < phi_i_min)
2488 {
2489 phi_i_min = phi_ij[j];
2490 eta_i = normal_f_j;
2491 }
2492 //3.1-On calcule l'angle moyen phi_im
2493 phi_im = phi_im + w_ij*phi_ij[j];
2494 j++;
2495 }
2496 normal_f_i_mean.norme();
2497 j = 0;
2498 for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
2499 {
2500 //3.2-Calcul de s_i selon la variance
2501 s_i = s_i + w_ij*pow((phi_ij[j] - phi_im),2);
2502 j++;
2503 }
2504 delete[] phi_ij;
2505 }
2506 ecart_type_i = sqrt(s_i);
2507 sprintf(mess," Moyenne des normes des triangles de la surface : %f",phi_im); affiche(mess);
2508 sprintf(mess," Varience des normes des triangles de la surface : %f",s_i); affiche(mess);
2509 sprintf(mess," Ecart type des normes des triangles de la surface : %f",ecart_type_i); affiche(mess);
2510 ecart_type = 1;
2511 }
2512 while (ecart_type == 0);
2513 ecart_type = 0;//reinitialisation d'ecart_type pour la prochainepasse*/
2514
2515
2516
2517
2518 //première passe de taubin pour partir
2519 do
2520 {
2521 v_taubin_prime = v_taubin;//assignation du volume de l'itération précédente pour fair la loi de controle
2522 int taubin=cycle_taubin1995(mg_mai, gest2, lambda, nu);
2523 /*
2524 /////partie lambda du lissage
2525 vector<double> nouv_position_x;
2526 vector<double> nouv_position_y;
2527 vector<double> nouv_position_z;
2528 LISTE_MG_NOEUD::iterator it_no;
2529 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
2530 {
2531 int origine = noeud_i->get_origine();
2532 if ((origine != MAGIC::ORIGINE::IMPOSE)&& (noeud_i->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&& (origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&&(noeud_i->get_lien_topologie()==NULL))///////////////////////////////////////////////////////////////////////////////
2533 {
2534 int nb_voisins_j = noeud_i->get_lien_triangle()->get_nb();
2535 double delta_x = 0.0;
2536 double delta_y = 0.0;
2537 double delta_z = 0.0;
2538
2539
2540 double v_x_done[nb_voisins_j];
2541 double v_y_done[nb_voisins_j];
2542 double v_z_done[nb_voisins_j];
2543 double v_i_x = 0.0;
2544 double v_i_y = 0.0;
2545 double v_i_z = 0.0;
2546
2547 for(int j=0;j<nb_voisins_j;j++)
2548 {
2549 if (j==0)
2550 {
2551 for (int jj=0;jj<nb_voisins_j;jj++)
2552 {
2553 v_x_done[jj] = 0.0;
2554 v_y_done[jj] = 0.0;
2555 v_z_done[jj] = 0.0;
2556 }
2557 }
2558
2559
2560 MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
2561 MG_NOEUD* v_1 = mgtri_j->get_noeud1();
2562 MG_NOEUD* v_2 = mgtri_j->get_noeud2();
2563 MG_NOEUD* v_3 = mgtri_j->get_noeud3();
2564 double v_x = noeud_i->get_x();//v_1->get_x();
2565 double v_y = noeud_i->get_y();//v_1->get_y();
2566 double v_z = noeud_i->get_z();//v_1->get_z();
2567 double v_1_x = v_1->get_x();
2568 double v_1_y = v_1->get_y();
2569 double v_1_z = v_1->get_z();
2570 double v_2_x = v_2->get_x();
2571 double v_2_y = v_2->get_y();
2572 double v_2_z = v_2->get_z();
2573 double v_3_x = v_3->get_x();
2574 double v_3_y = v_3->get_y();
2575 double v_3_z = v_3->get_z();
2576
2577 if (((v_1_x == v_x)&&(v_1_y == v_y)&&(v_1_y == v_y)) && (((v_2_x!=v_x_done[0])&&(v_2_y!=v_y_done[0])&&(v_2_z!=v_z_done[0]))||((v_2_x!=v_x_done[1])&&(v_2_y!=v_y_done[1])&&(v_2_z!=v_z_done[1]))||((v_2_x!=v_x_done[2])&&(v_2_y!=v_y_done[2])&&(v_2_z!=v_z_done[2]))||((v_2_x!=v_x_done[3])&&(v_2_y!=v_y_done[3])&&(v_2_z!=v_z_done[3]))||((v_2_x!=v_x_done[4])&&(v_2_y!=v_y_done[4])&&(v_2_z!=v_z_done[4]))||((v_2_x!=v_x_done[5])&&(v_2_y!=v_y_done[5])&&(v_2_z!=v_z_done[5]))||((v_2_x!=v_x_done[6])&&(v_2_y!=v_y_done[6])&&(v_2_z!=v_z_done[6]))||((v_2_x!=v_x_done[7])&&(v_2_y!=v_y_done[7])&&(v_2_z!=v_z_done[7]))||((v_2_x!=v_x_done[8])&&(v_2_y!=v_y_done[8])&&(v_2_z!=v_z_done[8]))||((v_2_x!=v_x_done[9])&&(v_2_y!=v_y_done[9])&&(v_2_z!=v_z_done[9]))))
2578 {
2579 v_i_x = v_2_x;
2580 v_i_y = v_2_y;
2581 v_i_z = v_2_z;
2582 }
2583 else if (((v_3_x == v_x)&&(v_3_y == v_y)&&(v_3_y == v_y)) && (((v_1_x!=v_x_done[0])&&(v_1_y!=v_y_done[0])&&(v_1_z!=v_z_done[0]))||((v_1_x!=v_x_done[1])&&(v_1_y!=v_y_done[1])&&(v_1_z!=v_z_done[1]))||((v_1_x!=v_x_done[2])&&(v_1_y!=v_y_done[2])&&(v_1_z!=v_z_done[2]))||((v_1_x!=v_x_done[3])&&(v_1_y!=v_y_done[3])&&(v_1_z!=v_z_done[3]))||((v_1_x!=v_x_done[4])&&(v_1_y!=v_y_done[4])&&(v_1_z!=v_z_done[4]))||((v_1_x!=v_x_done[5])&&(v_1_y!=v_y_done[5])&&(v_1_z!=v_z_done[5]))||((v_1_x!=v_x_done[6])&&(v_1_y!=v_y_done[6])&&(v_1_z!=v_z_done[6]))||((v_1_x!=v_x_done[7])&&(v_1_y!=v_y_done[7])&&(v_1_z!=v_z_done[7]))||((v_1_x!=v_x_done[8])&&(v_1_y!=v_y_done[8])&&(v_1_z!=v_z_done[8]))||((v_1_x!=v_x_done[9])&&(v_1_y!=v_y_done[9])&&(v_1_z!=v_z_done[9]))))
2584 {
2585 v_i_x = v_1_x;
2586 v_i_y = v_1_y;
2587 v_i_z = v_1_z;
2588 }
2589 else
2590 {
2591 v_i_x = v_3_x;
2592 v_i_y = v_3_y;
2593 v_i_z = v_3_z;
2594 }
2595
2596 v_x_done[j] = v_i_x;
2597 v_y_done[j] = v_i_y;
2598 v_z_done[j] = v_i_z;
2599
2600 double multiplicateur = (1.0/nb_voisins_j);
2601 delta_x = delta_x+(multiplicateur*(v_i_x-v_x));
2602 delta_y = delta_y+(multiplicateur*(v_i_y-v_y));
2603 delta_z = delta_z+(multiplicateur*(v_i_z-v_z));
2604
2605 }
2606 double i_x =noeud_i->get_x();
2607 double i_y =noeud_i->get_y();
2608 double i_z =noeud_i->get_z();
2609 double x_prime = (i_x)+(lambda*delta_x);
2610 double y_prime = (i_y)+(lambda*delta_y);
2611 double z_prime = (i_z)+(lambda*delta_z);
2612
2613 //5-On calcule la nouvelle position des noeuds et on affecte au tableau temporaire
2614 OT_VECTEUR_3D v_premier (x_prime,y_prime,z_prime);
2615 nouv_position_x.push_back(v_premier.get_x());
2616 nouv_position_y.push_back(v_premier.get_y());
2617 nouv_position_z.push_back(v_premier.get_z());
2618 }
2619 }
2620 //On actualise la position des noeuds
2621 int ind_noeud=0;
2622 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
2623 {
2624 int origine = noeud_i->get_origine();
2625 if ((origine != MAGIC::ORIGINE::IMPOSE)&& (noeud_i->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&& (origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&&(noeud_i->get_lien_topologie()==NULL))///////////////////////////////////////////////////////////////////////////////
2626 {
2627 noeud_i->change_x(nouv_position_x[ind_noeud]);
2628 noeud_i->change_y(nouv_position_y[ind_noeud]);
2629 noeud_i->change_z(nouv_position_z[ind_noeud]);
2630 ind_noeud++;
2631 }
2632 }
2633
2634
2635 //partie nu du lissage
2636 vector<double> nouv_position2_x;
2637 vector<double> nouv_position2_y;
2638 vector<double> nouv_position2_z;
2639 for (MG_NOEUD* noeud_i2=mg_mai->get_premier_noeud(it_no);noeud_i2!=NULL;noeud_i2=mg_mai->get_suivant_noeud(it_no))
2640 {
2641 int origine = noeud_i2->get_origine();
2642 if ((origine != MAGIC::ORIGINE::IMPOSE)&& (noeud_i2->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&& (origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&&(noeud_i2->get_lien_topologie()==NULL))///////////////////////////////////////////////////////////////////////////////
2643 {
2644 int nb_voisins_j = noeud_i2->get_lien_triangle()->get_nb();
2645 double delta_x = 0.0;
2646 double delta_y = 0.0;
2647 double delta_z = 0.0;
2648 double v_x_done[10];
2649 double v_y_done[10];
2650 double v_z_done[10];
2651 double v_i_x = 0.0;
2652 double v_i_y = 0.0;
2653 double v_i_z = 0.0;
2654
2655 for(int j=0;j<nb_voisins_j;j++)
2656 {
2657 if (j==0)
2658 {
2659 for (int jj=0;jj<10;jj++)
2660 {
2661 v_x_done[jj] = 0.0;
2662 v_y_done[jj] = 0.0;
2663 v_z_done[jj] = 0.0;
2664 }
2665 }
2666
2667
2668 MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i2->get_lien_triangle()->get(j);
2669 MG_NOEUD* v_1 = mgtri_j->get_noeud1();
2670 MG_NOEUD* v_2 = mgtri_j->get_noeud2();
2671 MG_NOEUD* v_3 = mgtri_j->get_noeud3();
2672 double v_x = noeud_i2->get_x();//v_1->get_x();
2673 double v_y = noeud_i2->get_y();//v_1->get_y();
2674 double v_z = noeud_i2->get_z();//v_1->get_z();
2675 double v_1_x = v_1->get_x();
2676 double v_1_y = v_1->get_y();
2677 double v_1_z = v_1->get_z();
2678 double v_2_x = v_2->get_x();
2679 double v_2_y = v_2->get_y();
2680 double v_2_z = v_2->get_z();
2681 double v_3_x = v_3->get_x();
2682 double v_3_y = v_3->get_y();
2683 double v_3_z = v_3->get_z();
2684
2685 if (((v_1_x == v_x)&&(v_1_y == v_y)&&(v_1_y == v_y)) && (((v_2_x!=v_x_done[0])&&(v_2_y!=v_y_done[0])&&(v_2_z!=v_z_done[0]))||((v_2_x!=v_x_done[1])&&(v_2_y!=v_y_done[1])&&(v_2_z!=v_z_done[1]))||((v_2_x!=v_x_done[2])&&(v_2_y!=v_y_done[2])&&(v_2_z!=v_z_done[2]))||((v_2_x!=v_x_done[3])&&(v_2_y!=v_y_done[3])&&(v_2_z!=v_z_done[3]))||((v_2_x!=v_x_done[4])&&(v_2_y!=v_y_done[4])&&(v_2_z!=v_z_done[4]))||((v_2_x!=v_x_done[5])&&(v_2_y!=v_y_done[5])&&(v_2_z!=v_z_done[5]))||((v_2_x!=v_x_done[6])&&(v_2_y!=v_y_done[6])&&(v_2_z!=v_z_done[6]))||((v_2_x!=v_x_done[7])&&(v_2_y!=v_y_done[7])&&(v_2_z!=v_z_done[7]))||((v_2_x!=v_x_done[8])&&(v_2_y!=v_y_done[8])&&(v_2_z!=v_z_done[8]))||((v_2_x!=v_x_done[9])&&(v_2_y!=v_y_done[9])&&(v_2_z!=v_z_done[9]))))
2686 {
2687 v_i_x = v_2_x;
2688 v_i_y = v_2_y;
2689 v_i_z = v_2_z;
2690 }
2691 else if (((v_3_x == v_x)&&(v_3_y == v_y)&&(v_3_y == v_y)) && (((v_1_x!=v_x_done[0])&&(v_1_y!=v_y_done[0])&&(v_1_z!=v_z_done[0]))||((v_1_x!=v_x_done[1])&&(v_1_y!=v_y_done[1])&&(v_1_z!=v_z_done[1]))||((v_1_x!=v_x_done[2])&&(v_1_y!=v_y_done[2])&&(v_1_z!=v_z_done[2]))||((v_1_x!=v_x_done[3])&&(v_1_y!=v_y_done[3])&&(v_1_z!=v_z_done[3]))||((v_1_x!=v_x_done[4])&&(v_1_y!=v_y_done[4])&&(v_1_z!=v_z_done[4]))||((v_1_x!=v_x_done[5])&&(v_1_y!=v_y_done[5])&&(v_1_z!=v_z_done[5]))||((v_1_x!=v_x_done[6])&&(v_1_y!=v_y_done[6])&&(v_1_z!=v_z_done[6]))||((v_1_x!=v_x_done[7])&&(v_1_y!=v_y_done[7])&&(v_1_z!=v_z_done[7]))||((v_1_x!=v_x_done[8])&&(v_1_y!=v_y_done[8])&&(v_1_z!=v_z_done[8]))||((v_1_x!=v_x_done[9])&&(v_1_y!=v_y_done[9])&&(v_1_z!=v_z_done[9]))))
2692 {
2693 v_i_x = v_1_x;
2694 v_i_y = v_1_y;
2695 v_i_z = v_1_z;
2696 }
2697 else
2698 {
2699 v_i_x = v_3_x;
2700 v_i_y = v_3_y;
2701 v_i_z = v_3_z;
2702 }
2703
2704 v_x_done[j] = v_i_x;
2705 v_y_done[j] = v_i_y;
2706 v_z_done[j] = v_i_z;
2707
2708 double multiplicateur = (1.0/nb_voisins_j);
2709 delta_x = delta_x+(multiplicateur*(v_i_x-v_x));
2710 delta_y = delta_y+(multiplicateur*(v_i_y-v_y));
2711 delta_z = delta_z+(multiplicateur*(v_i_z-v_z));
2712
2713 }
2714 double i_x =noeud_i2->get_x();
2715 double i_y =noeud_i2->get_y();
2716 double i_z =noeud_i2->get_z();
2717 double x_prime = (i_x)+(nu_*delta_x);
2718 double y_prime = (i_y)+(nu_*delta_y);
2719 double z_prime = (i_z)+(nu_*delta_z);
2720
2721 //5-On calcule la nouvelle position des noeuds et on affecte au tableau temporaire
2722 OT_VECTEUR_3D v_premier (x_prime,y_prime,z_prime);
2723 nouv_position2_x.push_back(v_premier.get_x());
2724 nouv_position2_y.push_back(v_premier.get_y());
2725 nouv_position2_z.push_back(v_premier.get_z());
2726 }
2727 }
2728 //On actualise la position des noeuds
2729 int ind_noeud2=0;
2730 for (MG_NOEUD* noeud_i2=mg_mai->get_premier_noeud(it_no);noeud_i2!=NULL;noeud_i2=mg_mai->get_suivant_noeud(it_no))
2731 {
2732 int origine = noeud_i2->get_origine();
2733 if ((origine != MAGIC::ORIGINE::IMPOSE)&& ( noeud_i2->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&& (origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&&( noeud_i2->get_lien_topologie()==NULL))/////////////////////////////////////////////////////////////////////////////
2734 {
2735 noeud_i2->change_x(nouv_position2_x[ind_noeud2]);
2736 noeud_i2->change_y(nouv_position2_y[ind_noeud2]);
2737 noeud_i2->change_z(nouv_position2_z[ind_noeud2]);
2738 ind_noeud2++;
2739 }
2740 }*/
2741
2742 /// Calcul du volume
2743 d_taubin=0.;
2744 v_taubin=0;
2745 for (MG_TRIANGLE* ttr3=mg_mai->get_premier_triangle(it);ttr3!=NULL;ttr3=mg_mai->get_suivant_triangle(it))
2746 {
2747 MG_TRIANGLE_PEAU* tri3=(MG_TRIANGLE_PEAU*)ttr3;
2748 //if(tri->get_origine()!=MAGIC::ORIGINE::MAILLEUR_AUTO) // volume total sinon le volume total moins une constante
2749 {
2750 MG_NOEUD* no13=tri3->get_noeud1();
2751 MG_NOEUD* no23=tri3->get_noeud2();
2752 MG_NOEUD* no33=tri3->get_noeud3();
2753 double *xyz13=no13->get_coord();
2754 double *xyz23=no23->get_coord();
2755 double *xyz33=no33->get_coord();
2756 OT_VECTEUR_3D vec13(xyz13,xyz23);
2757 OT_VECTEUR_3D vec23(xyz13,xyz33);
2758 OT_VECTEUR_3D pvec3=vec23&vec13;
2759 d_taubin=pvec3.get_longueur();
2760 OT_VECTEUR_3D N =pvec3/(pvec3.get_longueur());
2761 OT_VECTEUR_3D F=(1/6.)*(1/3.)*((xyz13+(1/6.)*vec13+(1/6.)*vec23)
2762 +(xyz13+(2/3.)*vec13+(1/6.)*vec23)
2763 +(xyz13+(1/6.)*vec13+(2/3.)*vec23));
2764 v_taubin=v_taubin+d_taubin*N*F;
2765 }
2766 }
2767
2768 //implemantion d'un PI por controler le volume
2769 if (activationPI==1)
2770 {
2771 if (((fabs(v_taubin)-fabs(v_taubin_prime))/fabs(v_taubin))<-0.1)//fine adjustment makes part bigger if new iteration of part is smaller than the preceeding pass and volume is less than 10% bigger than original
2772 {
2773 nu_ =nu_-0.00005;
2774 }
2775 if (((fabs(v_taubin)-fabs(v_taubin_prime))/fabs(v_taubin))>0.1)//fine adjustment makes part smaller if part is much bigger than preceeding pass and the volume is larger than original
2776 {
2777 nu_ = nu_+0.00005;
2778 }
2779 if (fabs(v_taubin)>(fabs(v_initial)*1.015))//gross adjustment makes part smaller if part is 3% bigger than original make smaller
2780 {
2781 nu_ =nu_+0.0005;
2782 }
2783 if (fabs(v_taubin)<(fabs(v_initial)*0.985))//gross adjustment makes part bigger if it is smaller than the original
2784 {
2785 nu_ =nu_-0.0005;
2786 }
2787 }
2788
2789
2790 double un_sur_pi = 1./M_PI;
2791
2792
2793
2794
2795 //code qui vérifie la qualité des different trianges
2796 double qualmin=1e300,qualmax=-1e300,qualmoy=0.;
2797 int nbretourne=0;
2798 int itri=0;
2799 double eps_angle_retourne =0.03000;
2800 double borne1 =0.10000;
2801 double borne2 =0.20000;
2802 double borne3 =0.50000;
2803 LISTE_MG_TRIANGLE::iterator ittr;
2804 int nbtrifront=0;
2805 int tab[7]={0,0,0,0,0,0,0};//variable qui vérifie pour s'assuré qu'il n'y a pas de triangle retournés lors du lissage
2806 MG_SOLUTION *sol=NULL;
2807
2808 for (MG_TRIANGLE* tri=mg_mai->get_premier_triangle(ittr);tri!=NULL;tri=mg_mai->get_suivant_triangle(ittr))
2809 {
2810 if (mg_mai->get_nb_mg_tetra()==0)
2811 tri->change_nouveau_numero(1);
2812 if (tri->get_nouveau_numero()==1)
2813 {
2814 nbtrifront++;
2815 tri->get_segment1()->change_nouveau_numero(tri->get_segment1()->get_nouveau_numero()+1);
2816 tri->get_segment2()->change_nouveau_numero(tri->get_segment2()->get_nouveau_numero()+1);
2817 tri->get_segment3()->change_nouveau_numero(tri->get_segment3()->get_nouveau_numero()+1);
2818 tri->get_noeud1()->change_nouveau_numero(1);
2819 tri->get_noeud2()->change_nouveau_numero(1);
2820 tri->get_noeud3()->change_nouveau_numero(1);
2821
2822 }
2823 }
2824 for (MG_TRIANGLE* tri=mg_mai->get_premier_triangle(ittr);tri!=NULL;tri=mg_mai->get_suivant_triangle(ittr))
2825 if (tri->get_nouveau_numero()==1)
2826 {
2827 double qual=OPERATEUR::qualite_triangle(tri->get_noeud1()->get_coord(),tri->get_noeud2()->get_coord(),tri->get_noeud3()->get_coord());
2828 MG_NOEUD * no1=tri->get_noeud1();
2829 MG_NOEUD * no2=tri->get_noeud2();
2830 MG_NOEUD * no3=tri->get_noeud3();
2831 if (no1==no2)
2832 if (no1==no3)
2833 tab[6]++;
2834 int nb1=no1->get_lien_triangle()->get_nb();
2835 int nb2=no2->get_lien_triangle()->get_nb();
2836 int nb3=no3->get_lien_triangle()->get_nb();
2837 OT_VECTEUR_3D vec1(tri->get_noeud1()->get_coord(),tri->get_noeud2()->get_coord());
2838 OT_VECTEUR_3D vec2(tri->get_noeud1()->get_coord(),tri->get_noeud3()->get_coord());
2839 OT_VECTEUR_3D normal=vec1&vec2;
2840 normal.norme();
2841 int nbretourne=0;
2842 int nbvoisin=0;
2843
2844
2845 for (int i=0;i<nb1;i++)
2846 for (int j=0;j<nb2;j++)
2847 {
2848 MG_TRIANGLE* tri1=no1->get_lien_triangle()->get(i);
2849 MG_TRIANGLE* tri2=no2->get_lien_triangle()->get(j);
2850 if ( (tri1==tri2) && (tri1!=tri) && (tri1->get_nouveau_numero()==1))
2851 {
2852 OT_VECTEUR_3D vec1tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud2()->get_coord());
2853 OT_VECTEUR_3D vec2tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud3()->get_coord());
2854 OT_VECTEUR_3D normaltmp=vec1tmp&vec2tmp;
2855 normaltmp.norme();
2856 double psca=normal*normaltmp;
2857 if (psca<-cos(eps_angle_retourne)) nbretourne++;
2858 nbvoisin++;
2859 }
2860 }
2861 for (int i=0;i<nb1;i++)
2862 for (int j=0;j<nb3;j++)
2863 {
2864 MG_TRIANGLE* tri1=no1->get_lien_triangle()->get(i);
2865 MG_TRIANGLE* tri2=no3->get_lien_triangle()->get(j);
2866 if ( (tri1==tri2) && (tri1!=tri) && (tri1->get_nouveau_numero()==1))
2867 {
2868 OT_VECTEUR_3D vec1tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud2()->get_coord());
2869 OT_VECTEUR_3D vec2tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud3()->get_coord());
2870 OT_VECTEUR_3D normaltmp=vec1tmp&vec2tmp;
2871 normaltmp.norme();
2872 double psca=normal*normaltmp;
2873 if (psca<-cos(eps_angle_retourne)) nbretourne++;
2874 nbvoisin++;
2875 }
2876 }
2877 for (int i=0;i<nb2;i++)
2878 for (int j=0;j<nb3;j++)
2879 {
2880 MG_TRIANGLE* tri1=no2->get_lien_triangle()->get(i);
2881 MG_TRIANGLE* tri2=no3->get_lien_triangle()->get(j);
2882 if ( (tri1==tri2) && (tri1!=tri) && (tri1->get_nouveau_numero()==1))
2883 {
2884 OT_VECTEUR_3D vec1tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud2()->get_coord());
2885 OT_VECTEUR_3D vec2tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud3()->get_coord());
2886 OT_VECTEUR_3D normaltmp=vec1tmp&vec2tmp;
2887 normaltmp.norme();
2888 double psca=normal*normaltmp;
2889 if (psca<-cos(eps_angle_retourne)) nbretourne++;
2890 nbvoisin++;
2891 }
2892 }
2893 if (nbvoisin!=3)
2894 tab[5]++;
2895 if (nbretourne>1) qual=-qual;
2896 qualmoy=qualmoy+qual;
2897 if (qual<qualmin) qualmin=qual;
2898 if (qual>qualmax) qualmax=qual;
2899 if (qual<0.) tab[0]++;
2900 else if (qual<borne1) tab[1]++;
2901 else if (qual<borne2) tab[2]++;
2902 else if (qual<borne3) tab[3]++;
2903 else tab[4]++;
2904 if (sol!=NULL)
2905 if (mg_mai->get_nb_mg_tetra()==0) sol->ecrire(qual,itri,0);
2906 itri++;
2907 }
2908 if (tab[0]>0)
2909 {
2910 compteur_triangle_retourne++;
2911 compteur_temp--;
2912 sprintf(mess, "Triangle retourné");
2913 affiche(mess);
2914 }
2915 compteur_taubin_initial++;
2916 compteur_total++;
2917 compteur_temp++;
2918
2919
2920
2921
2922
2923 //calcule de la varience et l'écart type pour la surface du maillaige au début
2924 double varience = varience_taubin1995(mg_mai,gest2,0);
2925 /*
2926 ecart_type = 0;
2927 s_i = 0.0;
2928 phi_im = 0.0;
2929 ecart_type_i = 0.;
2930 do
2931 {
2932 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales;
2933 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales2;
2934 TPL_LISTE_ENTITE<double> liste_wij;
2935 LISTE_MG_TRIANGLE::iterator it_tri;
2936 int k = 0; //pour identifier les triangles pour liste_normales et liste_wij
2937 for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
2938 {
2939 MG_TRIANGLE_PEAU* mgtri_i = (MG_TRIANGLE_PEAU*)mgtri;
2940 OT_VECTEUR_3D normal_f_i = mgtri_i->calcul_normal();
2941 normal_f_i.norme();
2942 liste_normales2.ajouter(normal_f_i);
2943 //Remplissage de la liste des voisins du triangle i
2944 TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*> liste_voisins;
2945 MG_NOEUD* noeud1 = mgtri_i->get_noeud1();
2946 double nb_voisins1 = noeud1->get_lien_triangle()->get_nb();
2947 for (int j = 0;j<nb_voisins1;j++)
2948 {
2949 MG_TRIANGLE_PEAU* mgtri_1 = (MG_TRIANGLE_PEAU*) noeud1->get_lien_triangle()->get(j);
2950 liste_voisins.ajouter(mgtri_1);
2951 }
2952 MG_NOEUD* noeud2 = mgtri_i->get_noeud2();
2953 double nb_voisins2 = noeud2->get_lien_triangle()->get_nb();
2954 for (int j = 0;j<nb_voisins2;j++)
2955 {
2956 MG_TRIANGLE_PEAU* mgtri_2 = (MG_TRIANGLE_PEAU*) noeud2->get_lien_triangle()->get(j);
2957 liste_voisins.ajouter(mgtri_2);
2958 }
2959 MG_NOEUD* noeud3 = mgtri_i->get_noeud3();
2960 double nb_voisins3 = noeud3->get_lien_triangle()->get_nb();
2961 for (int j = 0;j<nb_voisins3;j++)
2962 {
2963 MG_TRIANGLE_PEAU* mgtri_3 = (MG_TRIANGLE_PEAU*) noeud3->get_lien_triangle()->get(j);
2964 liste_voisins.ajouter(mgtri_3);
2965 }
2966 liste_voisins.supprimer(mgtri_i);
2967 int nb_voisins = liste_voisins.get_nb();
2968 double w_ij = 1./nb_voisins;
2969 double phi_i_min = 10.;
2970 s_i = 0.0;
2971 phi_im = 0.0;
2972 double *phi_ij = new double[nb_voisins];
2973 OT_VECTEUR_3D normal_f_i_mean(0.,0.,0.);
2974 normal_f_i_mean = normal_f_i;
2975 OT_VECTEUR_3D eta_i(0.,0.,0.);
2976 TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*>::ITERATEUR it;
2977 int j = 0;
2978 double un_sur_pi = 1./M_PI;
2979 for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
2980 {
2981 OT_VECTEUR_3D normal_f_j = mgtri_j->calcul_normal();
2982 //1-Calculer la normale moyenne pour chaque triangle
2983 normal_f_i_mean = normal_f_i_mean + normal_f_j;
2984 //2.1-On calcule l'angle entre normal_f_i et normal_f_j pour j allant de 1 a Nb_voisins
2985 double prod_scalaire = normal_f_i*normal_f_j;
2986 if (prod_scalaire > 1.)
2987 {
2988 prod_scalaire = 1.;
2989 }
2990 if (prod_scalaire < -1.)
2991 {
2992 prod_scalaire = -1.;
2993 }
2994 phi_ij[j] = acos(prod_scalaire)*un_sur_pi;
2995 //2.2-On trouve le plus petit des angles et la normale heta_i correspondante
2996 if (phi_ij[j] < phi_i_min)
2997 {
2998 phi_i_min = phi_ij[j];
2999 eta_i = normal_f_j;
3000 }
3001 //3.1-On calcule l'angle moyen phi_im
3002 phi_im = phi_im + w_ij*phi_ij[j];
3003 j++;
3004 }
3005 normal_f_i_mean.norme();
3006 j = 0;
3007 for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
3008 {
3009 //3.2-Calcul de s_i selon la variance
3010 s_i = s_i + w_ij*pow((phi_ij[j] - phi_im),2);
3011 j++;
3012 }
3013 delete[] phi_ij;
3014 }
3015 ecart_type_i = sqrt(s_i);
3016 ecart_type = 1;
3017 condition_de_varience = s_i;
3018
3019 }
3020
3021
3022 while (ecart_type == 0);
3023 ecart_type = 0;//reinitialisation d'ecart_type pour la prochaine passe*/
3024
3025 if (((compteur_temp >= iter_taubin)&&(condition_de_varience<0.0275))||(compteur_taubin_initial >(2*iter_taubin)))
3026 {
3027 taubin_premiere_passe = 1;
3028 }
3029
3030
3031 }
3032 while (taubin_premiere_passe == 0);
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042 //code d'utilisation de chen pour garder la forme et de taubin pour retirer les triangles retournés
3043 sprintf(mess, "Début de Chen pour iter_max iterations avec Taubin qui résoud les triangles retournés"); affiche(mess);
3044
3045 do
3046 {
3047
3048 int nbiter=lissage_chen2008(mg_mai,gest2,sigma,gamma_,epsilon,1);
3049 /*
3050 double un_sur_pi = 1./M_PI;
3051 vector<double> nouv_position_x;
3052 vector<double> nouv_position_y;
3053 vector<double> nouv_position_z;
3054 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales;
3055 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales2;
3056 TPL_LISTE_ENTITE<double> liste_wij;
3057 LISTE_MG_TRIANGLE::iterator it_tri;
3058 int k = 0; //pour identifier les triangles pour liste_normales et liste_wij
3059 for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
3060 {
3061 MG_TRIANGLE_PEAU* mgtri_i = (MG_TRIANGLE_PEAU*)mgtri;
3062 OT_VECTEUR_3D normal_f_i = mgtri_i->calcul_normal();
3063 normal_f_i.norme();
3064 liste_normales2.ajouter(normal_f_i);
3065 //Remplissage de la liste des voisins du triangle i
3066 TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*> liste_voisins;
3067 MG_NOEUD* noeud1 = mgtri_i->get_noeud1();
3068 double nb_voisins1 = noeud1->get_lien_triangle()->get_nb();
3069 for (int j = 0;j<nb_voisins1;j++)
3070 {
3071 MG_TRIANGLE_PEAU* mgtri_1 = (MG_TRIANGLE_PEAU*) noeud1->get_lien_triangle()->get(j);
3072 liste_voisins.ajouter(mgtri_1);
3073 }
3074 MG_NOEUD* noeud2 = mgtri_i->get_noeud2();
3075 double nb_voisins2 = noeud2->get_lien_triangle()->get_nb();
3076 for (int j = 0;j<nb_voisins2;j++)
3077 {
3078 MG_TRIANGLE_PEAU* mgtri_2 = (MG_TRIANGLE_PEAU*) noeud2->get_lien_triangle()->get(j);
3079 liste_voisins.ajouter(mgtri_2);
3080 }
3081 MG_NOEUD* noeud3 = mgtri_i->get_noeud3();
3082 double nb_voisins3 = noeud3->get_lien_triangle()->get_nb();
3083 for (int j = 0;j<nb_voisins3;j++)
3084 {
3085 MG_TRIANGLE_PEAU* mgtri_3 = (MG_TRIANGLE_PEAU*) noeud3->get_lien_triangle()->get(j);
3086 liste_voisins.ajouter(mgtri_3);
3087 }
3088 liste_voisins.supprimer(mgtri_i);
3089 int nb_voisins = liste_voisins.get_nb();
3090 double w_ij = 1./nb_voisins;
3091 double phi_i_min = 10.;
3092 double s_i = 0.0;
3093 double phi_im = 0.0;
3094 double *phi_ij = new double[nb_voisins];
3095 OT_VECTEUR_3D normal_f_i_mean(0.,0.,0.);
3096 normal_f_i_mean = normal_f_i;
3097 OT_VECTEUR_3D eta_i(0.,0.,0.);
3098 TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*>::ITERATEUR it;
3099 int j = 0;
3100 for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
3101 {
3102 OT_VECTEUR_3D normal_f_j = mgtri_j->calcul_normal();
3103 //1-Calculer la normale moyenne pour chaque triangle
3104 normal_f_i_mean = normal_f_i_mean + normal_f_j;
3105 //2.1-On calcule l'angle entre normal_f_i et normal_f_j pour j allant de 1 a Nb_voisins
3106 double prod_scalaire = normal_f_i*normal_f_j;
3107 if (prod_scalaire > 1.)
3108 {
3109 prod_scalaire = 1.;
3110 }
3111 if (prod_scalaire < -1.)
3112 {
3113 prod_scalaire = -1.;
3114 }
3115 phi_ij[j] = acos(prod_scalaire)*un_sur_pi;
3116 //2.2-On trouve le plus petit des angles et la normale heta_i correspondante
3117 if (phi_ij[j] < phi_i_min)
3118 {
3119 phi_i_min = phi_ij[j];
3120 eta_i = normal_f_j;
3121 }
3122 //3.1-On calcule l'angle moyen phi_im
3123 phi_im = phi_im + w_ij*phi_ij[j];
3124 j++;
3125 }
3126 normal_f_i_mean.norme();
3127 j = 0;
3128 for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
3129 {
3130 //3.2-Calcul de s_i selon la variance
3131 s_i = s_i + w_ij*pow((phi_ij[j] - phi_im),2);
3132 j++;
3133 }
3134 delete[] phi_ij;
3135 //4-On calcule une nouvelle normale pour chaque triangle
3136 double pond;
3137 int num=filtre;
3138 if (num==1) pond=ponderation_gaussian(s_i,sigma);
3139 else if (num==2) pond=ponderation_laplacian(s_i,sigma);
3140 else if (num==3) pond=ponderation_elfallahford(s_i,sigma);
3141 OT_VECTEUR_3D normal_f_i_new = pond*normal_f_i_mean + (1. - pond)*eta_i;
3142 normal_f_i_new.norme();
3143 liste_normales.ajouter(normal_f_i_new);
3144 liste_wij.ajouter(w_ij);
3145 mgtri->change_nouveau_numero(k);
3146 k++;
3147 }
3148
3149 LISTE_MG_NOEUD::iterator it_no;
3150 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
3151 {
3152 int origine = noeud_i->get_origine();
3153 if ((origine != MAGIC::ORIGINE::IMPOSE))//&& (noeud_i->get_lien_topologie()==NULL))///((origine != MAGIC::ORIGINE::IMPOSE)&&(origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&& (noeud_i->get_lien_topologie()==NULL))////////////////////////////////////////////////////////////////////////////
3154 {
3155 int nb_voisins_j = noeud_i->get_lien_triangle()->get_nb();
3156 double w_ij_prime = 0.0;
3157 OT_VECTEUR_3D v_temp(0.,0.,0.);
3158 OT_VECTEUR_3D v_i(noeud_i->get_x(),noeud_i->get_y(),noeud_i->get_z());
3159 for(int j=0;j<nb_voisins_j;j++)
3160 {
3161 MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
3162 //On calcule le centroide cj du triangle mgtri_j
3163 MG_NOEUD* n1 = mgtri_j->get_noeud1();
3164 MG_NOEUD* n2 = mgtri_j->get_noeud2();
3165 MG_NOEUD* n3 = mgtri_j->get_noeud3();
3166 double cj_x = 0.333333333333333*(n1->get_x() + n2->get_x() + n3->get_x());
3167 double cj_y = 0.333333333333333*(n1->get_y() + n2->get_y() + n3->get_y());
3168 double cj_z = 0.333333333333333*(n1->get_z() + n2->get_z() + n3->get_z());
3169 //On forme le vecteur vi_cj
3170 OT_VECTEUR_3D vi_cj(cj_x - noeud_i->get_x(),cj_y - noeud_i->get_y(),cj_z - noeud_i->get_z());
3171 OT_VECTEUR_3D normal_f_i_new = liste_normales.get(mgtri_j->get_nouveau_numero());
3172 v_temp = v_temp + (vi_cj*normal_f_i_new)*normal_f_i_new;
3173 }
3174 //5-On met a jour la position des noeuds
3175 v_i = v_i + (gamma_/(2*nb_voisins_j))*v_temp;
3176 nouv_position_x.push_back(v_i.get_x());
3177 nouv_position_y.push_back(v_i.get_y());
3178 nouv_position_z.push_back(v_i.get_z());
3179 }
3180 }
3181
3182 //On actualise la position des noeuds
3183 int ind_noeud=0;
3184 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
3185 {
3186 int origine = noeud_i->get_origine();
3187 if ((origine != MAGIC::ORIGINE::IMPOSE))//&& (noeud_i->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&& (origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&&(noeud_i->get_lien_topologie()==NULL))/////////////////////////////////////////////////////////////////////////////
3188 {
3189 noeud_i->change_x(nouv_position_x[ind_noeud]);
3190 noeud_i->change_y(nouv_position_y[ind_noeud]);
3191 noeud_i->change_z(nouv_position_z[ind_noeud]);
3192 ind_noeud++;
3193 }
3194 }*/
3195
3196 // code de vérifiaction de triangle retourner
3197 int triangleretourner = 0;
3198 //code qui vérifie la qualité des different trianges
3199 double qualmin=1e300,qualmax=-1e300,qualmoy=0.;
3200 int nbretourne=0;
3201 int itri=0;
3202 double eps_angle_retourne =0.03000;
3203 double borne1 =0.10000;
3204 double borne2 =0.20000;
3205 double borne3 =0.50000;
3206 LISTE_MG_TRIANGLE::iterator ittr;
3207 int nbtrifront=0;
3208 int tab[7]={0,0,0,0,0,0,0};//variable qui vérifie pour s'assuré qu'il n'y a pas de triangle retournés lors du lissage
3209 MG_SOLUTION *sol=NULL;
3210
3211 for (MG_TRIANGLE* tri=mg_mai->get_premier_triangle(ittr);tri!=NULL;tri=mg_mai->get_suivant_triangle(ittr))
3212 {
3213 if (mg_mai->get_nb_mg_tetra()==0)
3214 tri->change_nouveau_numero(1);
3215 if (tri->get_nouveau_numero()==1)
3216 {
3217 nbtrifront++;
3218 tri->get_segment1()->change_nouveau_numero(tri->get_segment1()->get_nouveau_numero()+1);
3219 tri->get_segment2()->change_nouveau_numero(tri->get_segment2()->get_nouveau_numero()+1);
3220 tri->get_segment3()->change_nouveau_numero(tri->get_segment3()->get_nouveau_numero()+1);
3221 tri->get_noeud1()->change_nouveau_numero(1);
3222 tri->get_noeud2()->change_nouveau_numero(1);
3223 tri->get_noeud3()->change_nouveau_numero(1);
3224
3225 }
3226 }
3227 for (MG_TRIANGLE* tri=mg_mai->get_premier_triangle(ittr);tri!=NULL;tri=mg_mai->get_suivant_triangle(ittr))
3228 if (tri->get_nouveau_numero()==1)
3229 {
3230 double qual=OPERATEUR::qualite_triangle(tri->get_noeud1()->get_coord(),tri->get_noeud2()->get_coord(),tri->get_noeud3()->get_coord());
3231 MG_NOEUD * no1=tri->get_noeud1();
3232 MG_NOEUD * no2=tri->get_noeud2();
3233 MG_NOEUD * no3=tri->get_noeud3();
3234 if (no1==no2)
3235 if (no1==no3)
3236 tab[6]++;
3237 int nb1=no1->get_lien_triangle()->get_nb();
3238 int nb2=no2->get_lien_triangle()->get_nb();
3239 int nb3=no3->get_lien_triangle()->get_nb();
3240 OT_VECTEUR_3D vec1(tri->get_noeud1()->get_coord(),tri->get_noeud2()->get_coord());
3241 OT_VECTEUR_3D vec2(tri->get_noeud1()->get_coord(),tri->get_noeud3()->get_coord());
3242 OT_VECTEUR_3D normal=vec1&vec2;
3243 normal.norme();
3244 int nbretourne=0;
3245 int nbvoisin=0;
3246
3247
3248 for (int i=0;i<nb1;i++)
3249 for (int j=0;j<nb2;j++)
3250 {
3251 MG_TRIANGLE* tri1=no1->get_lien_triangle()->get(i);
3252 MG_TRIANGLE* tri2=no2->get_lien_triangle()->get(j);
3253 if ( (tri1==tri2) && (tri1!=tri) && (tri1->get_nouveau_numero()==1))
3254 {
3255 OT_VECTEUR_3D vec1tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud2()->get_coord());
3256 OT_VECTEUR_3D vec2tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud3()->get_coord());
3257 OT_VECTEUR_3D normaltmp=vec1tmp&vec2tmp;
3258 normaltmp.norme();
3259 double psca=normal*normaltmp;
3260 if (psca<-cos(eps_angle_retourne)) nbretourne++;
3261 nbvoisin++;
3262 }
3263 }
3264 for (int i=0;i<nb1;i++)
3265 for (int j=0;j<nb3;j++)
3266 {
3267 MG_TRIANGLE* tri1=no1->get_lien_triangle()->get(i);
3268 MG_TRIANGLE* tri2=no3->get_lien_triangle()->get(j);
3269 if ( (tri1==tri2) && (tri1!=tri) && (tri1->get_nouveau_numero()==1))
3270 {
3271 OT_VECTEUR_3D vec1tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud2()->get_coord());
3272 OT_VECTEUR_3D vec2tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud3()->get_coord());
3273 OT_VECTEUR_3D normaltmp=vec1tmp&vec2tmp;
3274 normaltmp.norme();
3275 double psca=normal*normaltmp;
3276 if (psca<-cos(eps_angle_retourne)) nbretourne++;
3277 nbvoisin++;
3278 }
3279 }
3280 for (int i=0;i<nb2;i++)
3281 for (int j=0;j<nb3;j++)
3282 {
3283 MG_TRIANGLE* tri1=no2->get_lien_triangle()->get(i);
3284 MG_TRIANGLE* tri2=no3->get_lien_triangle()->get(j);
3285 if ( (tri1==tri2) && (tri1!=tri) && (tri1->get_nouveau_numero()==1))
3286 {
3287 OT_VECTEUR_3D vec1tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud2()->get_coord());
3288 OT_VECTEUR_3D vec2tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud3()->get_coord());
3289 OT_VECTEUR_3D normaltmp=vec1tmp&vec2tmp;
3290 normaltmp.norme();
3291 double psca=normal*normaltmp;
3292 if (psca<-cos(eps_angle_retourne)) nbretourne++;
3293 nbvoisin++;
3294 }
3295 }
3296 if (nbvoisin!=3)
3297 tab[5]++;
3298 if (nbretourne>1) qual=-qual;
3299 qualmoy=qualmoy+qual;
3300 if (qual<qualmin) qualmin=qual;
3301 if (qual>qualmax) qualmax=qual;
3302 if (qual<0.) tab[0]++;
3303 else if (qual<borne1) tab[1]++;
3304 else if (qual<borne2) tab[2]++;
3305 else if (qual<borne3) tab[3]++;
3306 else tab[4]++;
3307 if (sol!=NULL)
3308 if (mg_mai->get_nb_mg_tetra()==0) sol->ecrire(qual,itri,0);
3309 itri++;
3310 }
3311 if (tab[0]>0)
3312 {
3313 triangleretourner = 1;
3314 } else
3315 {
3316 triangleretourner = 0;
3317 }
3318
3319
3320
3321
3322
3323 //code de retourenage de triangle inverser avec taubin 1995
3324 if (triangleretourner == 1)
3325 {
3326 do
3327 {
3328 v_taubin_prime = v_taubin;//assignation du volume de l'itération précédente pour fair la loi de controle
3329 int taubin=cycle_taubin1995(mg_mai, gest2, lambda, nu);
3330 /*
3331 /////partie lambda du lissage
3332 vector<double> nouv_position_x;
3333 vector<double> nouv_position_y;
3334 vector<double> nouv_position_z;
3335 LISTE_MG_NOEUD::iterator it_no;
3336 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
3337 {
3338 int origine = noeud_i->get_origine();
3339 if ((origine != MAGIC::ORIGINE::IMPOSE))//&& (noeud_i->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&& (origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&&(noeud_i->get_lien_topologie()==NULL))/////////////////////////////////////////////////////////////////////////////
3340 {
3341 int nb_voisins_j = noeud_i->get_lien_triangle()->get_nb();
3342 double delta_x = 0.0;
3343 double delta_y = 0.0;
3344 double delta_z = 0.0;
3345
3346
3347 double v_x_done[nb_voisins_j];
3348 double v_y_done[nb_voisins_j];
3349 double v_z_done[nb_voisins_j];
3350 double v_i_x = 0.0;
3351 double v_i_y = 0.0;
3352 double v_i_z = 0.0;
3353
3354 for(int j=0;j<nb_voisins_j;j++)
3355 {
3356 if (j==0)
3357 {
3358 for (int jj=0;jj<nb_voisins_j;jj++)
3359 {
3360 v_x_done[jj] = 0.0;
3361 v_y_done[jj] = 0.0;
3362 v_z_done[jj] = 0.0;
3363 }
3364 }
3365
3366
3367 MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
3368 MG_NOEUD* v_1 = mgtri_j->get_noeud1();
3369 MG_NOEUD* v_2 = mgtri_j->get_noeud2();
3370 MG_NOEUD* v_3 = mgtri_j->get_noeud3();
3371 double v_x = noeud_i->get_x();//v_1->get_x();
3372 double v_y = noeud_i->get_y();//v_1->get_y();
3373 double v_z = noeud_i->get_z();//v_1->get_z();
3374 double v_1_x = v_1->get_x();
3375 double v_1_y = v_1->get_y();
3376 double v_1_z = v_1->get_z();
3377 double v_2_x = v_2->get_x();
3378 double v_2_y = v_2->get_y();
3379 double v_2_z = v_2->get_z();
3380 double v_3_x = v_3->get_x();
3381 double v_3_y = v_3->get_y();
3382 double v_3_z = v_3->get_z();
3383
3384 if (((v_1_x == v_x)&&(v_1_y == v_y)&&(v_1_y == v_y)) && (((v_2_x!=v_x_done[0])&&(v_2_y!=v_y_done[0])&&(v_2_z!=v_z_done[0]))||((v_2_x!=v_x_done[1])&&(v_2_y!=v_y_done[1])&&(v_2_z!=v_z_done[1]))||((v_2_x!=v_x_done[2])&&(v_2_y!=v_y_done[2])&&(v_2_z!=v_z_done[2]))||((v_2_x!=v_x_done[3])&&(v_2_y!=v_y_done[3])&&(v_2_z!=v_z_done[3]))||((v_2_x!=v_x_done[4])&&(v_2_y!=v_y_done[4])&&(v_2_z!=v_z_done[4]))||((v_2_x!=v_x_done[5])&&(v_2_y!=v_y_done[5])&&(v_2_z!=v_z_done[5]))||((v_2_x!=v_x_done[6])&&(v_2_y!=v_y_done[6])&&(v_2_z!=v_z_done[6]))||((v_2_x!=v_x_done[7])&&(v_2_y!=v_y_done[7])&&(v_2_z!=v_z_done[7]))||((v_2_x!=v_x_done[8])&&(v_2_y!=v_y_done[8])&&(v_2_z!=v_z_done[8]))||((v_2_x!=v_x_done[9])&&(v_2_y!=v_y_done[9])&&(v_2_z!=v_z_done[9]))))
3385 {
3386 v_i_x = v_2_x;
3387 v_i_y = v_2_y;
3388 v_i_z = v_2_z;
3389 }
3390 else if (((v_3_x == v_x)&&(v_3_y == v_y)&&(v_3_y == v_y)) && (((v_1_x!=v_x_done[0])&&(v_1_y!=v_y_done[0])&&(v_1_z!=v_z_done[0]))||((v_1_x!=v_x_done[1])&&(v_1_y!=v_y_done[1])&&(v_1_z!=v_z_done[1]))||((v_1_x!=v_x_done[2])&&(v_1_y!=v_y_done[2])&&(v_1_z!=v_z_done[2]))||((v_1_x!=v_x_done[3])&&(v_1_y!=v_y_done[3])&&(v_1_z!=v_z_done[3]))||((v_1_x!=v_x_done[4])&&(v_1_y!=v_y_done[4])&&(v_1_z!=v_z_done[4]))||((v_1_x!=v_x_done[5])&&(v_1_y!=v_y_done[5])&&(v_1_z!=v_z_done[5]))||((v_1_x!=v_x_done[6])&&(v_1_y!=v_y_done[6])&&(v_1_z!=v_z_done[6]))||((v_1_x!=v_x_done[7])&&(v_1_y!=v_y_done[7])&&(v_1_z!=v_z_done[7]))||((v_1_x!=v_x_done[8])&&(v_1_y!=v_y_done[8])&&(v_1_z!=v_z_done[8]))||((v_1_x!=v_x_done[9])&&(v_1_y!=v_y_done[9])&&(v_1_z!=v_z_done[9]))))
3391 {
3392 v_i_x = v_1_x;
3393 v_i_y = v_1_y;
3394 v_i_z = v_1_z;
3395 }
3396 else
3397 {
3398 v_i_x = v_3_x;
3399 v_i_y = v_3_y;
3400 v_i_z = v_3_z;
3401 }
3402
3403 v_x_done[j] = v_i_x;
3404 v_y_done[j] = v_i_y;
3405 v_z_done[j] = v_i_z;
3406
3407 double multiplicateur = (1.0/nb_voisins_j);
3408 delta_x = delta_x+(multiplicateur*(v_i_x-v_x));
3409 delta_y = delta_y+(multiplicateur*(v_i_y-v_y));
3410 delta_z = delta_z+(multiplicateur*(v_i_z-v_z));
3411
3412 }
3413 double i_x =noeud_i->get_x();
3414 double i_y =noeud_i->get_y();
3415 double i_z =noeud_i->get_z();
3416 double x_prime = (i_x)+(lambda*delta_x);
3417 double y_prime = (i_y)+(lambda*delta_y);
3418 double z_prime = (i_z)+(lambda*delta_z);
3419
3420 //5-On calcule la nouvelle position des noeuds et on affecte au tableau temporaire
3421 OT_VECTEUR_3D v_premier (x_prime,y_prime,z_prime);
3422 nouv_position_x.push_back(v_premier.get_x());
3423 nouv_position_y.push_back(v_premier.get_y());
3424 nouv_position_z.push_back(v_premier.get_z());
3425 }
3426 }
3427 //On actualise la position des noeuds
3428 int ind_noeud=0;
3429 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
3430 {
3431 int origine = noeud_i->get_origine();
3432 if (origine != MAGIC::ORIGINE::IMPOSE)
3433 {
3434 noeud_i->change_x(nouv_position_x[ind_noeud]);
3435 noeud_i->change_y(nouv_position_y[ind_noeud]);
3436 noeud_i->change_z(nouv_position_z[ind_noeud]);
3437 ind_noeud++;
3438 }
3439 }
3440
3441 //partie nu du lissage
3442 vector<double> nouv_position2_x;
3443 vector<double> nouv_position2_y;
3444 vector<double> nouv_position2_z;
3445 for (MG_NOEUD* noeud_i2=mg_mai->get_premier_noeud(it_no);noeud_i2!=NULL;noeud_i2=mg_mai->get_suivant_noeud(it_no))
3446 {
3447 int origine = noeud_i2->get_origine();
3448 if ((origine != MAGIC::ORIGINE::IMPOSE))//&& (noeud_i2->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&& (origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&&(noeud_i2->get_lien_topologie()==NULL))/////////////////////////////////////////////////////////////////////////////
3449 {
3450 int nb_voisins_j = noeud_i2->get_lien_triangle()->get_nb();
3451 double delta_x = 0.0;
3452 double delta_y = 0.0;
3453 double delta_z = 0.0;
3454 double v_x_done[10];
3455 double v_y_done[10];
3456 double v_z_done[10];
3457 double v_i_x = 0.0;
3458 double v_i_y = 0.0;
3459 double v_i_z = 0.0;
3460
3461 for(int j=0;j<nb_voisins_j;j++)
3462 {
3463 if (j==0)
3464 {
3465 for (int jj=0;jj<10;jj++)
3466 {
3467 v_x_done[jj] = 0.0;
3468 v_y_done[jj] = 0.0;
3469 v_z_done[jj] = 0.0;
3470 }
3471 }
3472
3473
3474 MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i2->get_lien_triangle()->get(j);
3475 MG_NOEUD* v_1 = mgtri_j->get_noeud1();
3476 MG_NOEUD* v_2 = mgtri_j->get_noeud2();
3477 MG_NOEUD* v_3 = mgtri_j->get_noeud3();
3478 double v_x = noeud_i2->get_x();//v_1->get_x();
3479 double v_y = noeud_i2->get_y();//v_1->get_y();
3480 double v_z = noeud_i2->get_z();//v_1->get_z();
3481 double v_1_x = v_1->get_x();
3482 double v_1_y = v_1->get_y();
3483 double v_1_z = v_1->get_z();
3484 double v_2_x = v_2->get_x();
3485 double v_2_y = v_2->get_y();
3486 double v_2_z = v_2->get_z();
3487 double v_3_x = v_3->get_x();
3488 double v_3_y = v_3->get_y();
3489 double v_3_z = v_3->get_z();
3490
3491 if (((v_1_x == v_x)&&(v_1_y == v_y)&&(v_1_y == v_y)) && (((v_2_x!=v_x_done[0])&&(v_2_y!=v_y_done[0])&&(v_2_z!=v_z_done[0]))||((v_2_x!=v_x_done[1])&&(v_2_y!=v_y_done[1])&&(v_2_z!=v_z_done[1]))||((v_2_x!=v_x_done[2])&&(v_2_y!=v_y_done[2])&&(v_2_z!=v_z_done[2]))||((v_2_x!=v_x_done[3])&&(v_2_y!=v_y_done[3])&&(v_2_z!=v_z_done[3]))||((v_2_x!=v_x_done[4])&&(v_2_y!=v_y_done[4])&&(v_2_z!=v_z_done[4]))||((v_2_x!=v_x_done[5])&&(v_2_y!=v_y_done[5])&&(v_2_z!=v_z_done[5]))||((v_2_x!=v_x_done[6])&&(v_2_y!=v_y_done[6])&&(v_2_z!=v_z_done[6]))||((v_2_x!=v_x_done[7])&&(v_2_y!=v_y_done[7])&&(v_2_z!=v_z_done[7]))||((v_2_x!=v_x_done[8])&&(v_2_y!=v_y_done[8])&&(v_2_z!=v_z_done[8]))||((v_2_x!=v_x_done[9])&&(v_2_y!=v_y_done[9])&&(v_2_z!=v_z_done[9]))))
3492 {
3493 v_i_x = v_2_x;
3494 v_i_y = v_2_y;
3495 v_i_z = v_2_z;
3496 }
3497 else if (((v_3_x == v_x)&&(v_3_y == v_y)&&(v_3_y == v_y)) && (((v_1_x!=v_x_done[0])&&(v_1_y!=v_y_done[0])&&(v_1_z!=v_z_done[0]))||((v_1_x!=v_x_done[1])&&(v_1_y!=v_y_done[1])&&(v_1_z!=v_z_done[1]))||((v_1_x!=v_x_done[2])&&(v_1_y!=v_y_done[2])&&(v_1_z!=v_z_done[2]))||((v_1_x!=v_x_done[3])&&(v_1_y!=v_y_done[3])&&(v_1_z!=v_z_done[3]))||((v_1_x!=v_x_done[4])&&(v_1_y!=v_y_done[4])&&(v_1_z!=v_z_done[4]))||((v_1_x!=v_x_done[5])&&(v_1_y!=v_y_done[5])&&(v_1_z!=v_z_done[5]))||((v_1_x!=v_x_done[6])&&(v_1_y!=v_y_done[6])&&(v_1_z!=v_z_done[6]))||((v_1_x!=v_x_done[7])&&(v_1_y!=v_y_done[7])&&(v_1_z!=v_z_done[7]))||((v_1_x!=v_x_done[8])&&(v_1_y!=v_y_done[8])&&(v_1_z!=v_z_done[8]))||((v_1_x!=v_x_done[9])&&(v_1_y!=v_y_done[9])&&(v_1_z!=v_z_done[9]))))
3498 {
3499 v_i_x = v_1_x;
3500 v_i_y = v_1_y;
3501 v_i_z = v_1_z;
3502 }
3503 else
3504 {
3505 v_i_x = v_3_x;
3506 v_i_y = v_3_y;
3507 v_i_z = v_3_z;
3508 }
3509
3510 v_x_done[j] = v_i_x;
3511 v_y_done[j] = v_i_y;
3512 v_z_done[j] = v_i_z;
3513
3514 double multiplicateur = (1.0/nb_voisins_j);
3515 delta_x = delta_x+(multiplicateur*(v_i_x-v_x));
3516 delta_y = delta_y+(multiplicateur*(v_i_y-v_y));
3517 delta_z = delta_z+(multiplicateur*(v_i_z-v_z));
3518 }
3519 double i_x =noeud_i2->get_x();
3520 double i_y =noeud_i2->get_y();
3521 double i_z =noeud_i2->get_z();
3522 double x_prime = (i_x)+(nu_*delta_x);
3523 double y_prime = (i_y)+(nu_*delta_y);
3524 double z_prime = (i_z)+(nu_*delta_z);
3525
3526 //5-On calcule la nouvelle position des noeuds et on affecte au tableau temporaire
3527 OT_VECTEUR_3D v_premier (x_prime,y_prime,z_prime);
3528 nouv_position2_x.push_back(v_premier.get_x());
3529 nouv_position2_y.push_back(v_premier.get_y());
3530 nouv_position2_z.push_back(v_premier.get_z());
3531 }
3532 }
3533 //On actualise la position des noeuds
3534 int ind_noeud2=0;
3535 for (MG_NOEUD* noeud_i2=mg_mai->get_premier_noeud(it_no);noeud_i2!=NULL;noeud_i2=mg_mai->get_suivant_noeud(it_no))
3536 {
3537 int origine = noeud_i2->get_origine();
3538 if ((origine != MAGIC::ORIGINE::IMPOSE))//&& (noeud_i2->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&&(origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&& (noeud_i2->get_lien_topologie()==NULL))/////////////////////////////////////////////////////////////////////////////
3539 {
3540 noeud_i2->change_x(nouv_position2_x[ind_noeud2]);
3541 noeud_i2->change_y(nouv_position2_y[ind_noeud2]);
3542 noeud_i2->change_z(nouv_position2_z[ind_noeud2]);
3543 ind_noeud2++;
3544 }
3545 }*/
3546
3547 /// Calcul du volume
3548 d_taubin=0.;
3549 v_taubin=0;
3550 for (MG_TRIANGLE* ttr=mg_mai->get_premier_triangle(it);ttr!=NULL;ttr=mg_mai->get_suivant_triangle(it))
3551 {
3552 MG_TRIANGLE_PEAU* tri=(MG_TRIANGLE_PEAU*)ttr;
3553 if(tri->get_origine()!=MAGIC::ORIGINE::MAILLEUR_AUTO)
3554 {
3555 MG_NOEUD* no1=tri->get_noeud1();
3556 MG_NOEUD* no2=tri->get_noeud2();
3557 MG_NOEUD* no3=tri->get_noeud3();
3558 double *xyz1=no1->get_coord();
3559 double *xyz2=no2->get_coord();
3560 double *xyz3=no3->get_coord();
3561 OT_VECTEUR_3D vec1(xyz1,xyz2);
3562 OT_VECTEUR_3D vec2(xyz1,xyz3);
3563 OT_VECTEUR_3D pvec=vec2&vec1;
3564 d_taubin=pvec.get_longueur();
3565 OT_VECTEUR_3D N =pvec/(pvec.get_longueur());
3566 OT_VECTEUR_3D F=(1/6.)*(1/3.)*((xyz1+(1/6.)*vec1+(1/6.)*vec2)
3567 +(xyz1+(2/3.)*vec1+(1/6.)*vec2)
3568 +(xyz1+(1/6.)*vec1+(2/3.)*vec2));
3569 v_taubin=v_taubin+d_taubin*N*F;
3570 }
3571 }
3572
3573 //implemantion d'un PI por controler le volume
3574 if (activationPI2 = 1)
3575 {
3576
3577 if (((fabs(v_taubin)-fabs(v_taubin_prime))/fabs(v_taubin))<-0.1)//fine adjustment makes part bigger if new iteration of part is smaller than the preceeding pass and volume is less than 10% bigger than original
3578 {
3579 nu_ =nu_-0.00005;
3580 }
3581
3582 if (((fabs(v_taubin)-fabs(v_taubin_prime))/fabs(v_taubin))>0.1)//fine adjustment makes part smaller if part is much bigger than preceeding pass and the volume is larger than original
3583 {
3584 nu_ = nu_+0.00005;
3585 }
3586
3587 if (fabs(v_taubin)>(fabs(v_initial)*1.015))//gross adjustment makes part smaller if part is 3% bigger than original make smaller
3588 {
3589 nu_ =nu_+0.0005;
3590 }
3591 if (fabs(v_taubin)<(fabs(v_initial)*0.985))//gross adjustment makes part bigger if it is smaller than the original
3592 {
3593 nu_ =nu_-0.0005;
3594 }
3595 }
3596
3597
3598
3599
3600 double un_sur_pi = 1./M_PI;
3601
3602 //code qui vérifie la qualité des different trianges
3603 double qualmin=1e300,qualmax=-1e300,qualmoy=0.;
3604 int nbretourne=0;
3605 int itri=0;
3606 double eps_angle_retourne =0.03000;
3607 double borne1 =0.10000;
3608 double borne2 =0.20000;
3609 double borne3 =0.50000;
3610 LISTE_MG_TRIANGLE::iterator ittr;
3611 int nbtrifront=0;
3612 int tab[7]={0,0,0,0,0,0,0};//variable qui vérifie pour s'assuré qu'il n'y a pas de triangle retournés lors du lissage
3613 MG_SOLUTION *sol=NULL;
3614
3615 for (MG_TRIANGLE* tri=mg_mai->get_premier_triangle(ittr);tri!=NULL;tri=mg_mai->get_suivant_triangle(ittr))
3616 {
3617 if (mg_mai->get_nb_mg_tetra()==0)
3618 tri->change_nouveau_numero(1);
3619 if (tri->get_nouveau_numero()==1)
3620 {
3621 nbtrifront++;
3622 tri->get_segment1()->change_nouveau_numero(tri->get_segment1()->get_nouveau_numero()+1);
3623 tri->get_segment2()->change_nouveau_numero(tri->get_segment2()->get_nouveau_numero()+1);
3624 tri->get_segment3()->change_nouveau_numero(tri->get_segment3()->get_nouveau_numero()+1);
3625 tri->get_noeud1()->change_nouveau_numero(1);
3626 tri->get_noeud2()->change_nouveau_numero(1);
3627 tri->get_noeud3()->change_nouveau_numero(1);
3628
3629 }
3630 }
3631 for (MG_TRIANGLE* tri=mg_mai->get_premier_triangle(ittr);tri!=NULL;tri=mg_mai->get_suivant_triangle(ittr))
3632 if (tri->get_nouveau_numero()==1)
3633 {
3634 double qual=OPERATEUR::qualite_triangle(tri->get_noeud1()->get_coord(),tri->get_noeud2()->get_coord(),tri->get_noeud3()->get_coord());
3635 MG_NOEUD * no1=tri->get_noeud1();
3636 MG_NOEUD * no2=tri->get_noeud2();
3637 MG_NOEUD * no3=tri->get_noeud3();
3638 if (no1==no2)
3639 if (no1==no3)
3640 tab[6]++;
3641 int nb1=no1->get_lien_triangle()->get_nb();
3642 int nb2=no2->get_lien_triangle()->get_nb();
3643 int nb3=no3->get_lien_triangle()->get_nb();
3644 OT_VECTEUR_3D vec1(tri->get_noeud1()->get_coord(),tri->get_noeud2()->get_coord());
3645 OT_VECTEUR_3D vec2(tri->get_noeud1()->get_coord(),tri->get_noeud3()->get_coord());
3646 OT_VECTEUR_3D normal=vec1&vec2;
3647 normal.norme();
3648 int nbretourne=0;
3649 int nbvoisin=0;
3650
3651
3652 for (int i=0;i<nb1;i++)
3653 for (int j=0;j<nb2;j++)
3654 {
3655 MG_TRIANGLE* tri1=no1->get_lien_triangle()->get(i);
3656 MG_TRIANGLE* tri2=no2->get_lien_triangle()->get(j);
3657 if ( (tri1==tri2) && (tri1!=tri) && (tri1->get_nouveau_numero()==1))
3658 {
3659 OT_VECTEUR_3D vec1tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud2()->get_coord());
3660 OT_VECTEUR_3D vec2tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud3()->get_coord());
3661 OT_VECTEUR_3D normaltmp=vec1tmp&vec2tmp;
3662 normaltmp.norme();
3663 double psca=normal*normaltmp;
3664 if (psca<-cos(eps_angle_retourne)) nbretourne++;
3665 nbvoisin++;
3666 }
3667 }
3668 for (int i=0;i<nb1;i++)
3669 for (int j=0;j<nb3;j++)
3670 {
3671 MG_TRIANGLE* tri1=no1->get_lien_triangle()->get(i);
3672 MG_TRIANGLE* tri2=no3->get_lien_triangle()->get(j);
3673 if ( (tri1==tri2) && (tri1!=tri) && (tri1->get_nouveau_numero()==1))
3674 {
3675 OT_VECTEUR_3D vec1tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud2()->get_coord());
3676 OT_VECTEUR_3D vec2tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud3()->get_coord());
3677 OT_VECTEUR_3D normaltmp=vec1tmp&vec2tmp;
3678 normaltmp.norme();
3679 double psca=normal*normaltmp;
3680 if (psca<-cos(eps_angle_retourne)) nbretourne++;
3681 nbvoisin++;
3682 }
3683 }
3684 for (int i=0;i<nb2;i++)
3685 for (int j=0;j<nb3;j++)
3686 {
3687 MG_TRIANGLE* tri1=no2->get_lien_triangle()->get(i);
3688 MG_TRIANGLE* tri2=no3->get_lien_triangle()->get(j);
3689 if ( (tri1==tri2) && (tri1!=tri) && (tri1->get_nouveau_numero()==1))
3690 {
3691 OT_VECTEUR_3D vec1tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud2()->get_coord());
3692 OT_VECTEUR_3D vec2tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud3()->get_coord());
3693 OT_VECTEUR_3D normaltmp=vec1tmp&vec2tmp;
3694 normaltmp.norme();
3695 double psca=normal*normaltmp;
3696 if (psca<-cos(eps_angle_retourne)) nbretourne++;
3697 nbvoisin++;
3698 }
3699 }
3700 if (nbvoisin!=3)
3701 tab[5]++;
3702 if (nbretourne>1) qual=-qual;
3703 qualmoy=qualmoy+qual;
3704 if (qual<qualmin) qualmin=qual;
3705 if (qual>qualmax) qualmax=qual;
3706 if (qual<0.) tab[0]++;
3707 else if (qual<borne1) tab[1]++;
3708 else if (qual<borne2) tab[2]++;
3709 else if (qual<borne3) tab[3]++;
3710 else tab[4]++;
3711 if (sol!=NULL)
3712 if (mg_mai->get_nb_mg_tetra()==0) sol->ecrire(qual,itri,0);
3713 itri++;
3714 }
3715 if (tab[0]>0)
3716 {
3717 triangleretourner = 1;
3718 sprintf(mess, "Trianlge retourner pas régler"); affiche(mess);
3719
3720 }
3721 else
3722 {
3723 triangleretourner = 0;
3724 sprintf(mess, "Trianlge retourner régler"); affiche(mess);
3725 }
3726 compteur_triangle_retourne++;
3727 compteur_taubin_chen++;
3728 compteur_total++;
3729 }
3730
3731 while ((triangleretourner > 0));
3732
3733 }
3734 compteur_total++;
3735 compteur_chen++;
3736
3737
3738 }
3739 while (compteur_chen < iter_max);
3740
3741 sprintf(mess, "Début du retour de volume avec Taubin1995 qui résoud les triangles retournés"); affiche(mess);
3742 // passe final de taubin pour revenir au volume initial
3743 d_taubin=0.;
3744 v_taubin=0;
3745
3746 for (MG_TRIANGLE* ttr=mg_mai->get_premier_triangle(it);ttr!=NULL;ttr=mg_mai->get_suivant_triangle(it))
3747 {
3748 MG_TRIANGLE_PEAU* tri=(MG_TRIANGLE_PEAU*)ttr;
3749 if(tri->get_origine()!=MAGIC::ORIGINE::MAILLEUR_AUTO)//((tri->get_origine()!=MAGIC::ORIGINE::MAILLEUR_AUTO)&& (tri->get_origine()!=MAGIC::ORIGINE::TRIANGULATION_ARETE)&&(tri->get_lien_topologie()==NULL))/////////////////////////////////////////////////////////////////////////////
3750 {
3751 MG_NOEUD* no1=tri->get_noeud1();
3752 MG_NOEUD* no2=tri->get_noeud2();
3753 MG_NOEUD* no3=tri->get_noeud3();
3754 double *xyz1=no1->get_coord();
3755 double *xyz2=no2->get_coord();
3756 double *xyz3=no3->get_coord();
3757 OT_VECTEUR_3D vec1(xyz1,xyz2);
3758 OT_VECTEUR_3D vec2(xyz1,xyz3);
3759 OT_VECTEUR_3D pvec=vec2&vec1;
3760 d_taubin=pvec.get_longueur();
3761 OT_VECTEUR_3D N =pvec/(pvec.get_longueur());
3762 OT_VECTEUR_3D F=(1/6.)*(1/3.)*((xyz1+(1/6.)*vec1+(1/6.)*vec2)
3763 +(xyz1+(2/3.)*vec1+(1/6.)*vec2)
3764 +(xyz1+(1/6.)*vec1+(2/3.)*vec2));
3765 v_taubin=v_taubin+d_taubin*N*F;
3766 }
3767 }
3768
3769 //if ((fabs(fabs(v_initial)-fabs(v_taubin)))>(0.02*(fabs(v_initial))))
3770 if (fabs(v_initial-v_taubin)>(0.02*(fabs(v_initial)))&&(1==2))
3771 {
3772 do
3773 {
3774 v_taubin_prime = v_taubin;
3775 int taubin=cycle_taubin1995(mg_mai, gest2, lambda, nu);
3776 /*
3777 /////partie lambda du lissage
3778 vector<double> nouv_position_x;
3779 vector<double> nouv_position_y;
3780 vector<double> nouv_position_z;
3781 LISTE_MG_NOEUD::iterator it_no;
3782 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
3783 {
3784 int origine = noeud_i->get_origine();
3785 if ((origine != MAGIC::ORIGINE::IMPOSE) && (noeud_i->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE) &&(origine != MAGIC::ORIGINE::TRIANGULATION_ARETE) && (noeud_i->get_lien_topologie()==NULL))/////////////////////////////////////////////////////////////////////////////
3786 {
3787 int nb_voisins_j = noeud_i->get_lien_triangle()->get_nb();
3788 double delta_x = 0.0;
3789 double delta_y = 0.0;
3790 double delta_z = 0.0;
3791
3792
3793 double v_x_done[10];
3794 double v_y_done[10];
3795 double v_z_done[10];
3796 double v_i_x = 0.0;
3797 double v_i_y = 0.0;
3798 double v_i_z = 0.0;
3799
3800 for(int j=0;j<nb_voisins_j;j++)
3801 {
3802 if (j==0)
3803 {
3804 for (int jj=0;jj<10;jj++)
3805 {
3806 v_x_done[jj] = 0.0;
3807 v_y_done[jj] = 0.0;
3808 v_z_done[jj] = 0.0;
3809 }
3810 }
3811
3812
3813 MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i->get_lien_triangle()->get(j);
3814 MG_NOEUD* v_1 = mgtri_j->get_noeud1();
3815 MG_NOEUD* v_2 = mgtri_j->get_noeud2();
3816 MG_NOEUD* v_3 = mgtri_j->get_noeud3();
3817 double v_x = noeud_i->get_x();//v_1->get_x();
3818 double v_y = noeud_i->get_y();//v_1->get_y();
3819 double v_z = noeud_i->get_z();//v_1->get_z();
3820 double v_1_x = v_1->get_x();
3821 double v_1_y = v_1->get_y();
3822 double v_1_z = v_1->get_z();
3823 double v_2_x = v_2->get_x();
3824 double v_2_y = v_2->get_y();
3825 double v_2_z = v_2->get_z();
3826 double v_3_x = v_3->get_x();
3827 double v_3_y = v_3->get_y();
3828 double v_3_z = v_3->get_z();
3829
3830 if (((v_1_x == v_x)&&(v_1_y == v_y)&&(v_1_y == v_y)) && (((v_2_x!=v_x_done[0])&&(v_2_y!=v_y_done[0])&&(v_2_z!=v_z_done[0]))||((v_2_x!=v_x_done[1])&&(v_2_y!=v_y_done[1])&&(v_2_z!=v_z_done[1]))||((v_2_x!=v_x_done[2])&&(v_2_y!=v_y_done[2])&&(v_2_z!=v_z_done[2]))||((v_2_x!=v_x_done[3])&&(v_2_y!=v_y_done[3])&&(v_2_z!=v_z_done[3]))||((v_2_x!=v_x_done[4])&&(v_2_y!=v_y_done[4])&&(v_2_z!=v_z_done[4]))||((v_2_x!=v_x_done[5])&&(v_2_y!=v_y_done[5])&&(v_2_z!=v_z_done[5]))||((v_2_x!=v_x_done[6])&&(v_2_y!=v_y_done[6])&&(v_2_z!=v_z_done[6]))||((v_2_x!=v_x_done[7])&&(v_2_y!=v_y_done[7])&&(v_2_z!=v_z_done[7]))||((v_2_x!=v_x_done[8])&&(v_2_y!=v_y_done[8])&&(v_2_z!=v_z_done[8]))||((v_2_x!=v_x_done[9])&&(v_2_y!=v_y_done[9])&&(v_2_z!=v_z_done[9]))))
3831 {
3832 v_i_x = v_2_x;
3833 v_i_y = v_2_y;
3834 v_i_z = v_2_z;
3835 }
3836 else if (((v_3_x == v_x)&&(v_3_y == v_y)&&(v_3_y == v_y)) && (((v_1_x!=v_x_done[0])&&(v_1_y!=v_y_done[0])&&(v_1_z!=v_z_done[0]))||((v_1_x!=v_x_done[1])&&(v_1_y!=v_y_done[1])&&(v_1_z!=v_z_done[1]))||((v_1_x!=v_x_done[2])&&(v_1_y!=v_y_done[2])&&(v_1_z!=v_z_done[2]))||((v_1_x!=v_x_done[3])&&(v_1_y!=v_y_done[3])&&(v_1_z!=v_z_done[3]))||((v_1_x!=v_x_done[4])&&(v_1_y!=v_y_done[4])&&(v_1_z!=v_z_done[4]))||((v_1_x!=v_x_done[5])&&(v_1_y!=v_y_done[5])&&(v_1_z!=v_z_done[5]))||((v_1_x!=v_x_done[6])&&(v_1_y!=v_y_done[6])&&(v_1_z!=v_z_done[6]))||((v_1_x!=v_x_done[7])&&(v_1_y!=v_y_done[7])&&(v_1_z!=v_z_done[7]))||((v_1_x!=v_x_done[8])&&(v_1_y!=v_y_done[8])&&(v_1_z!=v_z_done[8]))||((v_1_x!=v_x_done[9])&&(v_1_y!=v_y_done[9])&&(v_1_z!=v_z_done[9]))))
3837 {
3838 v_i_x = v_1_x;
3839 v_i_y = v_1_y;
3840 v_i_z = v_1_z;
3841 }
3842 else
3843 {
3844 v_i_x = v_3_x;
3845 v_i_y = v_3_y;
3846 v_i_z = v_3_z;
3847 }
3848
3849 v_x_done[j] = v_i_x;
3850 v_y_done[j] = v_i_y;
3851 v_z_done[j] = v_i_z;
3852
3853 double multiplicateur = (1.0/nb_voisins_j);
3854 delta_x = delta_x+(multiplicateur*(v_i_x-v_x));
3855 delta_y = delta_y+(multiplicateur*(v_i_y-v_y));
3856 delta_z = delta_z+(multiplicateur*(v_i_z-v_z));
3857 }
3858 double i_x =noeud_i->get_x();
3859 double i_y =noeud_i->get_y();
3860 double i_z =noeud_i->get_z();
3861 double x_prime = (i_x)+(lambda*delta_x);
3862 double y_prime = (i_y)+(lambda*delta_y);
3863 double z_prime = (i_z)+(lambda*delta_z);
3864
3865 //5-On calcule la nouvelle position des noeuds et on affecte au tableau temporaire
3866 OT_VECTEUR_3D v_premier (x_prime,y_prime,z_prime);
3867 nouv_position_x.push_back(v_premier.get_x());
3868 nouv_position_y.push_back(v_premier.get_y());
3869 nouv_position_z.push_back(v_premier.get_z());
3870 }
3871 }
3872 //On actualise la position des noeuds
3873 int ind_noeud=0;
3874 for (MG_NOEUD* noeud_i=mg_mai->get_premier_noeud(it_no);noeud_i!=NULL;noeud_i=mg_mai->get_suivant_noeud(it_no))
3875 {
3876 int origine = noeud_i->get_origine();
3877 if ((origine != MAGIC::ORIGINE::IMPOSE)&& (noeud_i->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&&(origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&& (noeud_i->get_lien_topologie()==NULL))/////////////////////////////////////////////////////////////////////////////
3878 {
3879 noeud_i->change_x(nouv_position_x[ind_noeud]);
3880 noeud_i->change_y(nouv_position_y[ind_noeud]);
3881 noeud_i->change_z(nouv_position_z[ind_noeud]);
3882 ind_noeud++;
3883 }
3884 }
3885
3886
3887 //partie nu du lissage
3888 vector<double> nouv_position2_x;
3889 vector<double> nouv_position2_y;
3890 vector<double> nouv_position2_z;
3891 for (MG_NOEUD* noeud_i2=mg_mai->get_premier_noeud(it_no);noeud_i2!=NULL;noeud_i2=mg_mai->get_suivant_noeud(it_no))
3892 {
3893 int origine = noeud_i2->get_origine();
3894 if ((origine != MAGIC::ORIGINE::IMPOSE)&& (noeud_i2->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&&(origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&& (noeud_i2->get_lien_topologie()==NULL))/////////////////////////////////////////////////////////////////////////////
3895 {
3896 int nb_voisins_j = noeud_i2->get_lien_triangle()->get_nb();
3897 double delta_x = 0.0;
3898 double delta_y = 0.0;
3899 double delta_z = 0.0;
3900 double v_x_done[10];
3901 double v_y_done[10];
3902 double v_z_done[10];
3903 double v_i_x = 0.0;
3904 double v_i_y = 0.0;
3905 double v_i_z = 0.0;
3906
3907 for(int j=0;j<nb_voisins_j;j++)
3908 {
3909 if (j==0)
3910 {
3911 for (int jj=0;jj<10;jj++)
3912 {
3913 v_x_done[jj] = 0.0;
3914 v_y_done[jj] = 0.0;
3915 v_z_done[jj] = 0.0;
3916 }
3917 }
3918
3919
3920 MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud_i2->get_lien_triangle()->get(j);
3921 MG_NOEUD* v_1 = mgtri_j->get_noeud1();
3922 MG_NOEUD* v_2 = mgtri_j->get_noeud2();
3923 MG_NOEUD* v_3 = mgtri_j->get_noeud3();
3924 double v_x = noeud_i2->get_x();//v_1->get_x();
3925 double v_y = noeud_i2->get_y();//v_1->get_y();
3926 double v_z = noeud_i2->get_z();//v_1->get_z();
3927 double v_1_x = v_1->get_x();
3928 double v_1_y = v_1->get_y();
3929 double v_1_z = v_1->get_z();
3930 double v_2_x = v_2->get_x();
3931 double v_2_y = v_2->get_y();
3932 double v_2_z = v_2->get_z();
3933 double v_3_x = v_3->get_x();
3934 double v_3_y = v_3->get_y();
3935 double v_3_z = v_3->get_z();
3936
3937 if (((v_1_x == v_x)&&(v_1_y == v_y)&&(v_1_y == v_y)) && (((v_2_x!=v_x_done[0])&&(v_2_y!=v_y_done[0])&&(v_2_z!=v_z_done[0]))||((v_2_x!=v_x_done[1])&&(v_2_y!=v_y_done[1])&&(v_2_z!=v_z_done[1]))||((v_2_x!=v_x_done[2])&&(v_2_y!=v_y_done[2])&&(v_2_z!=v_z_done[2]))||((v_2_x!=v_x_done[3])&&(v_2_y!=v_y_done[3])&&(v_2_z!=v_z_done[3]))||((v_2_x!=v_x_done[4])&&(v_2_y!=v_y_done[4])&&(v_2_z!=v_z_done[4]))||((v_2_x!=v_x_done[5])&&(v_2_y!=v_y_done[5])&&(v_2_z!=v_z_done[5]))||((v_2_x!=v_x_done[6])&&(v_2_y!=v_y_done[6])&&(v_2_z!=v_z_done[6]))||((v_2_x!=v_x_done[7])&&(v_2_y!=v_y_done[7])&&(v_2_z!=v_z_done[7]))||((v_2_x!=v_x_done[8])&&(v_2_y!=v_y_done[8])&&(v_2_z!=v_z_done[8]))||((v_2_x!=v_x_done[9])&&(v_2_y!=v_y_done[9])&&(v_2_z!=v_z_done[9]))))
3938 {
3939 v_i_x = v_2_x;
3940 v_i_y = v_2_y;
3941 v_i_z = v_2_z;
3942 }
3943 else if (((v_3_x == v_x)&&(v_3_y == v_y)&&(v_3_y == v_y)) && (((v_1_x!=v_x_done[0])&&(v_1_y!=v_y_done[0])&&(v_1_z!=v_z_done[0]))||((v_1_x!=v_x_done[1])&&(v_1_y!=v_y_done[1])&&(v_1_z!=v_z_done[1]))||((v_1_x!=v_x_done[2])&&(v_1_y!=v_y_done[2])&&(v_1_z!=v_z_done[2]))||((v_1_x!=v_x_done[3])&&(v_1_y!=v_y_done[3])&&(v_1_z!=v_z_done[3]))||((v_1_x!=v_x_done[4])&&(v_1_y!=v_y_done[4])&&(v_1_z!=v_z_done[4]))||((v_1_x!=v_x_done[5])&&(v_1_y!=v_y_done[5])&&(v_1_z!=v_z_done[5]))||((v_1_x!=v_x_done[6])&&(v_1_y!=v_y_done[6])&&(v_1_z!=v_z_done[6]))||((v_1_x!=v_x_done[7])&&(v_1_y!=v_y_done[7])&&(v_1_z!=v_z_done[7]))||((v_1_x!=v_x_done[8])&&(v_1_y!=v_y_done[8])&&(v_1_z!=v_z_done[8]))||((v_1_x!=v_x_done[9])&&(v_1_y!=v_y_done[9])&&(v_1_z!=v_z_done[9]))))
3944 {
3945 v_i_x = v_1_x;
3946 v_i_y = v_1_y;
3947 v_i_z = v_1_z;
3948 }
3949 else
3950 {
3951 v_i_x = v_3_x;
3952 v_i_y = v_3_y;
3953 v_i_z = v_3_z;
3954 }
3955
3956 v_x_done[j] = v_i_x;
3957 v_y_done[j] = v_i_y;
3958 v_z_done[j] = v_i_z;
3959
3960 double multiplicateur = (1.0/nb_voisins_j);
3961 delta_x = delta_x+(multiplicateur*(v_i_x-v_x));
3962 delta_y = delta_y+(multiplicateur*(v_i_y-v_y));
3963 delta_z = delta_z+(multiplicateur*(v_i_z-v_z));
3964
3965 }
3966 double i_x =noeud_i2->get_x();
3967 double i_y =noeud_i2->get_y();
3968 double i_z =noeud_i2->get_z();
3969 double x_prime = (i_x)+(nu_*delta_x);
3970 double y_prime = (i_y)+(nu_*delta_y);
3971 double z_prime = (i_z)+(nu_*delta_z);
3972
3973 //5-On calcule la nouvelle position des noeuds et on affecte au tableau temporaire
3974 OT_VECTEUR_3D v_premier (x_prime,y_prime,z_prime);
3975 nouv_position2_x.push_back(v_premier.get_x());
3976 nouv_position2_y.push_back(v_premier.get_y());
3977 nouv_position2_z.push_back(v_premier.get_z());
3978 }
3979 }
3980 //On actualise la position des noeuds
3981 int ind_noeud2=0;
3982 for (MG_NOEUD* noeud_i2=mg_mai->get_premier_noeud(it_no);noeud_i2!=NULL;noeud_i2=mg_mai->get_suivant_noeud(it_no))
3983 {
3984 int origine = noeud_i2->get_origine();
3985 if ((origine != MAGIC::ORIGINE::IMPOSE)&& (noeud_i2->get_lien_topologie()==NULL))//((origine != MAGIC::ORIGINE::IMPOSE)&&(origine != MAGIC::ORIGINE::TRIANGULATION_ARETE)&& (noeud_i2->get_lien_topologie()==NULL))/////////////////////////////////////////////////////////////////////////////
3986 {
3987 noeud_i2->change_x(nouv_position2_x[ind_noeud2]);
3988 noeud_i2->change_y(nouv_position2_y[ind_noeud2]);
3989 noeud_i2->change_z(nouv_position2_z[ind_noeud2]);
3990 ind_noeud2++;
3991 }
3992 }*/
3993
3994 /// Calcul du volume
3995 d_taubin=0.;
3996 v_taubin=0;
3997 for (MG_TRIANGLE* ttr=mg_mai->get_premier_triangle(it);ttr!=NULL;ttr=mg_mai->get_suivant_triangle(it))
3998 {
3999 MG_TRIANGLE_PEAU* tri=(MG_TRIANGLE_PEAU*)ttr;
4000 if(tri->get_origine()!=MAGIC::ORIGINE::MAILLEUR_AUTO)
4001 {
4002 MG_NOEUD* no13=tri->get_noeud1();
4003 MG_NOEUD* no23=tri->get_noeud2();
4004 MG_NOEUD* no33=tri->get_noeud3();
4005 double *xyz13=no13->get_coord();
4006 double *xyz23=no23->get_coord();
4007 double *xyz33=no33->get_coord();
4008 OT_VECTEUR_3D vec13(xyz13,xyz23);
4009 OT_VECTEUR_3D vec23(xyz13,xyz33);
4010 OT_VECTEUR_3D pvec3=vec23&vec13;
4011 d_taubin=pvec3.get_longueur();
4012 OT_VECTEUR_3D N =pvec3/(pvec3.get_longueur());
4013 OT_VECTEUR_3D F=(1/6.)*(1/3.)*((xyz13+(1/6.)*vec13+(1/6.)*vec23)
4014 +(xyz13+(2/3.)*vec13+(1/6.)*vec23)
4015 +(xyz13+(1/6.)*vec13+(2/3.)*vec23));
4016 v_taubin=v_taubin+d_taubin*N*F;
4017 }
4018 }
4019
4020 //implemantion d'un PDF pour controler le volume
4021
4022 if (((fabs(v_taubin)-fabs(v_taubin_prime))/fabs(v_taubin))<-0.1)//fine adjustment makes part bigger if new iteration of part is smaller than the preceeding pass and volume is less than 10% bigger than original
4023 {
4024 nu_ =nu_-0.00002;
4025 sprintf(mess, "ajustement mineur 1"); affiche(mess);
4026 }
4027
4028 if (((fabs(v_taubin)-fabs(v_taubin_prime))/fabs(v_taubin))>0.1)//fine adjustment makes part smaller if part is much bigger than preceeding pass and the volume is larger than original
4029 {
4030 nu_ = nu_+0.00002;
4031 sprintf(mess, "ajustement mineur 2"); affiche(mess);
4032 }
4033
4034 if (fabs(v_taubin)>(fabs(v_initial)*1.015))//gross adjustment makes part smaller if part is 1.5% bigger than original make smaller
4035 {
4036 nu_ =nu_+0.0005;
4037 sprintf(mess, "ajustement majeur 1"); affiche(mess);
4038 }
4039 if (fabs(v_taubin)<(fabs(v_initial)*0.985))//gross adjustment makes part bigger if it is more than 1.5% smaller than the original
4040 {
4041 nu_ =nu_-0.0005;
4042 sprintf(mess, "ajustement majeur 2"); affiche(mess);
4043 }
4044 sprintf(mess, "Volume: %f\n old vol: %f\n nu_: %f\n",v_taubin,v_taubin_prime, nu_); affiche(mess);
4045
4046
4047
4048
4049 //code qui vérifie la qualité des different trianges
4050 double qualmin=1e300,qualmax=-1e300,qualmoy=0.;
4051 int nbretourne=0;
4052 int itri=0;
4053 double eps_angle_retourne =0.03000;
4054 double borne1 =0.10000;
4055 double borne2 =0.20000;
4056 double borne3 =0.50000;
4057 LISTE_MG_TRIANGLE::iterator ittr;
4058 int nbtrifront=0;
4059 int tab[7]={0,0,0,0,0,0,0};//variable qui vérifie pour s'assuré qu'il n'y a pas de triangle retournés lors du lissage
4060 MG_SOLUTION *sol=NULL;
4061
4062 for (MG_TRIANGLE* tri=mg_mai->get_premier_triangle(ittr);tri!=NULL;tri=mg_mai->get_suivant_triangle(ittr))
4063 {
4064 if (mg_mai->get_nb_mg_tetra()==0)
4065 tri->change_nouveau_numero(1);
4066 if (tri->get_nouveau_numero()==1)
4067 {
4068 nbtrifront++;
4069 tri->get_segment1()->change_nouveau_numero(tri->get_segment1()->get_nouveau_numero()+1);
4070 tri->get_segment2()->change_nouveau_numero(tri->get_segment2()->get_nouveau_numero()+1);
4071 tri->get_segment3()->change_nouveau_numero(tri->get_segment3()->get_nouveau_numero()+1);
4072 tri->get_noeud1()->change_nouveau_numero(1);
4073 tri->get_noeud2()->change_nouveau_numero(1);
4074 tri->get_noeud3()->change_nouveau_numero(1);
4075
4076 }
4077 }
4078 for (MG_TRIANGLE* tri0=mg_mai->get_premier_triangle(ittr);tri0!=NULL;tri0=mg_mai->get_suivant_triangle(ittr))
4079 if (tri0->get_nouveau_numero()==1)
4080 {
4081 double qual=OPERATEUR::qualite_triangle(tri0->get_noeud1()->get_coord(),tri0->get_noeud2()->get_coord(),tri0->get_noeud3()->get_coord());
4082 MG_NOEUD * no1=tri0->get_noeud1();
4083 MG_NOEUD * no2=tri0->get_noeud2();
4084 MG_NOEUD * no3=tri0->get_noeud3();
4085 if (no1==no2)
4086 if (no1==no3)
4087 tab[6]++;
4088 int nb1=no1->get_lien_triangle()->get_nb();
4089 int nb2=no2->get_lien_triangle()->get_nb();
4090 int nb3=no3->get_lien_triangle()->get_nb();
4091 OT_VECTEUR_3D vec1(tri0->get_noeud1()->get_coord(),tri0->get_noeud2()->get_coord());
4092 OT_VECTEUR_3D vec2(tri0->get_noeud1()->get_coord(),tri0->get_noeud3()->get_coord());
4093 OT_VECTEUR_3D normal=vec1&vec2;
4094 normal.norme();
4095 int nbretourne=0;
4096 int nbvoisin=0;
4097
4098
4099 for (int i=0;i<nb1;i++)
4100 for (int j=0;j<nb2;j++)
4101 {
4102 MG_TRIANGLE* tri1=no1->get_lien_triangle()->get(i);
4103 MG_TRIANGLE* tri2=no2->get_lien_triangle()->get(j);
4104 if ( (tri1==tri2) && (tri1!=tri0) && (tri1->get_nouveau_numero()==1))
4105 {
4106 OT_VECTEUR_3D vec1tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud2()->get_coord());
4107 OT_VECTEUR_3D vec2tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud3()->get_coord());
4108 OT_VECTEUR_3D normaltmp=vec1tmp&vec2tmp;
4109 normaltmp.norme();
4110 double psca=normal*normaltmp;
4111 if (psca<-cos(eps_angle_retourne)) nbretourne++;
4112 nbvoisin++;
4113 }
4114 }
4115 for (int i=0;i<nb1;i++)
4116 for (int j=0;j<nb3;j++)
4117 {
4118 MG_TRIANGLE* tri1=no1->get_lien_triangle()->get(i);
4119 MG_TRIANGLE* tri2=no3->get_lien_triangle()->get(j);
4120 if ( (tri1==tri2) && (tri1!=tri0) && (tri1->get_nouveau_numero()==1))
4121 {
4122 OT_VECTEUR_3D vec1tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud2()->get_coord());
4123 OT_VECTEUR_3D vec2tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud3()->get_coord());
4124 OT_VECTEUR_3D normaltmp=vec1tmp&vec2tmp;
4125 normaltmp.norme();
4126 double psca=normal*normaltmp;
4127 if (psca<-cos(eps_angle_retourne)) nbretourne++;
4128 nbvoisin++;
4129 }
4130 }
4131 for (int i=0;i<nb2;i++)
4132 for (int j=0;j<nb3;j++)
4133 {
4134 MG_TRIANGLE* tri1=no2->get_lien_triangle()->get(i);
4135 MG_TRIANGLE* tri2=no3->get_lien_triangle()->get(j);
4136 if ( (tri1==tri2) && (tri1!=tri0) && (tri1->get_nouveau_numero()==1))
4137 {
4138 OT_VECTEUR_3D vec1tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud2()->get_coord());
4139 OT_VECTEUR_3D vec2tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud3()->get_coord());
4140 OT_VECTEUR_3D normaltmp=vec1tmp&vec2tmp;
4141 normaltmp.norme();
4142 double psca=normal*normaltmp;
4143 if (psca<-cos(eps_angle_retourne)) nbretourne++;
4144 nbvoisin++;
4145 }
4146 }
4147 if (nbvoisin!=3)
4148 tab[5]++;
4149 if (nbretourne>1) qual=-qual;
4150 qualmoy=qualmoy+qual;
4151 if (qual<qualmin) qualmin=qual;
4152 if (qual>qualmax) qualmax=qual;
4153 if (qual<0.) tab[0]++;
4154 else if (qual<borne1) tab[1]++;
4155 else if (qual<borne2) tab[2]++;
4156 else if (qual<borne3) tab[3]++;
4157 else tab[4]++;
4158 if (sol!=NULL)
4159 if (mg_mai->get_nb_mg_tetra()==0) sol->ecrire(qual,itri,0);
4160 itri++;
4161 }
4162 if (tab[0]>0)
4163 {
4164 compteur_triangle_retourne++;
4165 sprintf(mess, "Triangle retourné");
4166 affiche(mess);
4167 triangle_final_retourne =1;
4168 }
4169 else{triangle_final_retourne =0;}
4170
4171 compteur_taubin_final++;
4172 compteur_total++;
4173
4174 }
4175
4176 while ((triangle_final_retourne ==0)&&(fabs(v_initial-v_taubin)>(fabs(0.02*v_initial))));//((compteur_ < 1000));
4177
4178 }
4179
4180 ////////////////////////////calcul du mouvement des noeuds par rapport a l'original
4181 /******************code qui calcule la moyenne de pourcentage de déplacement des differents noeuds*/
4182 double pourcentage_de_deplacement = 0.0;
4183 //LISTE_MG_NOEUD::iterator it_no;
4184 ii=0;
4185 for (MG_NOEUD* noeud=mg_mai->get_premier_noeud(it_no);noeud!=NULL;noeud=mg_mai->get_suivant_noeud(it_no))
4186 {
4187 double difference_de_deplacement = 0;
4188 MG_NOEUD* noe=(MG_NOEUD*)noeud;
4189 if(noe->get_origine()!=MAGIC::ORIGINE::MAILLEUR_AUTO)////////
4190 {
4191 // noeud_i->change_z(nouv_position_z[ind_noeud]);
4192 double vecteur_nouvel_position = (sqrt(pow(noeud->get_x(),2.0))+(pow(noeud->get_y(),2.0))+(pow(noeud->get_z(),2.0)) );
4193 double val_absolue_diff_vecteur = abs(vecteur_nouvel_position-vecteur_original[ii]);
4194 double moyenne_de_longeur_des_arretes_voisines = 0.0;
4195 TPL_MAP_ENTITE<MG_NOEUD*> listno;
4196 int nb_vois = noeud->get_lien_triangle()->get_nb();
4197 for (int iii =0; iii< nb_vois; iii++)
4198 {
4199 MG_TRIANGLE_PEAU* mgtri_j = (MG_TRIANGLE_PEAU*) noeud->get_lien_triangle()->get(iii);
4200 if (mgtri_j->get_noeud1()!=noeud) listno.ajouter(mgtri_j->get_noeud1());
4201 if (mgtri_j->get_noeud2()!=noeud) listno.ajouter(mgtri_j->get_noeud2());
4202 if (mgtri_j->get_noeud3()!=noeud) listno.ajouter(mgtri_j->get_noeud3());
4203 /*
4204
4205 double v_x_done[nb_vois];
4206 double v_y_done[nb_vois];
4207 double v_z_done[nb_vois];
4208 double v_i_x = 0.0;
4209 double v_i_y = 0.0;
4210 double v_i_z = 0.0;
4211 if (iii==0)
4212 {
4213 for (int jj=0;jj<nb_vois;jj++)
4214 {
4215 v_x_done[jj] = 0.0;
4216 v_y_done[jj] = 0.0;
4217 v_z_done[jj] = 0.0;
4218 }
4219 }
4220 MG_NOEUD* v_1 = mgtri_j->get_noeud1();
4221 MG_NOEUD* v_2 = mgtri_j->get_noeud2();
4222 MG_NOEUD* v_3 = mgtri_j->get_noeud3();
4223 double v_x = noeud->get_x();//v_1->get_x();
4224 double v_y = noeud->get_y();//v_1->get_y();
4225 double v_z = noeud->get_z();//v_1->get_z();
4226 double v_1_x = v_1->get_x();
4227 double v_1_y = v_1->get_y();
4228 double v_1_z = v_1->get_z();
4229 double v_2_x = v_2->get_x();
4230 double v_2_y = v_2->get_y();
4231 double v_2_z = v_2->get_z();
4232 double v_3_x = v_3->get_x();
4233 double v_3_y = v_3->get_y();
4234 double v_3_z = v_3->get_z();
4235 if (((v_1_x == v_x)&&(v_1_y == v_y)&&(v_1_y == v_y)) && (((v_2_x!=v_x_done[0])&&(v_2_y!=v_y_done[0])&&(v_2_z!=v_z_done[0]))||((v_2_x!=v_x_done[1])&&(v_2_y!=v_y_done[1])&&(v_2_z!=v_z_done[1]))||((v_2_x!=v_x_done[2])&&(v_2_y!=v_y_done[2])&&(v_2_z!=v_z_done[2]))||((v_2_x!=v_x_done[3])&&(v_2_y!=v_y_done[3])&&(v_2_z!=v_z_done[3]))||((v_2_x!=v_x_done[4])&&(v_2_y!=v_y_done[4])&&(v_2_z!=v_z_done[4]))||((v_2_x!=v_x_done[5])&&(v_2_y!=v_y_done[5])&&(v_2_z!=v_z_done[5]))||((v_2_x!=v_x_done[6])&&(v_2_y!=v_y_done[6])&&(v_2_z!=v_z_done[6]))||((v_2_x!=v_x_done[7])&&(v_2_y!=v_y_done[7])&&(v_2_z!=v_z_done[7]))||((v_2_x!=v_x_done[8])&&(v_2_y!=v_y_done[8])&&(v_2_z!=v_z_done[8]))||((v_2_x!=v_x_done[9])&&(v_2_y!=v_y_done[9])&&(v_2_z!=v_z_done[9]))))
4236 {
4237 v_i_x = v_2_x;
4238 v_i_y = v_2_y;
4239 v_i_z = v_2_z;
4240 }
4241 else if (((v_3_x == v_x)&&(v_3_y == v_y)&&(v_3_y == v_y)) && (((v_1_x!=v_x_done[0])&&(v_1_y!=v_y_done[0])&&(v_1_z!=v_z_done[0]))||((v_1_x!=v_x_done[1])&&(v_1_y!=v_y_done[1])&&(v_1_z!=v_z_done[1]))||((v_1_x!=v_x_done[2])&&(v_1_y!=v_y_done[2])&&(v_1_z!=v_z_done[2]))||((v_1_x!=v_x_done[3])&&(v_1_y!=v_y_done[3])&&(v_1_z!=v_z_done[3]))||((v_1_x!=v_x_done[4])&&(v_1_y!=v_y_done[4])&&(v_1_z!=v_z_done[4]))||((v_1_x!=v_x_done[5])&&(v_1_y!=v_y_done[5])&&(v_1_z!=v_z_done[5]))||((v_1_x!=v_x_done[6])&&(v_1_y!=v_y_done[6])&&(v_1_z!=v_z_done[6]))||((v_1_x!=v_x_done[7])&&(v_1_y!=v_y_done[7])&&(v_1_z!=v_z_done[7]))||((v_1_x!=v_x_done[8])&&(v_1_y!=v_y_done[8])&&(v_1_z!=v_z_done[8]))||((v_1_x!=v_x_done[9])&&(v_1_y!=v_y_done[9])&&(v_1_z!=v_z_done[9]))))
4242 {
4243 v_i_x = v_1_x;
4244 v_i_y = v_1_y;
4245 v_i_z = v_1_z;
4246 }
4247 else
4248 {
4249 v_i_x = v_3_x;
4250 v_i_y = v_3_y;
4251 v_i_z = v_3_z;
4252 }
4253 v_x_done[iii] = v_i_x;
4254 v_y_done[iii] = v_i_y;
4255 v_z_done[iii] = v_i_z;
4256 double posi_voisin = sqrt((pow((v_x_done[iii]),2.0))+(pow((v_y_done[iii]),2.0))+(pow((v_z_done[iii]),2.0)));
4257 double longeur_arrete = abs(posi_voisin-vecteur_original[ii]);
4258 moyenne_de_longeur_des_arretes_voisines=moyenne_de_longeur_des_arretes_voisines+longeur_arrete;
4259 iii++;*/
4260 TPL_MAP_ENTITE<MG_NOEUD*>::ITERATEUR it;
4261 for (MG_NOEUD* notmp=listno.get_premier(it);notmp!=NULL;notmp=listno.get_suivant(it))
4262 {
4263 OT_VECTEUR_3D vec(notmp->get_coord(),noeud->get_coord());
4264 moyenne_de_longeur_des_arretes_voisines=moyenne_de_longeur_des_arretes_voisines+vec.get_longueur();
4265 }
4266 }
4267 moyenne_de_longeur_des_arretes_voisines = moyenne_de_longeur_des_arretes_voisines/listno.get_nb();
4268 pourcentage_de_deplacement = pourcentage_de_deplacement+(val_absolue_diff_vecteur/moyenne_de_longeur_des_arretes_voisines);
4269 ii++;
4270 }
4271 }
4272 double moyenne_de_pourcentage_de_deplacement= pourcentage_de_deplacement/ii;
4273 sprintf(mess, "Moyenne de Pourcentage de déplacment: %f", moyenne_de_pourcentage_de_deplacement); affiche(mess);
4274
4275
4276
4277
4278 /// Calcul du volume final
4279 d_final=0.;
4280 v_final=0.;
4281 for (MG_TRIANGLE* ttr=mg_mai->get_premier_triangle(it);ttr!=NULL;ttr=mg_mai->get_suivant_triangle(it))
4282 {
4283 MG_TRIANGLE_PEAU* tri=(MG_TRIANGLE_PEAU*)ttr;
4284 if(tri->get_origine()!=MAGIC::ORIGINE::MAILLEUR_AUTO)
4285 {
4286 MG_NOEUD* no1=tri->get_noeud1();
4287 MG_NOEUD* no2=tri->get_noeud2();
4288 MG_NOEUD* no3=tri->get_noeud3();
4289 double *xyz1=no1->get_coord();
4290 double *xyz2=no2->get_coord();
4291 double *xyz3=no3->get_coord();
4292 OT_VECTEUR_3D vec1(xyz1,xyz2);
4293 OT_VECTEUR_3D vec2(xyz1,xyz3);
4294 OT_VECTEUR_3D pvec=vec2&vec1;
4295
4296 d_final=pvec.get_longueur();
4297 OT_VECTEUR_3D N =pvec/(pvec.get_longueur());
4298 OT_VECTEUR_3D F=(1/6.)*(1/3.)*((xyz1+(1/6.)*vec1+(1/6.)*vec2)
4299 +(xyz1+(2/3.)*vec1+(1/6.)*vec2)
4300 +(xyz1+(1/6.)*vec1+(2/3.)*vec2));
4301 v_final=v_final+d_final*N*F;
4302 }
4303 }
4304 double delta_vol = v_final-v_initial;
4305 double vol_pourcent = (v_final/v_initial)*100;
4306 double delta_vol_pourcent = vol_pourcent-100;
4307 sprintf(mess, "Volume initial: %f",v_initial);affiche(mess);
4308 sprintf(mess, "Volume final: %f",v_final);affiche(mess);
4309 sprintf(mess, "Volume final pourcentage: %f",vol_pourcent);affiche(mess);
4310 sprintf(mess, "Delta Volume: %f",delta_vol);affiche(mess);
4311 sprintf(mess, "Delta Volume pourcentage: %f",delta_vol_pourcent);affiche(mess);
4312 sprintf(mess, " Iteration inital Taubin1995: %i",compteur_taubin_initial); affiche(mess);
4313 sprintf(mess, " Iteration Chen2008: %i",compteur_chen); affiche(mess);
4314 sprintf(mess, " Iteration Taubin1995 dans Chen2008: %i",compteur_taubin_chen); affiche(mess);
4315 sprintf(mess, " epsilon: %f",epsilon); affiche(mess);
4316 sprintf(mess, " sigma: %f",sigma); affiche(mess);
4317 sprintf(mess, " gamma_: %f",gamma_); affiche(mess);
4318 sprintf(mess, " filtre: %i",filtre); affiche(mess);
4319 sprintf(mess, " Iteration final Taubin1995: %i",compteur_taubin_final); affiche(mess);
4320 sprintf(mess, " lambda(depart): %f",lambda); affiche(mess);
4321 sprintf(mess, " nu(depart):%f",nu); affiche(mess);
4322 sprintf(mess, " nu(fin):%f",nu_); affiche(mess);
4323 sprintf(mess, " Iteration triangle retourné: %i",compteur_triangle_retourne); affiche(mess);
4324 sprintf(mess, " Iteration Total: %i",compteur_total); affiche(mess);
4325
4326
4327
4328
4329 //verification de nombre de triange retournée
4330 sprintf(mess,"ANALYSEUR DE MG MAILLAGE 3D"); affiche(mess);
4331 double qualmin=1e300,qualmax=-1e300,qualmoy=0.;
4332 int tab[7]={0,0,0,0,0,0,0};
4333 int itri=0;
4334 double eps_angle_retourne =0.03000;
4335 double borne1 =0.10000;
4336 double borne2 =0.20000;
4337 double borne3 =0.50000;
4338 LISTE_MG_TRIANGLE::iterator ittr;
4339 int nbtrifront=0;
4340 MG_SOLUTION *sol=NULL;
4341
4342 for (MG_TRIANGLE* tri=mg_mai->get_premier_triangle(ittr);tri!=NULL;tri=mg_mai->get_suivant_triangle(ittr))
4343 {
4344 if (mg_mai->get_nb_mg_tetra()==0)
4345 tri->change_nouveau_numero(1);
4346 if (tri->get_nouveau_numero()==1)
4347 {
4348 nbtrifront++;
4349 tri->get_segment1()->change_nouveau_numero(tri->get_segment1()->get_nouveau_numero()+1);
4350 tri->get_segment2()->change_nouveau_numero(tri->get_segment2()->get_nouveau_numero()+1);
4351 tri->get_segment3()->change_nouveau_numero(tri->get_segment3()->get_nouveau_numero()+1);
4352 tri->get_noeud1()->change_nouveau_numero(1);
4353 tri->get_noeud2()->change_nouveau_numero(1);
4354 tri->get_noeud3()->change_nouveau_numero(1);
4355
4356 }
4357 }
4358 for (MG_TRIANGLE* tri=mg_mai->get_premier_triangle(ittr);tri!=NULL;tri=mg_mai->get_suivant_triangle(ittr))
4359 if (tri->get_nouveau_numero()==1)
4360 {
4361 double qual=OPERATEUR::qualite_triangle(tri->get_noeud1()->get_coord(),tri->get_noeud2()->get_coord(),tri->get_noeud3()->get_coord());
4362 MG_NOEUD * no1=tri->get_noeud1();
4363 MG_NOEUD * no2=tri->get_noeud2();
4364 MG_NOEUD * no3=tri->get_noeud3();
4365 if (no1==no2)
4366 if (no1==no3)
4367 tab[6]++;
4368 int nb1=no1->get_lien_triangle()->get_nb();
4369 int nb2=no2->get_lien_triangle()->get_nb();
4370 int nb3=no3->get_lien_triangle()->get_nb();
4371 OT_VECTEUR_3D vec1(tri->get_noeud1()->get_coord(),tri->get_noeud2()->get_coord());
4372 OT_VECTEUR_3D vec2(tri->get_noeud1()->get_coord(),tri->get_noeud3()->get_coord());
4373 OT_VECTEUR_3D normal=vec1&vec2;
4374 normal.norme();
4375 int nbretourne=0;
4376 int nbvoisin=0;
4377 for (int i=0;i<nb1;i++)
4378 for (int j=0;j<nb2;j++)
4379 {
4380 MG_TRIANGLE* tri1=no1->get_lien_triangle()->get(i);
4381 MG_TRIANGLE* tri2=no2->get_lien_triangle()->get(j);
4382 if ( (tri1==tri2) && (tri1!=tri) && (tri1->get_nouveau_numero()==1))
4383 {
4384 OT_VECTEUR_3D vec1tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud2()->get_coord());
4385 OT_VECTEUR_3D vec2tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud3()->get_coord());
4386 OT_VECTEUR_3D normaltmp=vec1tmp&vec2tmp;
4387 normaltmp.norme();
4388 double psca=normal*normaltmp;
4389 if (psca<-cos(eps_angle_retourne)) nbretourne++;
4390 nbvoisin++;
4391 }
4392 }
4393 for (int i=0;i<nb1;i++)
4394 for (int j=0;j<nb3;j++)
4395 {
4396 MG_TRIANGLE* tri1=no1->get_lien_triangle()->get(i);
4397 MG_TRIANGLE* tri2=no3->get_lien_triangle()->get(j);
4398 if ( (tri1==tri2) && (tri1!=tri) && (tri1->get_nouveau_numero()==1))
4399 {
4400 OT_VECTEUR_3D vec1tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud2()->get_coord());
4401 OT_VECTEUR_3D vec2tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud3()->get_coord());
4402 OT_VECTEUR_3D normaltmp=vec1tmp&vec2tmp;
4403 normaltmp.norme();
4404 double psca=normal*normaltmp;
4405 if (psca<-cos(eps_angle_retourne)) nbretourne++;
4406 nbvoisin++;
4407 }
4408 }
4409 for (int i=0;i<nb2;i++)
4410 for (int j=0;j<nb3;j++)
4411 {
4412 MG_TRIANGLE* tri1=no2->get_lien_triangle()->get(i);
4413 MG_TRIANGLE* tri2=no3->get_lien_triangle()->get(j);
4414 if ( (tri1==tri2) && (tri1!=tri) && (tri1->get_nouveau_numero()==1))
4415 {
4416 OT_VECTEUR_3D vec1tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud2()->get_coord());
4417 OT_VECTEUR_3D vec2tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud3()->get_coord());
4418 OT_VECTEUR_3D normaltmp=vec1tmp&vec2tmp;
4419 normaltmp.norme();
4420 double psca=normal*normaltmp;
4421 if (psca<-cos(eps_angle_retourne)) nbretourne++;
4422 nbvoisin++;
4423 }
4424 }
4425 if (nbvoisin!=3)
4426 tab[5]++;
4427 if (nbretourne>1) qual=-qual;
4428 qualmoy=qualmoy+qual;
4429 if (qual<qualmin) qualmin=qual;
4430 if (qual>qualmax) qualmax=qual;
4431 if (qual<0.) tab[0]++;
4432 else if (qual<borne1) tab[1]++;
4433 else if (qual<borne2) tab[2]++;
4434 else if (qual<borne3) tab[3]++;
4435 else tab[4]++;
4436 if (sol!=NULL)
4437 if (mg_mai->get_nb_mg_tetra()==0) sol->ecrire(qual,itri,0);
4438 itri++;
4439 }
4440
4441 if (nbtrifront!=0)
4442 {
4443 sprintf(mess," Nombre de triangles avec des noeuds fusionnés : %d",tab[6]); affiche(mess);
4444 sprintf(mess," Nombre de triangles avec 1 voisin manquant : %d",tab[5]); affiche(mess);
4445 sprintf(mess," critere d'angle limite pour l'inversion : %lf",eps_angle_retourne); affiche(mess);
4446 sprintf(mess," qualite moyenne des triangles de frontiere : %lf",qualmoy/nbtrifront); affiche(mess);
4447 sprintf(mess," qualite min des triangles de frontiere : %lf",qualmin); affiche(mess);
4448 sprintf(mess," qualite max des triangles de frontiere : %lf",qualmax); affiche(mess);
4449 sprintf(mess," nombre de triangles de frontiere >%lf : %d (%.2lf%%)",borne3,tab[4],tab[4]*100./nbtrifront); affiche(mess);
4450 sprintf(mess," nombre de triangles de frontiere >%lf : %d (%.2lf%%)",borne2,tab[3],tab[3]*100./nbtrifront); affiche(mess);
4451 sprintf(mess," nombre de triangles de frontiere >%lf : %d (%.2lf%%)",borne1,tab[2],tab[2]*100./nbtrifront); affiche(mess);
4452 sprintf(mess," nombre de triangles de frontiere >%lf : %d (%.2lf%%)",0.,tab[1],tab[1]*100./nbtrifront); affiche(mess);
4453 sprintf(mess," nombre de triangles de frontiere retournes : %d (%.2lf%%)",tab[0],tab[0]*100./nbtrifront); affiche(mess);
4454 }
4455
4456 //calcule de la varience et l'écart type pour la surface du maillaige
4457 double varience2 = varience_taubin1995(mg_mai,gest2,1);
4458 /*
4459 ecart_type = 0;
4460 s_i = 0.0;
4461 phi_im = 0.0;
4462 ecart_type_i = 0.;
4463 do
4464 {
4465 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales;
4466 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales2;
4467 TPL_LISTE_ENTITE<double> liste_wij;
4468 LISTE_MG_TRIANGLE::iterator it_tri;
4469 int k = 0; //pour identifier les triangles pour liste_normales et liste_wij
4470 for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
4471 {
4472 MG_TRIANGLE_PEAU* mgtri_i = (MG_TRIANGLE_PEAU*)mgtri;
4473 OT_VECTEUR_3D normal_f_i = mgtri_i->calcul_normal();
4474 normal_f_i.norme();
4475 liste_normales2.ajouter(normal_f_i);
4476 //Remplissage de la liste des voisins du triangle i
4477 TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*> liste_voisins;
4478 MG_NOEUD* noeud1 = mgtri_i->get_noeud1();
4479 double nb_voisins1 = noeud1->get_lien_triangle()->get_nb();
4480 for (int j = 0;j<nb_voisins1;j++)
4481 {
4482 MG_TRIANGLE_PEAU* mgtri_1 = (MG_TRIANGLE_PEAU*) noeud1->get_lien_triangle()->get(j);
4483 liste_voisins.ajouter(mgtri_1);
4484 }
4485 MG_NOEUD* noeud2 = mgtri_i->get_noeud2();
4486 double nb_voisins2 = noeud2->get_lien_triangle()->get_nb();
4487 for (int j = 0;j<nb_voisins2;j++)
4488 {
4489 MG_TRIANGLE_PEAU* mgtri_2 = (MG_TRIANGLE_PEAU*) noeud2->get_lien_triangle()->get(j);
4490 liste_voisins.ajouter(mgtri_2);
4491 }
4492 MG_NOEUD* noeud3 = mgtri_i->get_noeud3();
4493 double nb_voisins3 = noeud3->get_lien_triangle()->get_nb();
4494 for (int j = 0;j<nb_voisins3;j++)
4495 {
4496 MG_TRIANGLE_PEAU* mgtri_3 = (MG_TRIANGLE_PEAU*) noeud3->get_lien_triangle()->get(j);
4497 liste_voisins.ajouter(mgtri_3);
4498 }
4499 liste_voisins.supprimer(mgtri_i);
4500 int nb_voisins = liste_voisins.get_nb();
4501 double w_ij = 1./nb_voisins;
4502 double phi_i_min = 10.;
4503 s_i = 0.0;
4504 phi_im = 0.0;
4505 double *phi_ij = new double[nb_voisins];
4506 OT_VECTEUR_3D normal_f_i_mean(0.,0.,0.);
4507 normal_f_i_mean = normal_f_i;
4508 OT_VECTEUR_3D eta_i(0.,0.,0.);
4509 TPL_MAP_ENTITE<MG_TRIANGLE_PEAU*>::ITERATEUR it;
4510 int j = 0;
4511 double un_sur_pi = 1./M_PI;
4512 for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
4513 {
4514 OT_VECTEUR_3D normal_f_j = mgtri_j->calcul_normal();
4515 //1-Calculer la normale moyenne pour chaque triangle
4516 normal_f_i_mean = normal_f_i_mean + normal_f_j;
4517 //2.1-On calcule l'angle entre normal_f_i et normal_f_j pour j allant de 1 a Nb_voisins
4518 double prod_scalaire = normal_f_i*normal_f_j;
4519 if (prod_scalaire > 1.)
4520 {
4521 prod_scalaire = 1.;
4522 }
4523 if (prod_scalaire < -1.)
4524 {
4525 prod_scalaire = -1.;
4526 }
4527 phi_ij[j] = acos(prod_scalaire)*un_sur_pi;
4528 //2.2-On trouve le plus petit des angles et la normale heta_i correspondante
4529 if (phi_ij[j] < phi_i_min)
4530 {
4531 phi_i_min = phi_ij[j];
4532 eta_i = normal_f_j;
4533 }
4534 //3.1-On calcule l'angle moyen phi_im
4535 phi_im = phi_im + w_ij*phi_ij[j];
4536 j++;
4537 }
4538 normal_f_i_mean.norme();
4539 j = 0;
4540 for(MG_TRIANGLE_PEAU* mgtri_j=liste_voisins.get_premier(it);mgtri_j!=NULL;mgtri_j=liste_voisins.get_suivant(it))
4541 {
4542 //3.2-Calcul de s_i selon la variance
4543 s_i = s_i + w_ij*pow((phi_ij[j] - phi_im),2);
4544 j++;
4545 }
4546 delete[] phi_ij;
4547 }
4548 ecart_type_i = sqrt(s_i);
4549 sprintf(mess," Moyenne des normes des triangles de la surface : %f",phi_im); affiche(mess);
4550 sprintf(mess," Varience des normes des triangles de la surface : %f",s_i); affiche(mess);
4551 sprintf(mess," Ecart type des normes des triangles de la surface : %f",ecart_type_i); affiche(mess);
4552 ecart_type = 1;
4553 }
4554 while (ecart_type == 0);*/
4555
4556
4557 return compteur_total;
4558 }
4559
4560
4561
4562
4563 //---------------------------- Extract skin -------------------------------------------------------------------------
4564 int MGOPT_POSTTRAITEMENT::extract_skin(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2,int &nbpeau,int &nbmaniare,int &nbmanino, int *mai2_id)
4565 {
4566
4567 //etape 0 - On commence par mettre a zero tous les nouveau_numero des triangles et des noeuds du maillage
4568 LISTE_MG_TRIANGLE::iterator it_tri;
4569 for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
4570 {
4571 mgtri->change_nouveau_numero(0);
4572 mgtri->change_origine(MAGIC::ORIGINE::MAILLEUR_AUTO);
4573 }
4574 LISTE_MG_NOEUD::iterator it_noeud;
4575 for (MG_NOEUD* mgnoeud=mg_mai->get_premier_noeud(it_noeud);mgnoeud!=NULL;mgnoeud=mg_mai->get_suivant_noeud(it_noeud))
4576 {
4577 mgnoeud->change_nouveau_numero(0);
4578 }
4579
4580 //etape 1 - On boucle ensuite tous les tetraedres pour ajouter un compteur du nombre de fois qu'un triangle appartient a 1 tetra
4581 LISTE_MG_TETRA::iterator it_tetra;
4582 for (MG_TETRA* mgtet=mg_mai->get_premier_tetra(it_tetra);mgtet!=NULL;mgtet=mg_mai->get_suivant_tetra(it_tetra))
4583 {
4584 int origine = mgtet->get_origine();
4585 if (origine==MAGIC::ORIGINE::IMPOSE)
4586 {
4587 mgtet->get_triangle1()->change_origine(MAGIC::ORIGINE::IMPOSE);
4588 mgtet->get_triangle2()->change_origine(MAGIC::ORIGINE::IMPOSE);
4589 mgtet->get_triangle3()->change_origine(MAGIC::ORIGINE::IMPOSE);
4590 mgtet->get_triangle4()->change_origine(MAGIC::ORIGINE::IMPOSE);
4591 }
4592 if (origine==MAGIC::ORIGINE::OPTIMISE)
4593 {
4594 if (mgtet->get_triangle1()->get_origine()!=MAGIC::ORIGINE::IMPOSE) mgtet->get_triangle1()->change_origine(MAGIC::ORIGINE::OPTIMISE);
4595 if (mgtet->get_triangle2()->get_origine()!=MAGIC::ORIGINE::IMPOSE) mgtet->get_triangle2()->change_origine(MAGIC::ORIGINE::OPTIMISE);
4596 if (mgtet->get_triangle3()->get_origine()!=MAGIC::ORIGINE::IMPOSE) mgtet->get_triangle3()->change_origine(MAGIC::ORIGINE::OPTIMISE);
4597 if (mgtet->get_triangle4()->get_origine()!=MAGIC::ORIGINE::IMPOSE) mgtet->get_triangle4()->change_origine(MAGIC::ORIGINE::OPTIMISE);
4598 }
4599
4600 if (((origine == MAGIC::ORIGINE::OPTIMISE) && (etat[(MAGIC::ORIGINE::OPTIMISE-1000)/10]==1) ) ||
4601 ((origine == MAGIC::ORIGINE::IMPOSE) && (etat[(MAGIC::ORIGINE::IMPOSE-1000)/10]==1) ) ||
4602 ((origine == MAGIC::ORIGINE::MAILLEUR_AUTO) && (etat[(MAGIC::ORIGINE::MAILLEUR_AUTO-1000)/10]==1) ) ||
4603 ((origine == MAGIC::ORIGINE::TRIANGULATION) && (etat[(MAGIC::ORIGINE::TRIANGULATION-1000)/10]==1) ) ||
4604 ((origine == MAGIC::ORIGINE::MODIFICATION) && (etat[(MAGIC::ORIGINE::MODIFICATION-1000)/10]==1) ) ||
4605 ((origine == MAGIC::ORIGINE::DUPLIQUER) && (etat[(MAGIC::ORIGINE::DUPLIQUER-1000)/10]==1) ) )
4606
4607 {
4608 int num1 = mgtet->get_triangle1()->get_nouveau_numero();
4609 int num2 = mgtet->get_triangle2()->get_nouveau_numero();
4610 int num3 = mgtet->get_triangle3()->get_nouveau_numero();
4611 int num4 = mgtet->get_triangle4()->get_nouveau_numero();
4612 num1++;
4613 num2++;
4614 num3++;
4615 num4++;
4616 mgtet->get_triangle1()->change_nouveau_numero(num1);
4617 mgtet->get_triangle2()->change_nouveau_numero(num2);
4618 mgtet->get_triangle3()->change_nouveau_numero(num3);
4619 mgtet->get_triangle4()->change_nouveau_numero(num4);
4620 }
4621 }
4622
4623 //etape 2 - On boucle l'ensemble des triangles identifies a l'etape 1 pour identifier les noeuds leur appartenant
4624 for (MG_TRIANGLE* mgtri=mg_mai->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mg_mai->get_suivant_triangle(it_tri))
4625 {
4626 int num = mgtri->get_nouveau_numero();
4627 if (num == 1)
4628 {
4629 MG_NOEUD* noeud1 = mgtri->get_noeud1();
4630 MG_NOEUD* noeud2 = mgtri->get_noeud2();
4631 MG_NOEUD* noeud3 = mgtri->get_noeud3();
4632 noeud1->change_nouveau_numero(1);
4633 noeud2->change_nouveau_numero(1);
4634 noeud3->change_nouveau_numero(1);
4635 if (mgtri->get_origine()==MAGIC::ORIGINE::IMPOSE)
4636 {
4637 noeud1->change_origine(MAGIC::ORIGINE::IMPOSE);
4638 noeud2->change_origine(MAGIC::ORIGINE::IMPOSE);
4639 noeud3->change_origine(MAGIC::ORIGINE::IMPOSE);
4640 }
4641 }
4642 }
4643
4644 //etape 3 - On cree un nouveau maillage pour la peau
4645 gest2.vide();
4646 MG_GEOMETRIE* geo=new MG_GEOMETRIE((char*)"VIRTUEL",(char*)"VIRTUEL");
4647 geo->change_valeur_unite(mg_mai->get_mg_geometrie()->get_valeur_unite());
4648 gest2.ajouter_mg_geometrie(geo);
4649 MG_FACE_ELEMENT* face=new MG_FACE_ELEMENT();
4650 geo->ajouter_mg_face(face);
4651 MG_MAILLAGE* mai2 = new MG_MAILLAGE(geo);
4652 gest2.ajouter_mg_maillage(mai2);
4653
4654 //etape 4 - On boucle l'ensemble des noeuds identifies a l'etape 2 pour les recreer dans le second maillage
4655 for (MG_NOEUD* mgnoeud=mg_mai->get_premier_noeud(it_noeud);mgnoeud!=NULL;mgnoeud=mg_mai->get_suivant_noeud(it_noeud))
4656 {
4657 int num = mgnoeud->get_nouveau_numero();
4658 if (num == 1)
4659 {
4660 double x = mgnoeud->get_x();
4661 double y = mgnoeud->get_y();
4662 double z = mgnoeud->get_z();
4663 int origine=MAGIC::ORIGINE::TRIANGULATION;
4664 int nb_tri=mgnoeud->get_lien_triangle()->get_nb();
4665 bool tri2d=false,tri3d=false;
4666 for (int i=0;i<nb_tri;i++)
4667 {
4668 if (mgnoeud->get_lien_triangle()->get(i)->get_nouveau_numero()==1)
4669 {
4670 if (mgnoeud->get_lien_triangle()->get(i)->get_lien_topologie()->get_dimension()==2) tri2d=true;
4671 if (mgnoeud->get_lien_triangle()->get(i)->get_lien_topologie()->get_dimension()==3) tri3d=true;
4672 }
4673 }
4674 if ((tri2d)&&(tri3d)) origine=MAGIC::ORIGINE::TRIANGULATION_ARETE;
4675 if (mgnoeud->get_lien_topologie()->get_dimension()==1) origine=MAGIC::ORIGINE::TRIANGULATION_ARETE;
4676 if (mgnoeud->get_origine()==MAGIC::ORIGINE::IMPOSE) origine=MAGIC::ORIGINE::IMPOSE;
4677 MG_NOEUD* noeud1 = new MG_NOEUD(NULL,x,y,z,origine);
4678 mai2->ajouter_mg_noeud(noeud1);
4679 mgnoeud->change_nouveau_numero(noeud1->get_id());
4680 noeud1->change_nouveau_numero(mgnoeud->get_id());
4681 }
4682 }
4683
4684 // etape 5 - On boucle l'ensemble des triangles identifies a l'etape 1 pour les recreer dans le maillage 2
4685 for (MG_TETRA* mgtet=mg_mai->get_premier_tetra(it_tetra);mgtet!=NULL;mgtet=mg_mai->get_suivant_tetra(it_tetra))
4686 {
4687 int originetet=mgtet->get_origine();
4688 if (((originetet == MAGIC::ORIGINE::OPTIMISE) && (etat[(MAGIC::ORIGINE::OPTIMISE-1000)/10]==1) ) ||
4689 ((originetet == MAGIC::ORIGINE::IMPOSE) && (etat[(MAGIC::ORIGINE::IMPOSE-1000)/10]==1) ) ||
4690 ((originetet == MAGIC::ORIGINE::MAILLEUR_AUTO) && (etat[(MAGIC::ORIGINE::MAILLEUR_AUTO-1000)/10]==1) ) ||
4691 ((originetet == MAGIC::ORIGINE::TRIANGULATION) && (etat[(MAGIC::ORIGINE::TRIANGULATION-1000)/10]==1) ) ||
4692 ((originetet == MAGIC::ORIGINE::MODIFICATION) && (etat[(MAGIC::ORIGINE::MODIFICATION-1000)/10]==1) ) ||
4693 ((originetet == MAGIC::ORIGINE::DUPLIQUER) && (etat[(MAGIC::ORIGINE::DUPLIQUER-1000)/10]==1) ) )
4694 {
4695 MG_NOEUD* noeud1 = mgtet->get_noeud1();
4696 MG_NOEUD* noeud2 = mgtet->get_noeud2();
4697 MG_NOEUD* noeud3 = mgtet->get_noeud3();
4698 MG_NOEUD* noeud4 = mgtet->get_noeud4();
4699 MG_NOEUD* node1 = mai2->get_mg_noeudid(noeud1->get_nouveau_numero());
4700 MG_NOEUD* node2 = mai2->get_mg_noeudid(noeud2->get_nouveau_numero());
4701 MG_NOEUD* node3 = mai2->get_mg_noeudid(noeud3->get_nouveau_numero());
4702 MG_NOEUD* node4 = mai2->get_mg_noeudid(noeud4->get_nouveau_numero());
4703 MG_TRIANGLE* tri1=mgtet->get_triangle1();
4704 MG_TRIANGLE* tri2=mgtet->get_triangle2();
4705 MG_TRIANGLE* tri3=mgtet->get_triangle3();
4706 MG_TRIANGLE* tri4=mgtet->get_triangle4();
4707 if (tri1->get_nouveau_numero()==1)
4708 {
4709 int origine=MAGIC::ORIGINE::TRIANGULATION;
4710 if (tri1->get_origine()==MAGIC::ORIGINE::IMPOSE) origine=MAGIC::ORIGINE::IMPOSE;
4711 MG_FACE* topo=NULL;
4712 if (tri1->get_lien_topologie()->get_dimension()==2) topo=face;
4713 MG_TRIANGLE_PEAU* tripeau = insere_triangle(topo,node1,node2,node3,mai2,origine);
4714 tripeau->change_nouveau_numero(0);
4715 tri1->change_nouveau_numero(0);
4716 }
4717 if (tri2->get_nouveau_numero()==1)
4718 {
4719 int origine=MAGIC::ORIGINE::TRIANGULATION;
4720 if (tri2->get_origine()==MAGIC::ORIGINE::IMPOSE) origine=MAGIC::ORIGINE::IMPOSE;
4721 MG_FACE* topo=NULL;
4722 if (tri2->get_lien_topologie()->get_dimension()==2) topo=face;
4723 MG_TRIANGLE_PEAU* tripeau = insere_triangle(topo,node1,node4,node2,mai2,origine);
4724 tripeau->change_nouveau_numero(0);
4725 tri2->change_nouveau_numero(0);
4726 }
4727 if (tri3->get_nouveau_numero()==1)
4728 {
4729 int origine=MAGIC::ORIGINE::TRIANGULATION;
4730 MG_FACE* topo=NULL;
4731 if (tri3->get_lien_topologie()->get_dimension()==2) topo=face;
4732 if (tri3->get_origine()==MAGIC::ORIGINE::IMPOSE) origine=MAGIC::ORIGINE::IMPOSE;
4733 MG_TRIANGLE_PEAU* tripeau = insere_triangle(topo,node2,node4,node3,mai2,origine);
4734 tripeau->change_nouveau_numero(0);
4735 tri3->change_nouveau_numero(0);
4736 }
4737 if (tri4->get_nouveau_numero()==1)
4738 {
4739 int origine=MAGIC::ORIGINE::TRIANGULATION;
4740 MG_FACE* topo=NULL;
4741 if (tri4->get_lien_topologie()->get_dimension()==2) topo=face;
4742 if (tri4->get_origine()==MAGIC::ORIGINE::IMPOSE) origine=MAGIC::ORIGINE::IMPOSE;
4743 MG_TRIANGLE_PEAU* tripeau = insere_triangle(topo,node1,node3,node4,mai2,origine);
4744 tripeau->change_nouveau_numero(0);
4745 tri4->change_nouveau_numero(0);
4746 }
4747 }
4748 }
4749 // etape 6 recherche des vosins
4750 for (MG_TRIANGLE* mgtri=mai2->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mai2->get_suivant_triangle(it_tri))
4751 {
4752 MG_TRIANGLE_PEAU* tripeau=(MG_TRIANGLE_PEAU*)mgtri;
4753 MG_TRIANGLE_PEAU* voisin1=recherche_voisin(tripeau->get_noeud1(),tripeau->get_noeud2(),tripeau);
4754 MG_TRIANGLE_PEAU* voisin2=recherche_voisin(tripeau->get_noeud2(),tripeau->get_noeud3(),tripeau);
4755 MG_TRIANGLE_PEAU* voisin3=recherche_voisin(tripeau->get_noeud3(),tripeau->get_noeud1(),tripeau);
4756 tripeau->change_voisin1(voisin1);
4757 tripeau->change_voisin2(voisin2);
4758 tripeau->change_voisin3(voisin3);
4759 }
4760 // etape 7 - On recherche les peaux
4761 int fin;
4762 do
4763 {
4764 fin=1;
4765 for (MG_TRIANGLE* mgtri=mai2->get_premier_triangle(it_tri);mgtri!=NULL;mgtri=mai2->get_suivant_triangle(it_tri))
4766 {
4767 MG_TRIANGLE_PEAU *tripeau=(MG_TRIANGLE_PEAU*)mgtri;
4768 if (tripeau->get_nouveau_numero()==0)
4769 {
4770 fin=0;
4771 std::vector<MG_TRIANGLE_PEAU*> *peau=new std::vector<MG_TRIANGLE_PEAU*>;
4772 lst_peau.push_back(peau);
4773 tripeau->change_nouveau_numero(1);
4774 peau->push_back(tripeau);
4775 determine_peau(peau);
4776 }
4777 }
4778 }
4779 while (fin==0);
4780 nbpeau=lst_peau.size();
4781 //test de manifold
4782 LISTE_MG_SEGMENT::iterator itseg;
4783 for (MG_SEGMENT* seg=mai2->get_premier_segment(itseg);seg!=NULL;seg=mai2->get_suivant_segment(itseg))
4784 seg->change_nouveau_numero(0);
4785 TPL_MAP_ENTITE<MG_SEGMENT*> nonmanifoldarete;
4786 TPL_MAP_ENTITE<MG_NOEUD*> nonmanifoldnoeud;
4787 TPL_MAP_ENTITE<MG_NOEUD*> nonmanifoldnoeuddepuisarete;
4788 nbpeau=lst_peau.size();
4789 for (int i=0;i<nbpeau;i++)
4790 {
4791 int nbtri=lst_peau[i]->size();
4792 for (int j=0;j<nbtri;j++)
4793 {
4794 MG_TRIANGLE_PEAU* tripeau=(*lst_peau[i])[j];
4795 tripeau->get_segment1()->change_nouveau_numero(tripeau->get_segment1()->get_nouveau_numero()+1);
4796 tripeau->get_segment2()->change_nouveau_numero(tripeau->get_segment2()->get_nouveau_numero()+1);
4797 tripeau->get_segment3()->change_nouveau_numero(tripeau->get_segment3()->get_nouveau_numero()+1);
4798 if (tripeau->get_segment1()->get_nouveau_numero()>2)
4799 nonmanifoldarete.ajouter(tripeau->get_segment1());
4800 if (tripeau->get_segment2()->get_nouveau_numero()>2)
4801 nonmanifoldarete.ajouter(tripeau->get_segment2());
4802 if (tripeau->get_segment3()->get_nouveau_numero()>2)
4803 nonmanifoldarete.ajouter(tripeau->get_segment3());
4804 }
4805 }
4806
4807 int nbnonmanifoldarete=nonmanifoldarete.get_nb();
4808 for (int i=0;i<nbnonmanifoldarete;i++)
4809 {
4810 MG_SEGMENT* seg=nonmanifoldarete.get(i);
4811 MG_NOEUD* n1=seg->get_noeud1();
4812 MG_NOEUD* n2=seg->get_noeud2();
4813 nonmanifoldnoeuddepuisarete.ajouter(n1);
4814 nonmanifoldnoeuddepuisarete.ajouter(n2);
4815 }
4816 LISTE_MG_NOEUD::iterator itnoeud;
4817 for (MG_NOEUD* no=mai2->get_premier_noeud(itnoeud);no!=NULL;no=mai2->get_suivant_noeud(itnoeud))
4818 {
4819 if (nonmanifoldnoeuddepuisarete.existe(no)) continue;
4820 if (est_non_manifold(no)) nonmanifoldnoeud.ajouter(no);
4821 }
4822
4823 nbmaniare = nonmanifoldarete.get_nb();
4824 nbmanino = nonmanifoldnoeud.get_nb();
4825
4826 //etape 8 - Traitement des cas de non manifold
4827 //non manifold par arete
4828 for (int i=0;i<nbnonmanifoldarete;i++)
4829 {
4830 MG_SEGMENT* segment=nonmanifoldarete.get(i);
4831 MG_NOEUD* noeud1 = mg_mai->get_mg_noeudid(segment->get_noeud1()->get_nouveau_numero());
4832 MG_NOEUD* noeud2 = mg_mai->get_mg_noeudid(segment->get_noeud2()->get_nouveau_numero());
4833 int nb_tetra = noeud1->get_lien_tetra()->get_nb();
4834 for (int j=0;j<nb_tetra;j++)
4835 {
4836 MG_TETRA* mgtet =noeud1->get_lien_tetra()->get(j);
4837 int originetet=mgtet->get_origine();
4838 if (originetet == MAGIC::ORIGINE::MAILLEUR_AUTO)
4839 {
4840 //On reactive le tetra si l'autre noeud du segment lui appartient aussi
4841 MG_NOEUD* no1 = mgtet->get_noeud1();
4842 MG_NOEUD* no2 = mgtet->get_noeud2();
4843 MG_NOEUD* no3 = mgtet->get_noeud3();
4844 MG_NOEUD* no4 = mgtet->get_noeud4();
4845 if((no1 == noeud2) ||(no2 == noeud2) || (no3 == noeud2) || (no4 == noeud2))
4846 mgtet->change_origine(MAGIC::ORIGINE::OPTIMISE);
4847 }
4848 }
4849 }
4850
4851 //non manifold par noeud
4852 int nbnonmanifoldnoeud=nonmanifoldnoeud.get_nb();
4853 for (int i=0;i<nbnonmanifoldnoeud;i++)
4854 {
4855 MG_NOEUD* noeud=mg_mai->get_mg_noeudid(nonmanifoldnoeud.get(i)->get_nouveau_numero());
4856 int nb_tetra = noeud->get_lien_tetra()->get_nb();
4857 for (int j = 0;j<nb_tetra;j++)
4858 {
4859 MG_TETRA* mgtet =noeud->get_lien_tetra()->get(j);
4860 int originetet=mgtet->get_origine();
4861 if (originetet == MAGIC::ORIGINE::MAILLEUR_AUTO)
4862 {
4863 mgtet->change_origine(MAGIC::ORIGINE::OPTIMISE);
4864 }
4865 }
4866 }
4867 *mai2_id = mai2->get_id();
4868 if ((nbnonmanifoldarete != 0) || (nbnonmanifoldnoeud != 0))
4869 {
4870 for (int i=0;i<lst_peau.size();i++)
4871 {
4872 delete lst_peau[i];
4873 }
4874 lst_peau.clear();
4875 gest2.supprimer_mg_maillageid(*mai2_id);
4876 return 0;
4877 }
4878
4879 return 1;
4880 }
4881
4882 //---------------------------- Determine peau -------------------------------------------------------------------------
4883 void MGOPT_POSTTRAITEMENT::determine_peau(std::vector<MG_TRIANGLE_PEAU*> * peau)
4884 {
4885 int num=0;
4886 while (num!=peau->size())
4887 {
4888 MG_TRIANGLE_PEAU* p=(*peau)[num];
4889 if (p->get_voisin1()->get_nouveau_numero()==0)
4890 {
4891 peau->push_back(p->get_voisin1());
4892 p->get_voisin1()->change_nouveau_numero(1);
4893 }
4894 if (p->get_voisin2()->get_nouveau_numero()==0)
4895 {
4896 peau->push_back(p->get_voisin2());
4897 p->get_voisin2()->change_nouveau_numero(1);
4898 }
4899 if (p->get_voisin3()->get_nouveau_numero()==0)
4900 {
4901 peau->push_back(p->get_voisin3());
4902 p->get_voisin3()->change_nouveau_numero(1);
4903 }
4904 num++;
4905 }
4906 }
4907
4908 //---------------------------- Insere triangle -------------------------------------------------------------------------
4909 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)
4910 {
4911 MG_TRIANGLE_PEAU* voisin1=NULL,*voisin2=NULL,*voisin3=NULL;
4912 MG_SEGMENT* mgsegment1=mg_maillage->get_mg_segment(mgnoeud1->get_id(),mgnoeud2->get_id());
4913 MG_SEGMENT* mgsegment2=mg_maillage->get_mg_segment(mgnoeud2->get_id(),mgnoeud3->get_id());
4914 MG_SEGMENT* mgsegment3=mg_maillage->get_mg_segment(mgnoeud3->get_id(),mgnoeud1->get_id());
4915 if (mgsegment1==NULL)
4916 mgsegment1=mg_maillage->ajouter_mg_segment(topo,mgnoeud1,mgnoeud2,origine);
4917 if (mgsegment2==NULL)
4918 mgsegment2=mg_maillage->ajouter_mg_segment(topo,mgnoeud2,mgnoeud3,origine);
4919 if (mgsegment3==NULL)
4920 mgsegment3=mg_maillage->ajouter_mg_segment(topo,mgnoeud3,mgnoeud1,origine);
4921 MG_TRIANGLE_PEAU* mtriangle=new MG_TRIANGLE_PEAU(topo,mgnoeud1,mgnoeud2,mgnoeud3,mgsegment1,mgsegment2,mgsegment3,origine);
4922 mg_maillage->ajouter_mg_triangle(mtriangle);
4923 return mtriangle;
4924 }
4925
4926 //---------------------------- Recherche voisin -------------------------------------------------------------------------
4927 MG_TRIANGLE_PEAU* MGOPT_POSTTRAITEMENT::recherche_voisin(MG_NOEUD* mg_noeud1,MG_NOEUD* mg_noeud2,MG_TRIANGLE_PEAU* triref)
4928 {
4929 MG_TRIANGLE_PEAU* trisol=NULL;
4930 double angleref=4.*M_PI;
4931 int nb1=mg_noeud1->get_lien_triangle()->get_nb();
4932 int nb2=mg_noeud2->get_lien_triangle()->get_nb();
4933 for (int i=0;i<nb1;i++)
4934 for (int j=0;j<nb2;j++)
4935 if (mg_noeud1->get_lien_triangle()->get(i)==mg_noeud2->get_lien_triangle()->get(j))
4936 if ((MG_TRIANGLE_PEAU*)mg_noeud1->get_lien_triangle()->get(i)!=triref)
4937 {
4938 double angle=calcul_angle(triref,(MG_TRIANGLE_PEAU*)mg_noeud1->get_lien_triangle()->get(i));
4939 if (angle<angleref)
4940 {
4941 angleref=angle;
4942 trisol=(MG_TRIANGLE_PEAU*)mg_noeud1->get_lien_triangle()->get(i);
4943 }
4944 }
4945 return trisol;
4946 }
4947
4948 int MGOPT_POSTTRAITEMENT::est_non_manifold(MG_NOEUD* no)
4949 {
4950 static int compteur=0;
4951 compteur++;
4952 int nb_tri=no->get_lien_triangle()->get_nb();
4953 TPL_MAP_ENTITE<MG_TRIANGLE*> lst;
4954 for (int i=0;i<nb_tri;i++)
4955 lst.ajouter(no->get_lien_triangle()->get(i));
4956 MG_TRIANGLE_PEAU* premier_triangle=(MG_TRIANGLE_PEAU*)lst.get(0);
4957 lst.supprimer(premier_triangle);
4958 MG_TRIANGLE_PEAU* tricour=(MG_TRIANGLE_PEAU*)premier_triangle;
4959 int i=0;
4960 do
4961 {
4962 if (lst.existe(tricour->get_voisin1()) || ((tricour->get_voisin1()==premier_triangle)&& (i>1)))
4963 {
4964 tricour=tricour->get_voisin1();
4965 lst.supprimer(tricour);
4966 }
4967 else if (lst.existe(tricour->get_voisin2()) || ((tricour->get_voisin2()==premier_triangle)&& (i>1)))
4968 {
4969 tricour=tricour->get_voisin2();
4970 lst.supprimer(tricour);
4971 }
4972 else if (lst.existe(tricour->get_voisin3()) || ((tricour->get_voisin3()==premier_triangle)&& (i>1)))
4973 {
4974 tricour=tricour->get_voisin3();
4975 lst.supprimer(tricour);
4976 }
4977 i++;
4978 }
4979 while (tricour!=premier_triangle);
4980 if (lst.get_nb()>0)
4981 return 1;
4982 return 0;
4983 }
4984
4985 //---------------------------- Calcule angle -------------------------------------------------------------------------
4986 double MGOPT_POSTTRAITEMENT::calcul_angle(MG_TRIANGLE_PEAU* ft1,MG_TRIANGLE_PEAU* ft2)
4987 {
4988 MG_NOEUD* noeud1=ft1->get_noeud1();
4989 MG_NOEUD* noeud2=ft1->get_noeud2();
4990 MG_NOEUD* noeud3=ft1->get_noeud3();
4991 MG_NOEUD* noeud4=ft2->get_noeud1();
4992 MG_NOEUD* noeud5=ft2->get_noeud2();
4993 MG_NOEUD* noeud6=ft2->get_noeud3();
4994 double angle=get_angle_par_noeud<MG_NOEUD*>(noeud1,noeud2,noeud3,noeud4,noeud5,noeud6);
4995 return angle;
4996 }
4997
4998 //---------------------------- Ponderation gaussian -------------------------------------------------------------------------
4999 double MGOPT_POSTTRAITEMENT::ponderation_gaussian(double s,double sigma)
5000 {
5001 double w_s;
5002 w_s = exp(-(s*s)/(2.*sigma*sigma));
5003 return w_s;
5004 }
5005
5006 //---------------------------- Ponderation Laplacian -------------------------------------------------------------------------
5007 double MGOPT_POSTTRAITEMENT::ponderation_laplacian(double s,double sigma)
5008 {
5009 double w_s;
5010 w_s = exp(-(sqrt(2.)*fabs(s))/sigma);
5011 return w_s;
5012 }
5013
5014 //---------------------------- Ponderation elfallahford -------------------------------------------------------------------------
5015 double MGOPT_POSTTRAITEMENT::ponderation_elfallahford(double s,double sigma)
5016 {
5017 double w_s;
5018 w_s = 1./sqrt(1+pow((s/sigma),2));
5019 return w_s;
5020 }