1 |
francois |
1158 |
//####//------------------------------------------------------------ |
2 |
|
|
//####//------------------------------------------------------------ |
3 |
|
|
//####// MAGiC |
4 |
|
|
//####// Jean Christophe Cuilliere et Vincent FRANCOIS |
5 |
|
|
//####// Departement de Genie Mecanique - UQTR |
6 |
|
|
//####//------------------------------------------------------------ |
7 |
|
|
//####// MAGIC est un projet de recherche de l equipe ERICCA |
8 |
|
|
//####// du departement de genie mecanique de l Universite du Quebec a Trois Rivieres |
9 |
|
|
//####// http://www.uqtr.ca/ericca |
10 |
|
|
//####// http://www.uqtr.ca/ |
11 |
|
|
//####//------------------------------------------------------------ |
12 |
|
|
//####//------------------------------------------------------------ |
13 |
|
|
//####// |
14 |
|
|
//####// mailleur2d_optimisation.cpp |
15 |
|
|
//####// |
16 |
|
|
//####//------------------------------------------------------------ |
17 |
|
|
//####//------------------------------------------------------------ |
18 |
|
|
//####// COPYRIGHT 2000-2024 |
19 |
|
|
//####// jeu 13 jun 2024 11:58:55 EDT |
20 |
|
|
//####//------------------------------------------------------------ |
21 |
|
|
//####//------------------------------------------------------------ |
22 |
francois |
447 |
#include "mailleur2d_optimisation.h" |
23 |
|
|
#include "m3d_triangle.h" |
24 |
|
|
#include "mg_gestionnaire.h" |
25 |
|
|
#include "ot_decalage_parametre.h" |
26 |
|
|
#include <math.h> |
27 |
francois |
696 |
#include <string.h> |
28 |
francois |
447 |
|
29 |
|
|
|
30 |
francois |
494 |
MAILLEUR2D_OPTIMISATION::MAILLEUR2D_OPTIMISATION(MG_MAILLAGE* mgmai,int niv):MAILLEUR(false),mg_maillage(mgmai),niveau_optimisation(niv) |
31 |
francois |
447 |
{ |
32 |
|
|
} |
33 |
|
|
|
34 |
|
|
MAILLEUR2D_OPTIMISATION::~MAILLEUR2D_OPTIMISATION() |
35 |
|
|
{ |
36 |
|
|
} |
37 |
|
|
|
38 |
|
|
void MAILLEUR2D_OPTIMISATION::change_niveau_optimisation(int num) |
39 |
|
|
{ |
40 |
|
|
niveau_optimisation=num; |
41 |
|
|
} |
42 |
|
|
|
43 |
|
|
int MAILLEUR2D_OPTIMISATION::get_niveau_optimisation(void) |
44 |
|
|
{ |
45 |
|
|
return niveau_optimisation; |
46 |
|
|
} |
47 |
|
|
|
48 |
francois |
448 |
void MAILLEUR2D_OPTIMISATION::optimise(MG_VOLUME* mgvolume) |
49 |
|
|
{ |
50 |
|
|
LISTE_MG_TRIANGLE::iterator ittr; |
51 |
|
|
TPL_MAP_ENTITE<M3D_TRIANGLE*> lsttrim3d; |
52 |
|
|
for (MG_TRIANGLE* tri=mg_maillage->get_premier_triangle(ittr);tri!=NULL;tri=mg_maillage->get_suivant_triangle(ittr)) |
53 |
|
|
{ |
54 |
|
|
M3D_TRIANGLE* nvtri=new M3D_TRIANGLE(tri->get_id(),tri->get_lien_topologie(),tri->get_noeud1(),tri->get_noeud2(),tri->get_noeud3(),tri->get_segment1(),tri->get_segment2(),tri->get_segment3(),tri->get_origine()); |
55 |
|
|
lsttrim3d.ajouter(nvtri); |
56 |
|
|
} |
57 |
francois |
447 |
|
58 |
francois |
448 |
TPL_MAP_ENTITE<M3D_TRIANGLE*>::ITERATEUR it2; |
59 |
francois |
454 |
TPL_MAP_ENTITE<MG_NOEUD*> liste_noeud; |
60 |
francois |
448 |
|
61 |
francois |
454 |
|
62 |
francois |
448 |
for (M3D_TRIANGLE* tri=lsttrim3d.get_premier(it2);tri!=NULL;tri=lsttrim3d.get_suivant(it2)) |
63 |
|
|
{ |
64 |
|
|
mg_maillage->supprimer_mg_triangleid(tri->get_id()); |
65 |
francois |
454 |
mg_maillage->ajouter_mg_triangle(tri); |
66 |
|
|
liste_noeud.ajouter(tri->get_noeud1()); |
67 |
|
|
liste_noeud.ajouter(tri->get_noeud2()); |
68 |
|
|
liste_noeud.ajouter(tri->get_noeud3()); |
69 |
francois |
448 |
} |
70 |
|
|
|
71 |
|
|
int nbcoquille=mgvolume->get_nb_mg_coquille(); |
72 |
|
|
for (int i=0;i<nbcoquille;i++) |
73 |
|
|
{ |
74 |
|
|
MG_COQUILLE* coq=mgvolume->get_mg_coquille(i); |
75 |
|
|
int nbface=coq->get_nb_mg_coface(); |
76 |
|
|
for (int j=0;j<nbface;j++) |
77 |
|
|
{ |
78 |
|
|
MG_FACE* face=coq->get_mg_coface(j)->get_face(); |
79 |
francois |
454 |
optimise_avec_calcul_uv(face); |
80 |
francois |
448 |
} |
81 |
|
|
} |
82 |
|
|
|
83 |
|
|
} |
84 |
|
|
|
85 |
francois |
573 |
|
86 |
|
|
void MAILLEUR2D_OPTIMISATION::optimise(MG_COQUE* mgcoque) |
87 |
|
|
{ |
88 |
|
|
LISTE_MG_TRIANGLE::iterator ittr; |
89 |
|
|
TPL_MAP_ENTITE<M3D_TRIANGLE*> lsttrim3d; |
90 |
|
|
for (MG_TRIANGLE* tri=mg_maillage->get_premier_triangle(ittr);tri!=NULL;tri=mg_maillage->get_suivant_triangle(ittr)) |
91 |
|
|
{ |
92 |
|
|
M3D_TRIANGLE* nvtri=new M3D_TRIANGLE(tri->get_id(),tri->get_lien_topologie(),tri->get_noeud1(),tri->get_noeud2(),tri->get_noeud3(),tri->get_segment1(),tri->get_segment2(),tri->get_segment3(),tri->get_origine()); |
93 |
|
|
lsttrim3d.ajouter(nvtri); |
94 |
|
|
} |
95 |
|
|
|
96 |
|
|
TPL_MAP_ENTITE<M3D_TRIANGLE*>::ITERATEUR it2; |
97 |
|
|
TPL_MAP_ENTITE<MG_NOEUD*> liste_noeud; |
98 |
|
|
|
99 |
|
|
|
100 |
|
|
for (M3D_TRIANGLE* tri=lsttrim3d.get_premier(it2);tri!=NULL;tri=lsttrim3d.get_suivant(it2)) |
101 |
|
|
{ |
102 |
|
|
mg_maillage->supprimer_mg_triangleid(tri->get_id()); |
103 |
|
|
mg_maillage->ajouter_mg_triangle(tri); |
104 |
|
|
liste_noeud.ajouter(tri->get_noeud1()); |
105 |
|
|
liste_noeud.ajouter(tri->get_noeud2()); |
106 |
|
|
liste_noeud.ajouter(tri->get_noeud3()); |
107 |
|
|
} |
108 |
|
|
|
109 |
|
|
int nbcoquille=mgcoque->get_nb_mg_coquille(); |
110 |
|
|
for (int i=0;i<nbcoquille;i++) |
111 |
|
|
{ |
112 |
|
|
MG_COQUILLE* coq=mgcoque->get_mg_coquille(i); |
113 |
|
|
int nbface=coq->get_nb_mg_coface(); |
114 |
|
|
for (int j=0;j<nbface;j++) |
115 |
|
|
{ |
116 |
|
|
MG_FACE* face=coq->get_mg_coface(j)->get_face(); |
117 |
|
|
optimise_avec_calcul_uv(face); |
118 |
|
|
} |
119 |
|
|
} |
120 |
|
|
|
121 |
|
|
} |
122 |
francois |
454 |
void MAILLEUR2D_OPTIMISATION::optimise_avec_calcul_uv(MG_FACE* mgface) |
123 |
|
|
{ |
124 |
|
|
TPL_MAP_ENTITE<MG_NOEUD*> liste_noeud; |
125 |
|
|
TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it; |
126 |
|
|
for (MG_TRIANGLE *mgtri=(MG_TRIANGLE*)mgface->get_lien_maillage()->get_premier(it);mgtri!=NULL;mgtri=(MG_TRIANGLE*)mgface->get_lien_maillage()->get_suivant(it)) |
127 |
|
|
{ |
128 |
|
|
if (mg_maillage->get_mg_triangleid(mgtri->get_id())!=mgtri) continue; |
129 |
|
|
liste_noeud.ajouter(mgtri->get_noeud1()); |
130 |
|
|
liste_noeud.ajouter(mgtri->get_noeud2()); |
131 |
|
|
liste_noeud.ajouter(mgtri->get_noeud3()); |
132 |
|
|
} |
133 |
|
|
TPL_MAP_ENTITE<MG_NOEUD*>::ITERATEUR it2; |
134 |
|
|
for (MG_NOEUD* no=liste_noeud.get_premier(it2);no!=NULL;no=liste_noeud.get_suivant(it2)) |
135 |
|
|
{ |
136 |
|
|
double uv[2]; |
137 |
|
|
double *xyz=no->get_coord(); |
138 |
|
|
mgface->inverser(uv,xyz); |
139 |
|
|
no->change_u(uv[0]); |
140 |
|
|
no->change_v(uv[1]); |
141 |
|
|
} |
142 |
sattarpa |
644 |
reinit(); |
143 |
|
|
optimise(mgface); |
144 |
francois |
454 |
} |
145 |
|
|
|
146 |
|
|
|
147 |
|
|
|
148 |
sattarpa |
644 |
void MAILLEUR2D_OPTIMISATION::reinit(void) |
149 |
|
|
{ |
150 |
francois |
696 |
lst_tri[0].clear(); |
151 |
|
|
lst_tri[1].clear(); |
152 |
|
|
lst_triid[0].clear(); |
153 |
|
|
lst_triid[1].clear(); |
154 |
sattarpa |
644 |
} |
155 |
francois |
454 |
|
156 |
|
|
|
157 |
francois |
696 |
void MAILLEUR2D_OPTIMISATION::ajouter_ordre_tri(M3D_TRIANGLE* tri,int num) |
158 |
|
|
{ |
159 |
|
|
double val; |
160 |
|
|
if (num==0) val=tri->get_qualite(); |
161 |
|
|
if (num==1) val=1./tri->get_qualite(); |
162 |
|
|
std::pair<double,M3D_TRIANGLE*> tmp(val,tri); |
163 |
|
|
ORDRE_TRIANGLE::iterator p=lst_tri[num].insert(tmp); |
164 |
|
|
lst_triid[num][tri->get_id()]=p; |
165 |
|
|
} |
166 |
francois |
454 |
|
167 |
|
|
|
168 |
francois |
696 |
void MAILLEUR2D_OPTIMISATION::supprimer_ordre_tri(M3D_TRIANGLE* tri) |
169 |
|
|
{ |
170 |
|
|
int num=0; |
171 |
|
|
ORDRE_TRIANGLE_PARID::iterator it=lst_triid[num].find(tri->get_id()); |
172 |
|
|
if (it==lst_triid[num].end()) |
173 |
|
|
{ |
174 |
|
|
num=1; |
175 |
|
|
it=lst_triid[num].find(tri->get_id()); |
176 |
|
|
} |
177 |
|
|
if (it==lst_triid[num].end()) return; |
178 |
|
|
lst_tri[num].erase(it->second); |
179 |
|
|
lst_triid[num].erase(it); |
180 |
|
|
} |
181 |
|
|
|
182 |
|
|
|
183 |
francois |
447 |
void MAILLEUR2D_OPTIMISATION::optimise(MG_FACE* mgface) |
184 |
|
|
{ |
185 |
francois |
696 |
periode_u=mgface->get_surface()->get_periode_u(); |
186 |
|
|
periode_v=mgface->get_surface()->get_periode_v(); |
187 |
|
|
decalage=new OT_DECALAGE_PARAMETRE(periode_u,periode_v); |
188 |
|
|
std::vector<int> strategie; |
189 |
|
|
char* code=(char*)param.get_nom("Optimisation_2D").c_str(); |
190 |
|
|
for (int i=0;i<strlen(code);i++) |
191 |
|
|
{ |
192 |
|
|
if (code[i]=='1') strategie.push_back(1); |
193 |
|
|
if (code[i]=='2') strategie.push_back(2); |
194 |
|
|
if (code[i]=='3') strategie.push_back(3); |
195 |
|
|
if (code[i]=='4') strategie.push_back(4); |
196 |
|
|
} |
197 |
|
|
|
198 |
|
|
int nb_level=strategie.size(); |
199 |
|
|
std::string info=" stratégie d'optimisation "; |
200 |
|
|
for (int level=0;level<nb_level;level++) |
201 |
|
|
{ |
202 |
|
|
char chaine[10]; |
203 |
|
|
sprintf(chaine,"%d",strategie[level]); |
204 |
|
|
info = info + chaine; |
205 |
|
|
reinit(); |
206 |
francois |
447 |
TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it; |
207 |
|
|
for (MG_TRIANGLE *mgtri=(MG_TRIANGLE*)mgface->get_lien_maillage()->get_premier(it);mgtri!=NULL;mgtri=(MG_TRIANGLE*)mgface->get_lien_maillage()->get_suivant(it)) |
208 |
|
|
{ |
209 |
francois |
448 |
if (mg_maillage->get_mg_triangleid(mgtri->get_id())!=mgtri) continue; |
210 |
francois |
447 |
M3D_TRIANGLE* mtri=(M3D_TRIANGLE*)mgtri; |
211 |
|
|
double qual=OPERATEUR::qualite_triangle(mtri->get_noeud1()->get_coord(),mtri->get_noeud2()->get_coord(),mtri->get_noeud3()->get_coord()); |
212 |
|
|
mtri->change_qualite(qual); |
213 |
|
|
if (mtri->get_qualite()<0.1*niveau_optimisation) |
214 |
francois |
696 |
ajouter_ordre_tri(mtri,0); |
215 |
francois |
447 |
} |
216 |
francois |
696 |
|
217 |
francois |
447 |
for (int phase=0;phase<2;phase++) |
218 |
|
|
{ |
219 |
|
|
int ok=0; |
220 |
|
|
do |
221 |
|
|
{ |
222 |
francois |
696 |
ORDRE_TRIANGLE::iterator i=lst_tri[phase].begin(); |
223 |
|
|
if (i==lst_tri[phase].end()) |
224 |
francois |
447 |
{ |
225 |
|
|
ok=1; |
226 |
|
|
continue; |
227 |
|
|
} |
228 |
|
|
M3D_TRIANGLE* tri=(*i).second; |
229 |
francois |
696 |
supprimer_ordre_tri(tri); |
230 |
|
|
switch (strategie[level]) |
231 |
|
|
{ |
232 |
|
|
case 1: operateur_bouge_de_point(phase,mgface,tri); |
233 |
|
|
break; |
234 |
|
|
case 2: operateur_inverse_diagonale(phase,mgface,&tri); |
235 |
|
|
break; |
236 |
|
|
case 3: operateur_bouge_de_point(phase,mgface,tri); |
237 |
|
|
operateur_inverse_diagonale(phase,mgface,&tri); |
238 |
|
|
break; |
239 |
|
|
case 4: operateur_inverse_diagonale(phase,mgface,&tri); |
240 |
|
|
if (tri!=NULL) operateur_bouge_de_point(phase,mgface,tri); |
241 |
|
|
break; |
242 |
|
|
} |
243 |
|
|
if (tri!=NULL) |
244 |
francois |
447 |
if ((tri->get_qualite()<0.1*niveau_optimisation) && (phase==0)) |
245 |
francois |
696 |
ajouter_ordre_tri(tri,1); |
246 |
francois |
447 |
} |
247 |
|
|
while (ok==0); |
248 |
|
|
} |
249 |
francois |
696 |
} |
250 |
|
|
affiche((char*)info.c_str()); |
251 |
francois |
447 |
delete decalage; |
252 |
|
|
} |
253 |
|
|
|
254 |
francois |
696 |
int MAILLEUR2D_OPTIMISATION::inverse_diagonale(MG_FACE* face,int num,M3D_TRIANGLE* tri,M3D_TRIANGLE** autretri,double &crit,MG_NOEUD** tabnoeudres) |
255 |
|
|
{ |
256 |
|
|
MG_SEGMENT* seg; |
257 |
|
|
MG_NOEUD* no1; |
258 |
|
|
MG_NOEUD* no2; |
259 |
|
|
MG_NOEUD* no3; |
260 |
francois |
791 |
if (tri->get_origine()==MAGIC::ORIGINE::IMPOSE) return 0; |
261 |
francois |
696 |
if (num==0) |
262 |
|
|
{ |
263 |
|
|
seg=tri->get_segment1(); |
264 |
|
|
no1=tri->get_noeud1(); |
265 |
|
|
no2=tri->get_noeud2(); |
266 |
|
|
no3=tri->get_noeud3(); |
267 |
|
|
} |
268 |
|
|
else if (num==1) |
269 |
|
|
{ |
270 |
|
|
seg=tri->get_segment2(); |
271 |
|
|
no1=tri->get_noeud2(); |
272 |
|
|
no2=tri->get_noeud3(); |
273 |
|
|
no3=tri->get_noeud1(); |
274 |
|
|
} |
275 |
|
|
else if (num==2) |
276 |
|
|
{ |
277 |
|
|
seg=tri->get_segment3(); |
278 |
|
|
no1=tri->get_noeud3(); |
279 |
|
|
no2=tri->get_noeud1(); |
280 |
|
|
no3=tri->get_noeud2(); |
281 |
|
|
} |
282 |
|
|
else return 0; |
283 |
|
|
if (seg->get_lien_topologie()!=face) return 0; |
284 |
francois |
447 |
|
285 |
|
|
|
286 |
francois |
696 |
*autretri=NULL; |
287 |
|
|
for (int i=0;i<no1->get_lien_triangle()->get_nb();i++) |
288 |
|
|
for (int j=0;j<no2->get_lien_triangle()->get_nb();j++) |
289 |
|
|
{ |
290 |
|
|
MG_TRIANGLE* tri1=no1->get_lien_triangle()->get(i); |
291 |
|
|
MG_TRIANGLE* tri2=no2->get_lien_triangle()->get(j); |
292 |
|
|
if (tri1==tri2) |
293 |
|
|
if (tri1!=tri) *autretri=(M3D_TRIANGLE*)tri1; |
294 |
|
|
} |
295 |
|
|
if ((*autretri)==NULL) return 0; |
296 |
francois |
791 |
if ((*autretri)->get_origine()==MAGIC::ORIGINE::IMPOSE) return 0; |
297 |
francois |
696 |
MG_NOEUD* no4; |
298 |
|
|
if (((*autretri)->get_noeud1()!=no1) && ((*autretri)->get_noeud1()!=no2)) no4=(*autretri)->get_noeud1(); |
299 |
|
|
if (((*autretri)->get_noeud2()!=no1) && ((*autretri)->get_noeud2()!=no2)) no4=(*autretri)->get_noeud2(); |
300 |
|
|
if (((*autretri)->get_noeud3()!=no1) && ((*autretri)->get_noeud3()!=no2)) no4=(*autretri)->get_noeud3(); |
301 |
|
|
double qual1=tri->get_qualite(); |
302 |
|
|
double qual2=(*autretri)->get_qualite(); |
303 |
|
|
double qualmin=std::min(qual1,qual2); |
304 |
|
|
double nqual1=OPERATEUR::qualite_triangle(no1->get_coord(),no4->get_coord(),no3->get_coord()); |
305 |
|
|
double nqual2=OPERATEUR::qualite_triangle(no2->get_coord(),no3->get_coord(),no4->get_coord()); |
306 |
|
|
OT_VECTEUR_3D n1n3(no1->get_coord(),no3->get_coord()); |
307 |
|
|
OT_VECTEUR_3D n1n4(no1->get_coord(),no4->get_coord()); |
308 |
|
|
double xyznormal[3]; |
309 |
|
|
double uv[2]={no1->get_u(),no1->get_v()}; |
310 |
|
|
face->calcul_normale_unitaire(uv,xyznormal); |
311 |
|
|
OT_VECTEUR_3D normalface(xyznormal); |
312 |
|
|
OT_VECTEUR_3D normal=normalface&n1n3; |
313 |
|
|
normal.norme(); |
314 |
|
|
n1n4.norme(); |
315 |
|
|
if (normal*n1n4<0.0001) nqual1=0.; |
316 |
|
|
OT_VECTEUR_3D n2n4(no2->get_coord(),no4->get_coord()); |
317 |
|
|
OT_VECTEUR_3D n2n3(no2->get_coord(),no3->get_coord()); |
318 |
|
|
double uv2[2]={no2->get_u(),no2->get_v()}; |
319 |
|
|
face->calcul_normale_unitaire(uv2,xyznormal); |
320 |
|
|
OT_VECTEUR_3D normalface2(xyznormal); |
321 |
|
|
OT_VECTEUR_3D normal2=normalface&n2n4; |
322 |
|
|
normal2.norme(); |
323 |
|
|
n2n3.norme(); |
324 |
|
|
if (normal2*n2n3<0.0001) nqual2=0.; |
325 |
|
|
double nqualmin=std::min(nqual1,nqual2); |
326 |
|
|
if (nqualmin>qualmin) |
327 |
|
|
{ |
328 |
|
|
crit=nqualmin; |
329 |
|
|
tabnoeudres[0]=no1; |
330 |
|
|
tabnoeudres[1]=no4; |
331 |
|
|
tabnoeudres[2]=no3; |
332 |
|
|
tabnoeudres[3]=no2; |
333 |
|
|
tabnoeudres[4]=no3; |
334 |
|
|
tabnoeudres[5]=no4; |
335 |
|
|
return 1; |
336 |
|
|
} |
337 |
|
|
return 0; |
338 |
|
|
} |
339 |
|
|
|
340 |
francois |
447 |
int MAILLEUR2D_OPTIMISATION::bouge_point(MG_FACE* mgface,MG_NOEUD* mg_noeud,double& crit,double &u,double& v,double& x,double& y, double& z) |
341 |
|
|
{ |
342 |
|
|
if (mg_noeud->get_lien_topologie()!=mgface) return 0; |
343 |
francois |
791 |
if (mg_noeud->get_origine()==MAGIC::ORIGINE::IMPOSE) return 0; |
344 |
francois |
447 |
double du=decalage->calcul_decalage_parametre_u(mg_noeud->get_u()); |
345 |
|
|
double dv=decalage->calcul_decalage_parametre_v(mg_noeud->get_v()); |
346 |
|
|
double u1=decalage->decalage_parametre_u(mg_noeud->get_u(),du); |
347 |
|
|
double v1=decalage->decalage_parametre_v(mg_noeud->get_v(),dv); |
348 |
|
|
double uopt=0.; |
349 |
|
|
double vopt=0.; |
350 |
|
|
double qual_dep=1.; |
351 |
|
|
int nb_tri=mg_noeud->get_lien_triangle()->get_nb(); |
352 |
|
|
for (int i=0;i<nb_tri;i++) |
353 |
|
|
{ |
354 |
|
|
M3D_TRIANGLE* tri=(M3D_TRIANGLE*)mg_noeud->get_lien_triangle()->get(i); |
355 |
|
|
qual_dep=std::min(qual_dep,tri->get_qualite()); |
356 |
|
|
MG_NOEUD* no1=tri->get_noeud1(); |
357 |
|
|
MG_NOEUD* no2=tri->get_noeud2(); |
358 |
|
|
MG_NOEUD* no3=tri->get_noeud3(); |
359 |
|
|
MG_NOEUD *noeud1,*noeud2; |
360 |
|
|
if (no1==mg_noeud) |
361 |
|
|
{ |
362 |
|
|
noeud1=no2; |
363 |
|
|
noeud2=no3; |
364 |
|
|
} |
365 |
|
|
if (no2==mg_noeud) |
366 |
|
|
{ |
367 |
|
|
noeud1=no1; |
368 |
|
|
noeud2=no3; |
369 |
|
|
} |
370 |
|
|
if (no3==mg_noeud) |
371 |
|
|
{ |
372 |
|
|
noeud1=no1; |
373 |
|
|
noeud2=no2; |
374 |
|
|
} |
375 |
|
|
double u2=noeud1->get_u()+du; |
376 |
|
|
double v2=noeud1->get_v()+dv; |
377 |
|
|
uopt=uopt+u2; |
378 |
|
|
vopt=vopt+v2; |
379 |
|
|
u2=noeud2->get_u()+du; |
380 |
|
|
v2=noeud2->get_v()+dv; |
381 |
|
|
uopt=uopt+u2; |
382 |
|
|
vopt=vopt+v2; |
383 |
|
|
} |
384 |
|
|
uopt=uopt/2./nb_tri; |
385 |
|
|
vopt=vopt/2./nb_tri; |
386 |
|
|
|
387 |
|
|
double ddeb=sqrt((u1-uopt)*(u1-uopt)+(v1-vopt)*(v1-vopt)); |
388 |
|
|
double alpha=0.5; |
389 |
|
|
double d=alpha*ddeb; |
390 |
|
|
double qual=qual_dep; |
391 |
|
|
double testu[8]={1.,-1.,0.,0.,0.707106781,-0.707106781,-0.707106781,0.707106781}; |
392 |
|
|
double testv[8]={0.,0.,1.,-1.,0.707106781,0.707106781,-0.707106781,-0.707106781}; |
393 |
|
|
double uu=u1; |
394 |
|
|
double vv=v1; |
395 |
|
|
while (alpha>0.09) |
396 |
|
|
{ |
397 |
|
|
double qualcoq=0.; |
398 |
|
|
for (int nb_essai=0;nb_essai<8;nb_essai++) |
399 |
|
|
{ |
400 |
|
|
double uv[2]; |
401 |
|
|
double xyz[3]; |
402 |
|
|
uv[0]=uu+d*testu[nb_essai]-du; |
403 |
|
|
uv[1]=vv+d*testv[nb_essai]-dv; |
404 |
|
|
int valide1=mgface->valide_parametre_u(uv[0]); |
405 |
|
|
int valide2=mgface->valide_parametre_v(uv[1]); |
406 |
|
|
if (!((valide1) && (valide2) )) break; |
407 |
|
|
mgface->evaluer(uv,xyz); |
408 |
|
|
double qual1=1.; |
409 |
|
|
for (int i=0;i<nb_tri;i++) |
410 |
|
|
{ |
411 |
|
|
M3D_TRIANGLE* tri=(M3D_TRIANGLE*)mg_noeud->get_lien_triangle()->get(i); |
412 |
|
|
MG_NOEUD* no1=tri->get_noeud1(); |
413 |
|
|
MG_NOEUD* no2=tri->get_noeud2(); |
414 |
|
|
MG_NOEUD* no3=tri->get_noeud3(); |
415 |
|
|
double *xyz1=no1->get_coord(); |
416 |
|
|
double *xyz2=no2->get_coord(); |
417 |
|
|
double *xyz3=no3->get_coord(); |
418 |
|
|
if (no1==mg_noeud) xyz1=xyz; |
419 |
|
|
if (no2==mg_noeud) xyz2=xyz; |
420 |
|
|
if (no3==mg_noeud) xyz3=xyz; |
421 |
|
|
double qualtmp=OPERATEUR::qualite_triangle(xyz1,xyz2,xyz3); |
422 |
|
|
OT_VECTEUR_3D n1n3(xyz1,xyz3); |
423 |
|
|
OT_VECTEUR_3D n1n2(xyz1,xyz2); |
424 |
|
|
double xyznormal[3]; |
425 |
|
|
mgface->calcul_normale_unitaire(uv,xyznormal); |
426 |
|
|
OT_VECTEUR_3D normalface(xyznormal); |
427 |
|
|
OT_VECTEUR_3D normal=normalface&n1n3; |
428 |
|
|
normal.norme(); |
429 |
|
|
n1n2.norme(); |
430 |
|
|
if (normal*n1n2<0.0001) qualtmp=0.; |
431 |
|
|
if (qualtmp<qual1) qual1=qualtmp; |
432 |
|
|
} |
433 |
|
|
if (qual1>qualcoq) |
434 |
|
|
{ |
435 |
|
|
qualcoq=qual1; |
436 |
|
|
crit=qualcoq; |
437 |
|
|
u=uv[0]+du; |
438 |
|
|
v=uv[1]+dv; |
439 |
|
|
} |
440 |
|
|
} |
441 |
|
|
|
442 |
|
|
if (qualcoq<qual+0.0001) alpha=alpha-0.1; |
443 |
|
|
else |
444 |
|
|
{ |
445 |
|
|
qual=qualcoq; |
446 |
|
|
uu=u; |
447 |
|
|
vv=v; |
448 |
|
|
} |
449 |
|
|
d=ddeb*alpha; |
450 |
|
|
|
451 |
|
|
} |
452 |
|
|
if (qual>qual_dep) |
453 |
|
|
{ |
454 |
|
|
u=decalage->decalage_parametre_u(u,-du); |
455 |
|
|
v=decalage->decalage_parametre_v(v,-dv); |
456 |
|
|
double uv[2]; |
457 |
|
|
uv[0]=u; |
458 |
|
|
uv[1]=v; |
459 |
|
|
double xyz[3]; |
460 |
|
|
mgface->evaluer(uv,xyz); |
461 |
|
|
x=xyz[0]; |
462 |
|
|
y=xyz[1]; |
463 |
|
|
z=xyz[2]; |
464 |
|
|
return 1; |
465 |
|
|
} |
466 |
|
|
return 0; |
467 |
|
|
} |
468 |
francois |
696 |
|
469 |
|
|
class M3D_TRIANGLE* MAILLEUR2D_OPTIMISATION::insere_triangle(class MG_FACE* mgface,MG_NOEUD* noeud1,MG_NOEUD* noeud2,MG_NOEUD* noeud3,int origine) |
470 |
|
|
{ |
471 |
|
|
MG_SEGMENT* segment1=mg_maillage->get_mg_segment(noeud1->get_id(),noeud2->get_id()); |
472 |
francois |
700 |
MG_SEGMENT* segment2=mg_maillage->get_mg_segment(noeud2->get_id(),noeud3->get_id()); |
473 |
|
|
MG_SEGMENT* segment3=mg_maillage->get_mg_segment(noeud3->get_id(),noeud1->get_id()); |
474 |
francois |
696 |
if (segment1==NULL) segment1=cree_segment(mgface,noeud1,noeud2,origine); |
475 |
francois |
700 |
if (segment2==NULL) segment2=cree_segment(mgface,noeud2,noeud3,origine); |
476 |
|
|
if (segment3==NULL) segment3=cree_segment(mgface,noeud3,noeud1,origine); |
477 |
francois |
696 |
M3D_TRIANGLE* tri=cree_triangle(mgface,noeud1,noeud2,noeud3,segment1,segment2,segment3,origine); |
478 |
|
|
double qual=OPERATEUR::qualite_triangle(noeud1->get_coord(),noeud2->get_coord(),noeud3->get_coord()); |
479 |
|
|
tri->change_qualite(qual); |
480 |
|
|
return tri; |
481 |
|
|
} |
482 |
|
|
|
483 |
|
|
|
484 |
|
|
|
485 |
|
|
|
486 |
|
|
void MAILLEUR2D_OPTIMISATION::operateur_bouge_de_point(int phase,MG_FACE* mgface,M3D_TRIANGLE* tri) |
487 |
|
|
{ |
488 |
|
|
if (tri->get_qualite()<0.1*niveau_optimisation) |
489 |
|
|
{ |
490 |
|
|
MG_NOEUD* no[3]; |
491 |
|
|
no[0]=tri->get_noeud1(); |
492 |
|
|
no[1]=tri->get_noeud2(); |
493 |
|
|
no[2]=tri->get_noeud3(); |
494 |
|
|
double crit[3],u[3],v[3],x[3],y[3],z[3]; |
495 |
|
|
int ierr=bouge_point(mgface,no[0],crit[0],u[0],v[0],x[0],y[0],z[0]); |
496 |
|
|
if (ierr==0) crit[0]=0.; |
497 |
|
|
ierr=bouge_point(mgface,no[1],crit[1],u[1],v[1],x[1],y[1],z[1]); |
498 |
|
|
if (ierr==0) crit[1]=0.; |
499 |
|
|
ierr=bouge_point(mgface,no[2],crit[2],u[2],v[2],x[2],y[2],z[2]); |
500 |
|
|
if (ierr==0) crit[2]=0.; |
501 |
|
|
double critopt=std::max(crit[0],crit[1]); |
502 |
|
|
critopt=std::max(critopt,crit[2]); |
503 |
|
|
int num=-1; |
504 |
|
|
if (critopt>tri->get_qualite()) |
505 |
|
|
{ |
506 |
|
|
if (critopt==crit[0]) num=0; |
507 |
|
|
if (critopt==crit[1]) num=1; |
508 |
|
|
if (critopt==crit[2]) num=2; |
509 |
|
|
} |
510 |
|
|
if (num!=-1) |
511 |
|
|
{ |
512 |
|
|
no[num]->change_u(u[num]); |
513 |
|
|
no[num]->change_v(v[num]); |
514 |
|
|
no[num]->change_x(x[num]); |
515 |
|
|
no[num]->change_y(y[num]); |
516 |
|
|
no[num]->change_z(z[num]); |
517 |
|
|
int nb_tri=no[num]->get_lien_triangle()->get_nb(); |
518 |
|
|
for (int i=0;i<nb_tri;i++) |
519 |
|
|
{ |
520 |
|
|
M3D_TRIANGLE* mtri=(M3D_TRIANGLE*)no[num]->get_lien_triangle()->get(i); |
521 |
|
|
double qual=OPERATEUR::qualite_triangle(mtri->get_noeud1()->get_coord(),mtri->get_noeud2()->get_coord(),mtri->get_noeud3()->get_coord()); |
522 |
|
|
mtri->change_qualite(qual); |
523 |
|
|
if (mtri!=tri) |
524 |
|
|
{ |
525 |
|
|
supprimer_ordre_tri(mtri); |
526 |
|
|
if (mtri->get_qualite()<0.1*niveau_optimisation) ajouter_ordre_tri(mtri,phase); |
527 |
|
|
} |
528 |
|
|
|
529 |
|
|
} |
530 |
|
|
} |
531 |
|
|
} |
532 |
|
|
} |
533 |
|
|
|
534 |
|
|
|
535 |
|
|
void MAILLEUR2D_OPTIMISATION::operateur_inverse_diagonale(int phase,MG_FACE* mgface,M3D_TRIANGLE** tri) |
536 |
|
|
{ |
537 |
|
|
if ((*tri)->get_qualite()<0.1*niveau_optimisation) |
538 |
|
|
{ |
539 |
|
|
MG_NOEUD* tab1[6]; |
540 |
|
|
MG_NOEUD* tab2[6]; |
541 |
|
|
MG_NOEUD* tab3[6]; |
542 |
|
|
double crit1,crit2,crit3; |
543 |
|
|
M3D_TRIANGLE* autretri1; |
544 |
|
|
M3D_TRIANGLE* autretri2; |
545 |
|
|
M3D_TRIANGLE* autretri3; |
546 |
|
|
int ierr1=inverse_diagonale(mgface,0,*tri,&autretri1,crit1,tab1); |
547 |
|
|
int ierr2=inverse_diagonale(mgface,1,*tri,&autretri2,crit2,tab2); |
548 |
|
|
int ierr3=inverse_diagonale(mgface,2,*tri,&autretri3,crit3,tab3); |
549 |
|
|
double maxcrit=std::max(ierr1*crit1,ierr2*crit2); |
550 |
|
|
maxcrit=std::max(maxcrit,ierr3*crit3); |
551 |
|
|
MG_NOEUD** tab; |
552 |
|
|
M3D_TRIANGLE *autretri; |
553 |
|
|
if (maxcrit>(*tri)->get_qualite()) |
554 |
|
|
{ |
555 |
|
|
if (maxcrit==ierr1*crit1) {tab=tab1;autretri=autretri1;} |
556 |
|
|
if (maxcrit==ierr2*crit2) {tab=tab2;autretri=autretri2;} |
557 |
|
|
if (maxcrit==ierr3*crit3) {tab=tab3;autretri=autretri3;} |
558 |
francois |
791 |
M3D_TRIANGLE* nvtri1=insere_triangle(mgface,tab[0],tab[1],tab[2],MAGIC::ORIGINE::MAILLEUR_AUTO); |
559 |
|
|
M3D_TRIANGLE* nvtri2=insere_triangle(mgface,tab[3],tab[4],tab[5],MAGIC::ORIGINE::MAILLEUR_AUTO); |
560 |
francois |
696 |
if (nvtri1->get_qualite()<0.1*niveau_optimisation) ajouter_ordre_tri(nvtri1,phase); |
561 |
|
|
if (nvtri2->get_qualite()<0.1*niveau_optimisation) ajouter_ordre_tri(nvtri2,phase); |
562 |
|
|
supprimer_ordre_tri(autretri); |
563 |
|
|
mg_maillage->supprimer_mg_triangleid((*tri)->get_id());(*tri)=NULL; |
564 |
|
|
mg_maillage->supprimer_mg_triangleid(autretri->get_id()); |
565 |
|
|
} |
566 |
|
|
} |
567 |
|
|
} |
568 |
|
|
M3D_TRIANGLE* MAILLEUR2D_OPTIMISATION::cree_triangle(class MG_FACE* mgface,MG_NOEUD* noeud1,MG_NOEUD* noeud2,MG_NOEUD* noeud3,MG_SEGMENT* segment1,MG_SEGMENT* segment2,MG_SEGMENT* segment3,int origine) |
569 |
|
|
{ |
570 |
|
|
M3D_TRIANGLE* tri=new M3D_TRIANGLE(mgface,noeud1,noeud2,noeud3,segment1,segment2,segment3,origine); |
571 |
|
|
mg_maillage->ajouter_mg_triangle(tri); |
572 |
|
|
return tri; |
573 |
|
|
} |
574 |
|
|
|
575 |
|
|
|
576 |
|
|
|
577 |
|
|
MG_SEGMENT* MAILLEUR2D_OPTIMISATION::cree_segment(class MG_FACE* mgface,MG_NOEUD* noeud1,MG_NOEUD* noeud2,int origine) |
578 |
|
|
{ |
579 |
|
|
MG_SEGMENT* seg=mg_maillage->ajouter_mg_segment(mgface,noeud1,noeud2,origine); |
580 |
|
|
seg->change_dimension_topo_null(3); |
581 |
|
|
return seg; |
582 |
|
|
} |