ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/aster/src/mgopt_posttraitement.cpp
Revision: 804
Committed: Wed Jun 8 14:32:58 2016 UTC (8 years, 11 months ago) by mckenzie
File size: 207282 byte(s)
Log Message:
Commit des methodes de lissage lissage_McKenzie2016 et lissage_Taubin1995 ainsi que la mis a jour de postparam.txt et mgposttraitement.h

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