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 (8 years, 11 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

# User Rev Content
1 francois 222 #include "gestionversion.h"
2 francois 460 #include "mgopt_posttraitement.h"
3 francois 222 #include "fem_solution.h"
4     #include "fem_maillage.h"
5     #include "mg_maillage.h"
6     #include "mg_gestionnaire.h"
7     #include "mg_triangle_peau.h"
8 francois 335 #include "mg_geometrie_outils.h"
9 francois 412 #include "fem_maillage_outils.h"
10 francois 388 #include "tpl_fonctions_generiques.h"
11 cuillier 438 #include "ot_algorithme_geometrique.h"
12 francois 793 #include "mg_face_element.h"
13 francois 343 #include "mg_export.h"
14 francois 222 #include <stdio.h>
15 picher 230 #include <stdlib.h>
16     #include <time.h>
17 francois 222 #include <string.h>
18 francois 224 #include <math.h>
19 nana 629 #include <complex>
20 mckenzie 798 //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 francois 222 //---------------------------------------------------------------------------
26    
27    
28 francois 224
29 francois 460 MGOPT_POSTTRAITEMENT::MGOPT_POSTTRAITEMENT():affichageactif(0)
30 francois 222 {
31 francois 224 for (int i=0;i<9;i++) etat[i]=0;
32 francois 457 params.ajouter("decoupage",0.,OT_PARAMETRES::DOUBLE,"0. découpage en conservant les mailles entieres 1. découpage par isodensite");
33 nana 629 params.ajouter("seuil",0.5,OT_PARAMETRES::DOUBLE,"Valeur du seuil de densité pour les 2 découpages");
34 francois 457 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 nana 629 params.ajouter("chen2005_debut",0.,OT_PARAMETRES::DOUBLE,"Numero d'itération du debut d'application du lissage de chen2005 0. méthode non utilisee");
40     params.ajouter("chen2005_itermax",10.,OT_PARAMETRES::DOUBLE,"Nombre d'itérations maximales du lissage de chen2005");
41 francois 457 params.ajouter("chen2005_epsilon",0.01,OT_PARAMETRES::DOUBLE,"Critere de convergence du lissage de chen2005");
42 francois 458 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 francois 457 params.ajouter("chen2008_debut",0.,OT_PARAMETRES::DOUBLE,"Numero d'itération du debut d'application deu lissage de chen2008 0. méthode non utilisee");
45 nana 629 params.ajouter("chen2008_itermax",10.,OT_PARAMETRES::DOUBLE,"Nombre d'itérations maximales du lissage de chen2008");
46 francois 457 params.ajouter("chen2008_epsilon",0.01,OT_PARAMETRES::DOUBLE,"Critere de convergence du lissage de chen2008");
47 francois 458 params.ajouter("chen2008_sigma",0.1,OT_PARAMETRES::DOUBLE,"Écart type du filtre de lissage de chen2008");
48 francois 457 params.ajouter("chen2008_gamma",1.,OT_PARAMETRES::DOUBLE,"Vitesse d'avancement de déplacement du lissage de chen2008");
49 francois 458 params.ajouter("chen2008_filtre",1.,OT_PARAMETRES::DOUBLE,"Choix du filtre de lissage de chen2008 1. Gaussian 2.Laplacien 3.elfallahford");
50 francois 457 params.ajouter("jiao2012_debut",0.,OT_PARAMETRES::DOUBLE,"Numero d'itération du debut d'application deu lissage de jiao2012 0. méthode non utilisee");
51 nana 629 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 mckenzie 798 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 francois 222 }
64    
65    
66 francois 460 MGOPT_POSTTRAITEMENT::~MGOPT_POSTTRAITEMENT()
67 francois 222 {
68 francois 224 for (int i=0;i<lst_peau.size();i++)
69     delete lst_peau[i];
70 francois 222 }
71 picher 233
72 francois 460 void MGOPT_POSTTRAITEMENT::active_affichage(void (*fonc)(char*))
73 francois 232 {
74     affiche=fonc;
75     affichageactif=1;
76     }
77 francois 222
78 picher 233
79 francois 457
80 francois 461 void MGOPT_POSTTRAITEMENT::posttraite(char *fichier)
81 francois 457 {
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 francois 460 void MGOPT_POSTTRAITEMENT::conserve(int origine)
96 francois 224 {
97     etat[(origine-1000)/10]=1;
98     }
99    
100 picher 233
101 francois 460 void MGOPT_POSTTRAITEMENT::copieorigine(FEM_MAILLAGE* mai)
102 picher 231 {
103 francois 309 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 picher 233 {
106     MG_TETRA* mgtet=(MG_TETRA*)tet->get_mg_element_maillage();
107     mgtet->change_origine(mgtet->get_origine());
108     }
109     }
110 francois 457
111    
112 francois 460 void MGOPT_POSTTRAITEMENT::gain_poids(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2)
113 picher 233 {
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 francois 791 if (originetet != MAGIC::ORIGINE::MAILLEUR_AUTO)
140 picher 233 {
141     volume_final = volume_final + volume_tet;
142     }
143     }
144     }
145 francois 457
146 francois 460 void MGOPT_POSTTRAITEMENT::reactivation(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2)
147 picher 233 {
148 francois 457 cout << " Reactivation d'elements manquants sur aretes vives et faces planes" << endl;
149 picher 233 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 francois 791 if (originetet == MAGIC::ORIGINE::MAILLEUR_AUTO)
155 picher 233 {
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 francois 791 if ((tet1 != mgtet) && (ori1 == MAGIC::ORIGINE::MAILLEUR_AUTO)) compteur++;
166 picher 233 }
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 francois 791 if ((tet2 != mgtet) && (ori2 == MAGIC::ORIGINE::MAILLEUR_AUTO)) compteur++;
173 picher 233 }
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 francois 791 if ((tet3 != mgtet) && (ori3 == MAGIC::ORIGINE::MAILLEUR_AUTO)) compteur++;
180 picher 233 }
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 francois 791 if ((tet4 != mgtet) && (ori4 == MAGIC::ORIGINE::MAILLEUR_AUTO)) compteur++;
187 picher 233 }
188 francois 791 if (compteur == 0) mgtet->change_origine(MAGIC::ORIGINE::OPTIMISE);
189 picher 233 }
190     }
191     }
192    
193    
194 francois 343
195    
196 francois 460 MG_MAILLAGE* MGOPT_POSTTRAITEMENT::extract_skin_par_decoupage(FEM_SOLUTION* sol,double limit,MG_GESTIONNAIRE& gest2,std::string nom)
197 francois 343 {
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 francois 791 if (tet->get_mg_element_maillage()->get_origine()!=MAGIC::ORIGINE::IMPOSE)
213 francois 343 {
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 nana 629 if (passe==1) no->change_solution(nume/deno); else no->change_solution(1.);
223 francois 343 }
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 francois 383 FEM_SOLUTION* femdens=new FEM_SOLUTION(mai,1,(char*)chemin.c_str(),mai->get_nb_fem_element3(),"Extrapolation aux noeuds",MAGIC::ENTITE_SOLUTION::ENTITE_ELEMENT3_NOEUD,MAGIC::TYPE_SOLUTION::SCALAIRE);
230 francois 343 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 francois 791 if (tet2->get_origine()==MAGIC::ORIGINE::IMPOSE)
238 francois 343 {
239 francois 375 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 francois 343 }
244     else
245     {
246 francois 375 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 francois 343 }
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 francois 793 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 francois 343 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 francois 791 if (tet2->get_origine()==MAGIC::ORIGINE::IMPOSE)
276 francois 343 {
277 francois 791 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 francois 343 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 francois 791 if (tri->get_origine()==MAGIC::ORIGINE::IMPOSE)
312 francois 343 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 francois 791 if (tet->get_mg_element_maillage()->get_origine()!=MAGIC::ORIGINE::IMPOSE)
319 francois 343 {
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 francois 792 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 francois 343 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 francois 791 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[1],tab[2],mgmai,MAGIC::ORIGINE::TRIANGULATION);
343 francois 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 francois 791 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 francois 343 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 francois 791 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 francois 343 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 francois 791 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 francois 343 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 francois 791 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 francois 343 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 francois 791 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 francois 343 oriente_tri(tri,noext->get_coord());
378     oriente_tri(tri2,noext->get_coord());}
379     else
380     {
381 francois 791 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 francois 343 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 francois 792 if (num1*num2<0) interpole_segment(mai,mai->get_fem_noeudid(no1->get_nouveau_numero()),mai->get_fem_noeudid(no2->get_nouveau_numero()),&tab,limit,mgmai);
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 francois 343 MG_NOEUD* noint=mgfem->get_mg_noeudid(tri->get_nouveau_numero());
423     int nb=tab.size();
424     if (nb==3)
425     {
426 francois 791 MG_TRIANGLE_PEAU* tri=insere_triangle(NULL,tab[0],tab[1],tab[2],mgmai,MAGIC::ORIGINE::IMPOSE);
427 francois 343 oriente_tri(tri,noint->get_coord());
428     tri->inverse_sens();
429     }
430     if (nb==4)
431     {
432 francois 791 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 francois 343 oriente_tri(tri,noint->get_coord());
435     tri->inverse_sens();
436     oriente_tri(tri2,noint->get_coord());
437     tri2->inverse_sens();
438     }
439     }
440 francois 793 affiche((char*)" Decoupage des triangles sur la frontiere du volume");
441 francois 343 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 francois 791 if (tri->get_mg_element_maillage()->get_origine()==MAGIC::ORIGINE::IMPOSE)
457 francois 343 {
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 francois 792 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 francois 343 int nb=tab.size();
465     if (nb==0)
466     {
467 francois 793 MG_TRIANGLE_PEAU* tri=insere_triangle(face,mgno1,mgno2,mgno3,mgmai,MAGIC::ORIGINE::IMPOSE);
468 francois 343 oriente_tri(tri,xyzext);
469     }
470     if (nb==1)
471     {
472     if (num1==1)
473     {
474 francois 793 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 francois 343 oriente_tri(tri,xyzext);
477     oriente_tri(tri2,xyzext);
478     }
479     if (num2==1)
480     {
481 francois 793 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 francois 343 oriente_tri(tri,xyzext);
484     oriente_tri(tri2,xyzext);
485     }
486     if (num3==1)
487     {
488 francois 793 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 francois 343 oriente_tri(tri,xyzext);
491     oriente_tri(tri2,xyzext);
492     }
493     }
494     if (nb==2)
495     {
496     if (num1==0)
497     {
498 francois 793 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 francois 343 oriente_tri(tri,xyzext);
502     oriente_tri(tri2,xyzext);
503     oriente_tri(tri3,xyzext);
504     }
505     if (num2==0)
506     {
507 francois 793 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 francois 343 oriente_tri(tri,xyzext);
511     oriente_tri(tri2,xyzext);
512     oriente_tri(tri3,xyzext);
513     }
514     if (num2==0)
515     {
516 francois 793 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 francois 343 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 francois 793 MG_TRIANGLE_PEAU* tri=insere_triangle(face,mgno1,mgno2,mgno3,mgmai,MAGIC::ORIGINE::TRIANGULATION);
531 francois 343 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 francois 792 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 francois 343 int nb=tab.size();
561     if (nb==3)
562     {
563 francois 793 MG_TRIANGLE_PEAU* tri=insere_triangle(face,tab[0],tab[1],tab[2],mgmai,MAGIC::ORIGINE::TRIANGULATION);
564 francois 343 oriente_tri(tri,xyzext);
565     }
566     if (nb==4)
567     {
568 francois 793 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 francois 343 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 francois 457 return mgmai;
607     }
608 nana 629
609    
610 francois 460 void MGOPT_POSTTRAITEMENT::suppression_peaux_isoles(MG_MAILLAGE* mgmai)
611 francois 457 {
612     affiche((char*)"Suppression des peaux isolées");
613 francois 343
614     char message[500];
615     for (int cas=0;cas<2;cas++)
616     {
617 francois 457 if (cas==0) affiche((char*)" Analyse initiale des peaux");
618     if (cas==1) affiche((char*)" Analyse finale des peaux");
619     int nbisole=0;
620 francois 343 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 francois 791 if ((*lst_peau[i])[j]->get_origine()==MAGIC::ORIGINE::IMPOSE) {isole=0;break;}
625 francois 343 if (isole==1)
626     {
627 francois 457 nbisole++;
628 francois 343 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 francois 457 sprintf(message," %d peaux, %d non isoles, %d isoles",(int)lst_peau.size(),(int)lst_peau.size()-nbisole,nbisole);
636     affiche(message);
637 francois 343 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 francois 457 LISTE_MG_TRIANGLE::iterator itmg;
642 francois 343 for (MG_TRIANGLE* tri=mgmai->get_premier_triangle(itmg);tri!=NULL;tri=mgmai->get_suivant_triangle(itmg))
643     {
644 francois 791 if (tri->get_origine()==MAGIC::ORIGINE::IMPOSE)
645 francois 343 {
646 francois 791 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 francois 343 }
650     }
651 cuillier 438
652 francois 343 }
653    
654 nana 629
655 francois 460 void MGOPT_POSTTRAITEMENT::oriente_tri(MG_TRIANGLE_PEAU* tri,double *xyz)
656 francois 343 {
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 francois 460 MG_NOEUD* MGOPT_POSTTRAITEMENT::get_noeud_peau(FEM_NOEUD* no,MG_MAILLAGE* mai)
673 francois 343 {
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 francois 792 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 francois 343 mai->ajouter_mg_noeud(mgno);
686     correspond[key]=mgno;
687     }
688     return mgno;
689     }
690    
691    
692 francois 460 int MGOPT_POSTTRAITEMENT::test_du_point_milieu(MG_NOEUD* no1,MG_NOEUD* no2,FEM_ELEMENT3* tet)
693 francois 343 {
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 francois 412 FEM_MAILLAGE_OUTILS ot;
701 francois 388 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 francois 343 return 0;
704     }
705    
706    
707    
708 francois 792 int MGOPT_POSTTRAITEMENT::interpole_segment(FEM_MAILLAGE* fem,FEM_NOEUD* no1,FEM_NOEUD* no2,std::vector<MG_NOEUD*> *tab,double limit,MG_MAILLAGE* mai,int creation)
709 francois 343 {
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 francois 792 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 francois 345 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 francois 792 no=new MG_NOEUD(NULL,xyz1[0],xyz1[1],xyz1[2],origine);
736 francois 345 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 francois 792 no=new MG_NOEUD(NULL,xyz2[0],xyz2[1],xyz2[2],origine);
758 francois 345 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 francois 343 {
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 francois 792 no=new MG_NOEUD(NULL,xyz[0],xyz[1],xyz[2],origine);
787 francois 343 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 francois 460 void MGOPT_POSTTRAITEMENT::lire_params(char *fichier)
800 francois 457 {
801     params.lire(fichier);
802     }
803 francois 343
804 francois 461 void MGOPT_POSTTRAITEMENT::posttraite(FEM_SOLUTION* sol, MG_GESTIONNAIRE& gest2,char *nomparam)
805 picher 233 {
806 francois 457 if (nomparam!=NULL) lire_params(nomparam);
807 francois 272 affiche((char*)"Extraction du maillage de surface");
808 francois 457 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 nana 629 int nana2015_debut=params.get_valeur("nana2015_debut");
830 mckenzie 798 int taubin1995_debut=params.get_valeur("taubin1995_debut");
831 francois 457 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 nana 629 int nana2015fait=0;
838     if (nana2015_debut==0) nana2015fait=1;
839 mckenzie 798 int taubin1995fait=0;
840     if (taubin1995_debut==0) taubin1995fait=1;
841    
842 francois 457 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 nana 629 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 mckenzie 798 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 francois 457 else iteration++;
924     if (chen2005fait==1)
925     if (chen2008fait==1)
926     if (jiao2012fait==1)
927 nana 629 if (nana2015fait==1)
928 mckenzie 798 if (taubin1995fait==1)
929 nana 629 fin=1;
930 francois 457 }
931     while (fin==0);
932 mckenzie 798
933    
934 francois 457 }
935    
936    
937 francois 460 MG_MAILLAGE* MGOPT_POSTTRAITEMENT::extract_skin_maille_entiere(FEM_MAILLAGE* mai,MG_GESTIONNAIRE &gest2)
938 francois 457 {
939     //Menu de la methode de lissage
940     affiche((char*)"Extraction du maillage de surface");
941 picher 231 int coderesu = 0;
942 picher 233 int mai2_id;
943 francois 457 int imp=params.get_valeur("consimpose");
944     int opti=params.get_valeur("consoptimise");
945     int m_auto=params.get_valeur("consnooptimise");
946 francois 791 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 francois 457 copieorigine(mai);
950 picher 233 MG_MAILLAGE* mg_mai = (MG_MAILLAGE*)mai->get_mg_maillage();
951 francois 457 //gain_poids(mg_mai,gest2);
952     int reactiv=params.get_valeur("reactivation");
953 picher 233 if (reactiv == 1)
954     {
955     reactivation(mg_mai,gest2);
956     }
957 francois 457 affiche((char*)" Analyse des cas non manifold");
958 picher 231 do
959     {
960 francois 457 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 picher 231 }
967     while (coderesu == 0);
968 picher 233
969     MG_MAILLAGE* mg_mai2=gest2.get_mg_maillageid(mai2_id);
970 francois 457
971     return mg_mai2;
972    
973 picher 231 }
974    
975 nana 629
976 francois 460 void MGOPT_POSTTRAITEMENT::adapte_seuil(class FEM_MAILLAGE* fem,FEM_SOLUTION* solution)
977 picher 230 {
978 francois 457 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 picher 230 {
983 francois 791 if (((MG_TETRA*)tet->get_mg_element_maillage())->get_origine()!=MAGIC::ORIGINE::IMPOSE)
984 francois 457 if (tet->get_solution()>seuil)
985 francois 791 ((MG_TETRA*)tet->get_mg_element_maillage())->change_origine(MAGIC::ORIGINE::OPTIMISE);
986 francois 457 else
987 francois 791 ((MG_TETRA*)tet->get_mg_element_maillage())->change_origine(MAGIC::ORIGINE::MAILLEUR_AUTO);
988 francois 457
989 picher 230 }
990     }
991 francois 224
992 francois 457
993     //---------------------------- Lissage Chen 2005 Gilles Philippe -------------------------------------------------------------------------
994 francois 460 int MGOPT_POSTTRAITEMENT::lissage_chen2005(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, double epsilon, double sigma, int iter_max)
995 picher 230 {
996 francois 457 //Methode de lissage inspiree de Chen(2005) par Gilles Philipe Picher Martel
997 picher 230 double un_sur_pi = 1./M_PI;
998     int compteur = 0;
999     int fin = 0;
1000 francois 224
1001 francois 457
1002 picher 230 do
1003     {
1004     TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales;
1005 picher 233 TPL_LISTE_ENTITE<OT_VECTEUR_3D> liste_normales2;
1006 picher 230 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 picher 233 normal_f_i.norme();
1014     liste_normales2.ajouter(normal_f_i);
1015 picher 230 //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 picher 231 double *phi_ij = new double[nb_voisins];
1045 picher 230 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 francois 457 //2.1-On calcul l'angle entre normal_f_i et normal_f_j pour j allant de 1 a Nb_voisins
1055 picher 230 double prod_scalaire = normal_f_i*normal_f_j;
1056 picher 233 if (prod_scalaire > 1.)
1057     {
1058     prod_scalaire = 1.;
1059     }
1060     if (prod_scalaire < -1.)
1061     {
1062     prod_scalaire = -1.;
1063     }
1064 picher 230 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 picher 231 delete[] phi_ij;
1084 picher 230 //4-On calcule une nouvelle normale pour chaque triangle
1085 francois 458 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 picher 230 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 francois 457 //On calcule le centroide cj du triangle mgtri_j
1109 picher 230 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 francois 457 // w_ij_prime correspond a la somme des aires des triangles voisins du noeuds
1119 picher 233 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 picher 230 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 francois 457 //5-On met a jour la position des noeuds
1127 picher 230 v_i = v_i + v_temp/w_ij_prime;
1128 picher 233 int origine = noeud_i->get_origine();
1129 francois 791 if (origine != MAGIC::ORIGINE::IMPOSE)
1130 picher 233 {
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 picher 230 }
1136 francois 457 //Critere d'arret de l'algorithme
1137 picher 230 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 picher 233 OT_VECTEUR_3D normal_f_i = liste_normales2.get(mgtri_i->get_nouveau_numero());
1143 picher 230 OT_VECTEUR_3D normal_f_i_new = liste_normales.get(mgtri_i->get_nouveau_numero());
1144 picher 248 double critere = 1. - normal_f_i*normal_f_i_new;
1145 picher 230 if (critere <= epsilon) l++;
1146     }
1147 picher 248 double tolerance = 0.01*nb_tri;
1148     if (nb_tri - l <= 0) fin = 1;
1149 picher 230 compteur++;
1150     }
1151     while ((fin == 0) && (compteur < iter_max));
1152    
1153 francois 457 return compteur;
1154     }
1155 picher 230
1156 francois 457 //---------------------------- Lissage Jiao 2012 -------------------------------------------------------------------------
1157 francois 460 int MGOPT_POSTTRAITEMENT::lissage_jiao2012(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, int iter_max)
1158 picher 248 {
1159 francois 457 // Lissage global avec methode de lissage inspiree de JIAO IMR2012 par Jean Christophe sept 2013
1160 picher 248 int compteur = 0;
1161    
1162 cuillier 438 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 francois 791 if (origine != MAGIC::ORIGINE::IMPOSE)
1172 cuillier 438 {
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 francois 457 //On calcule le centroide cj du triangle mgtri_j
1182 cuillier 438 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 francois 791 if (origine != MAGIC::ORIGINE::IMPOSE)
1208 cuillier 438 {
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 francois 457 return compteur;
1221 cuillier 438 }
1222    
1223 francois 457 //---------------------------- Lissage Chen 2008 -------------------------------------------------------------------------
1224 francois 460 int MGOPT_POSTTRAITEMENT::lissage_chen2008(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2, double sigma, double gamma, double epsilon, int iter_max)
1225 cuillier 438 {
1226 francois 457 //Lissage global inspire de Chen(2008) corrige par Jean Christophe sept 2013
1227 cuillier 438 double un_sur_pi = 1./M_PI;
1228     int compteur = 0;
1229     int fin = 0;
1230 francois 457 compteur = 0;
1231 cuillier 438
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 francois 457 //2.1-On calcule l'angle entre normal_f_i et normal_f_j pour j allant de 1 a Nb_voisins
1289 cuillier 438 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 francois 457 //3.1-On calcule l'angle moyen phi_im
1306 cuillier 438 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 francois 458 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 cuillier 438 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 francois 791 if (origine != MAGIC::ORIGINE::IMPOSE)
1337 cuillier 438 {
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 francois 457 //On calcule le centroide cj du triangle mgtri_j
1346 cuillier 438 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 francois 457 //5-On met a jour la position des noeuds
1358 cuillier 438 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 francois 791 if (origine != MAGIC::ORIGINE::IMPOSE)
1371 cuillier 438 {
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 picher 248 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 francois 457 return compteur;
1397    
1398 picher 248 }
1399    
1400 cuillier 438
1401 nana 629 //---------------------------- 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 francois 791 if(tri->get_origine()!=MAGIC::ORIGINE::MAILLEUR_AUTO)
1416 nana 629 {
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 francois 791 if ((noeud_i->get_origine() != MAGIC::ORIGINE::IMPOSE))
1453 nana 629 {
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 francois 791 if(tri->get_origine()!=MAGIC::ORIGINE::MAILLEUR_AUTO)
1674 nana 629 {
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 francois 791 if ((noeud_i->get_origine() != MAGIC::ORIGINE::IMPOSE))
1706 nana 629 {
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 francois 791 if ((noeud_i->get_origine() != MAGIC::ORIGINE::IMPOSE) && (noeud_i != noeud))
1714 nana 629 {
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 francois 791 if ((noeud_i->get_origine() != MAGIC::ORIGINE::IMPOSE))
1730 nana 629 {
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 francois 791 if (mgtri_peau->get_origine() != MAGIC::ORIGINE::IMPOSE)
1910 nana 629 {
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 francois 791 if ((noeud_i->get_origine() != MAGIC::ORIGINE::IMPOSE))
1947 nana 629 {
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 francois 791 if(tri->get_origine()!=MAGIC::ORIGINE::MAILLEUR_AUTO)
1962 nana 629 {
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 mckenzie 798 //---------------------------- 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 nana 629
2004 mckenzie 798
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 francois 457 //---------------------------- Extract skin -------------------------------------------------------------------------
4564 francois 460 int MGOPT_POSTTRAITEMENT::extract_skin(MG_MAILLAGE* mg_mai,MG_GESTIONNAIRE& gest2,int &nbpeau,int &nbmaniare,int &nbmanino, int *mai2_id)
4565 cuillier 438 {
4566    
4567 francois 457 //etape 0 - On commence par mettre a zero tous les nouveau_numero des triangles et des noeuds du maillage
4568 francois 222 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 francois 791 mgtri->change_origine(MAGIC::ORIGINE::MAILLEUR_AUTO);
4573 francois 222 }
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 francois 457 //etape 1 - On boucle ensuite tous les tetraedres pour ajouter un compteur du nombre de fois qu'un triangle appartient a 1 tetra
4581 picher 233 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 francois 222 {
4584     int origine = mgtet->get_origine();
4585 francois 791 if (origine==MAGIC::ORIGINE::IMPOSE)
4586 francois 222 {
4587 francois 791 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 francois 224 }
4592 francois 791 if (origine==MAGIC::ORIGINE::OPTIMISE)
4593 francois 224 {
4594 francois 791 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 francois 224 }
4599    
4600 francois 791 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 francois 224
4607     {
4608 francois 222 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 francois 457 //etape 2 - On boucle l'ensemble des triangles identifies a l'etape 1 pour identifier les noeuds leur appartenant
4624 francois 222 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 francois 791 if (mgtri->get_origine()==MAGIC::ORIGINE::IMPOSE)
4636 picher 248 {
4637 francois 791 noeud1->change_origine(MAGIC::ORIGINE::IMPOSE);
4638     noeud2->change_origine(MAGIC::ORIGINE::IMPOSE);
4639     noeud3->change_origine(MAGIC::ORIGINE::IMPOSE);
4640 picher 248 }
4641 francois 222 }
4642     }
4643    
4644 francois 457 //etape 3 - On cree un nouveau maillage pour la peau
4645 francois 793 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 francois 222 gest2.ajouter_mg_maillage(mai2);
4653    
4654 francois 457 //etape 4 - On boucle l'ensemble des noeuds identifies a l'etape 2 pour les recreer dans le second maillage
4655 francois 222 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 francois 791 int origine=MAGIC::ORIGINE::TRIANGULATION;
4664 francois 792 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 francois 791 if (mgnoeud->get_origine()==MAGIC::ORIGINE::IMPOSE) origine=MAGIC::ORIGINE::IMPOSE;
4677 francois 224 MG_NOEUD* noeud1 = new MG_NOEUD(NULL,x,y,z,origine);
4678 francois 222 mai2->ajouter_mg_noeud(noeud1);
4679     mgnoeud->change_nouveau_numero(noeud1->get_id());
4680 francois 234 noeud1->change_nouveau_numero(mgnoeud->get_id());
4681 francois 222 }
4682     }
4683    
4684 francois 457 // etape 5 - On boucle l'ensemble des triangles identifies a l'etape 1 pour les recreer dans le maillage 2
4685 picher 233 for (MG_TETRA* mgtet=mg_mai->get_premier_tetra(it_tetra);mgtet!=NULL;mgtet=mg_mai->get_suivant_tetra(it_tetra))
4686 francois 222 {
4687 francois 224 int originetet=mgtet->get_origine();
4688 francois 791 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 francois 222 {
4695 francois 224 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 francois 222 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 francois 224 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 francois 791 int origine=MAGIC::ORIGINE::TRIANGULATION;
4710     if (tri1->get_origine()==MAGIC::ORIGINE::IMPOSE) origine=MAGIC::ORIGINE::IMPOSE;
4711 francois 793 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 francois 224 tripeau->change_nouveau_numero(0);
4715     tri1->change_nouveau_numero(0);
4716     }
4717     if (tri2->get_nouveau_numero()==1)
4718     {
4719 francois 791 int origine=MAGIC::ORIGINE::TRIANGULATION;
4720     if (tri2->get_origine()==MAGIC::ORIGINE::IMPOSE) origine=MAGIC::ORIGINE::IMPOSE;
4721 francois 793 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 francois 224 tripeau->change_nouveau_numero(0);
4725     tri2->change_nouveau_numero(0);
4726     }
4727     if (tri3->get_nouveau_numero()==1)
4728     {
4729 francois 791 int origine=MAGIC::ORIGINE::TRIANGULATION;
4730 francois 793 MG_FACE* topo=NULL;
4731     if (tri3->get_lien_topologie()->get_dimension()==2) topo=face;
4732 francois 791 if (tri3->get_origine()==MAGIC::ORIGINE::IMPOSE) origine=MAGIC::ORIGINE::IMPOSE;
4733 francois 793 MG_TRIANGLE_PEAU* tripeau = insere_triangle(topo,node2,node4,node3,mai2,origine);
4734 francois 224 tripeau->change_nouveau_numero(0);
4735     tri3->change_nouveau_numero(0);
4736     }
4737     if (tri4->get_nouveau_numero()==1)
4738     {
4739 francois 791 int origine=MAGIC::ORIGINE::TRIANGULATION;
4740 francois 793 MG_FACE* topo=NULL;
4741     if (tri4->get_lien_topologie()->get_dimension()==2) topo=face;
4742 francois 791 if (tri4->get_origine()==MAGIC::ORIGINE::IMPOSE) origine=MAGIC::ORIGINE::IMPOSE;
4743 francois 793 MG_TRIANGLE_PEAU* tripeau = insere_triangle(topo,node1,node3,node4,mai2,origine);
4744 francois 224 tripeau->change_nouveau_numero(0);
4745     tri4->change_nouveau_numero(0);
4746     }
4747 francois 222 }
4748 francois 224 }
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 francois 457 // etape 7 - On recherche les peaux
4761 francois 224 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 francois 457 nbpeau=lst_peau.size();
4781 francois 224 //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 francois 234 TPL_MAP_ENTITE<MG_NOEUD*> nonmanifoldnoeuddepuisarete;
4788 francois 457 nbpeau=lst_peau.size();
4789 francois 224 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 picher 233
4807 francois 224 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 francois 234 nonmanifoldnoeuddepuisarete.ajouter(n1);
4814     nonmanifoldnoeuddepuisarete.ajouter(n2);
4815 francois 224 }
4816 francois 234 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 francois 224
4823 francois 457 nbmaniare = nonmanifoldarete.get_nb();
4824     nbmanino = nonmanifoldnoeud.get_nb();
4825 picher 230
4826 francois 457 //etape 8 - Traitement des cas de non manifold
4827     //non manifold par arete
4828 picher 233 for (int i=0;i<nbnonmanifoldarete;i++)
4829     {
4830     MG_SEGMENT* segment=nonmanifoldarete.get(i);
4831 francois 234 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 picher 233 {
4836 francois 234 MG_TETRA* mgtet =noeud1->get_lien_tetra()->get(j);
4837     int originetet=mgtet->get_origine();
4838 francois 791 if (originetet == MAGIC::ORIGINE::MAILLEUR_AUTO)
4839 picher 233 {
4840 francois 457 //On reactive le tetra si l'autre noeud du segment lui appartient aussi
4841 francois 234 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 francois 791 mgtet->change_origine(MAGIC::ORIGINE::OPTIMISE);
4847 picher 233 }
4848     }
4849     }
4850    
4851     //non manifold par noeud
4852 picher 231 int nbnonmanifoldnoeud=nonmanifoldnoeud.get_nb();
4853     for (int i=0;i<nbnonmanifoldnoeud;i++)
4854     {
4855 francois 234 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 francois 345 {
4859 francois 234 MG_TETRA* mgtet =noeud->get_lien_tetra()->get(j);
4860     int originetet=mgtet->get_origine();
4861 francois 791 if (originetet == MAGIC::ORIGINE::MAILLEUR_AUTO)
4862 picher 231 {
4863 francois 791 mgtet->change_origine(MAGIC::ORIGINE::OPTIMISE);
4864 picher 231 }
4865     }
4866     }
4867 francois 234 *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 picher 230
4879 francois 234 return 1;
4880 francois 222 }
4881    
4882 francois 457 //---------------------------- Determine peau -------------------------------------------------------------------------
4883 francois 460 void MGOPT_POSTTRAITEMENT::determine_peau(std::vector<MG_TRIANGLE_PEAU*> * peau)
4884 francois 222 {
4885 francois 224 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 francois 457 //---------------------------- Insere triangle -------------------------------------------------------------------------
4909 francois 460 MG_TRIANGLE_PEAU* MGOPT_POSTTRAITEMENT::insere_triangle(MG_ELEMENT_TOPOLOGIQUE* topo,class MG_NOEUD *mgnoeud1,class MG_NOEUD *mgnoeud2,class MG_NOEUD *mgnoeud3,MG_MAILLAGE* mg_maillage,int origine)
4910 francois 224 {
4911 francois 222 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 francois 224 mgsegment1=mg_maillage->ajouter_mg_segment(topo,mgnoeud1,mgnoeud2,origine);
4917 francois 222 if (mgsegment2==NULL)
4918 francois 224 mgsegment2=mg_maillage->ajouter_mg_segment(topo,mgnoeud2,mgnoeud3,origine);
4919 francois 222 if (mgsegment3==NULL)
4920 francois 224 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 francois 222 mg_maillage->ajouter_mg_triangle(mtriangle);
4923     return mtriangle;
4924     }
4925    
4926 francois 457 //---------------------------- Recherche voisin -------------------------------------------------------------------------
4927 francois 460 MG_TRIANGLE_PEAU* MGOPT_POSTTRAITEMENT::recherche_voisin(MG_NOEUD* mg_noeud1,MG_NOEUD* mg_noeud2,MG_TRIANGLE_PEAU* triref)
4928 francois 222 {
4929 francois 224 MG_TRIANGLE_PEAU* trisol=NULL;
4930     double angleref=4.*M_PI;
4931 francois 222 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 francois 224 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 francois 222 }
4947 francois 223
4948 francois 460 int MGOPT_POSTTRAITEMENT::est_non_manifold(MG_NOEUD* no)
4949 francois 234 {
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 francois 224
4985 francois 457 //---------------------------- Calcule angle -------------------------------------------------------------------------
4986 francois 460 double MGOPT_POSTTRAITEMENT::calcul_angle(MG_TRIANGLE_PEAU* ft1,MG_TRIANGLE_PEAU* ft2)
4987 francois 223 {
4988 francois 388 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 francois 223 }
4997 picher 230
4998 francois 457 //---------------------------- Ponderation gaussian -------------------------------------------------------------------------
4999 francois 460 double MGOPT_POSTTRAITEMENT::ponderation_gaussian(double s,double sigma)
5000 picher 230 {
5001     double w_s;
5002     w_s = exp(-(s*s)/(2.*sigma*sigma));
5003     return w_s;
5004     }
5005    
5006 francois 457 //---------------------------- Ponderation Laplacian -------------------------------------------------------------------------
5007 francois 460 double MGOPT_POSTTRAITEMENT::ponderation_laplacian(double s,double sigma)
5008 picher 230 {
5009     double w_s;
5010     w_s = exp(-(sqrt(2.)*fabs(s))/sigma);
5011     return w_s;
5012     }
5013    
5014 francois 457 //---------------------------- Ponderation elfallahford -------------------------------------------------------------------------
5015 francois 460 double MGOPT_POSTTRAITEMENT::ponderation_elfallahford(double s,double sigma)
5016 picher 230 {
5017     double w_s;
5018     w_s = 1./sqrt(1+pow((s/sigma),2));
5019     return w_s;
5020     }