1 |
//####//------------------------------------------------------------ |
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 |
#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 |
#include <string.h> |
28 |
|
29 |
|
30 |
MAILLEUR2D_OPTIMISATION::MAILLEUR2D_OPTIMISATION(MG_MAILLAGE* mgmai,int niv):MAILLEUR(false),mg_maillage(mgmai),niveau_optimisation(niv) |
31 |
{ |
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 |
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 |
|
58 |
TPL_MAP_ENTITE<M3D_TRIANGLE*>::ITERATEUR it2; |
59 |
TPL_MAP_ENTITE<MG_NOEUD*> liste_noeud; |
60 |
|
61 |
|
62 |
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 |
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 |
} |
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 |
optimise_avec_calcul_uv(face); |
80 |
} |
81 |
} |
82 |
|
83 |
} |
84 |
|
85 |
|
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 |
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 |
reinit(); |
143 |
optimise(mgface); |
144 |
} |
145 |
|
146 |
|
147 |
|
148 |
void MAILLEUR2D_OPTIMISATION::reinit(void) |
149 |
{ |
150 |
lst_tri[0].clear(); |
151 |
lst_tri[1].clear(); |
152 |
lst_triid[0].clear(); |
153 |
lst_triid[1].clear(); |
154 |
} |
155 |
|
156 |
|
157 |
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 |
|
167 |
|
168 |
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 |
void MAILLEUR2D_OPTIMISATION::optimise(MG_FACE* mgface) |
184 |
{ |
185 |
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 |
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 |
if (mg_maillage->get_mg_triangleid(mgtri->get_id())!=mgtri) continue; |
210 |
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 |
ajouter_ordre_tri(mtri,0); |
215 |
} |
216 |
|
217 |
for (int phase=0;phase<2;phase++) |
218 |
{ |
219 |
int ok=0; |
220 |
do |
221 |
{ |
222 |
ORDRE_TRIANGLE::iterator i=lst_tri[phase].begin(); |
223 |
if (i==lst_tri[phase].end()) |
224 |
{ |
225 |
ok=1; |
226 |
continue; |
227 |
} |
228 |
M3D_TRIANGLE* tri=(*i).second; |
229 |
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 |
if ((tri->get_qualite()<0.1*niveau_optimisation) && (phase==0)) |
245 |
ajouter_ordre_tri(tri,1); |
246 |
} |
247 |
while (ok==0); |
248 |
} |
249 |
} |
250 |
affiche((char*)info.c_str()); |
251 |
delete decalage; |
252 |
} |
253 |
|
254 |
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 |
if (tri->get_origine()==MAGIC::ORIGINE::IMPOSE) return 0; |
261 |
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 |
|
285 |
|
286 |
*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 |
if ((*autretri)->get_origine()==MAGIC::ORIGINE::IMPOSE) return 0; |
297 |
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 |
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 |
if (mg_noeud->get_origine()==MAGIC::ORIGINE::IMPOSE) return 0; |
344 |
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 |
|
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 |
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 |
if (segment1==NULL) segment1=cree_segment(mgface,noeud1,noeud2,origine); |
475 |
if (segment2==NULL) segment2=cree_segment(mgface,noeud2,noeud3,origine); |
476 |
if (segment3==NULL) segment3=cree_segment(mgface,noeud3,noeud1,origine); |
477 |
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 |
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 |
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 |
} |