1 |
francois |
447 |
#include "mailleur2d_optimisation.h" |
2 |
|
|
#include "m3d_triangle.h" |
3 |
|
|
#include "mg_gestionnaire.h" |
4 |
|
|
#include "ot_decalage_parametre.h" |
5 |
|
|
#include <math.h> |
6 |
|
|
|
7 |
|
|
|
8 |
francois |
494 |
MAILLEUR2D_OPTIMISATION::MAILLEUR2D_OPTIMISATION(MG_MAILLAGE* mgmai,int niv):MAILLEUR(false),mg_maillage(mgmai),niveau_optimisation(niv) |
9 |
francois |
447 |
{ |
10 |
|
|
} |
11 |
|
|
|
12 |
|
|
MAILLEUR2D_OPTIMISATION::~MAILLEUR2D_OPTIMISATION() |
13 |
|
|
{ |
14 |
|
|
} |
15 |
|
|
|
16 |
|
|
void MAILLEUR2D_OPTIMISATION::change_niveau_optimisation(int num) |
17 |
|
|
{ |
18 |
|
|
niveau_optimisation=num; |
19 |
|
|
} |
20 |
|
|
|
21 |
|
|
int MAILLEUR2D_OPTIMISATION::get_niveau_optimisation(void) |
22 |
|
|
{ |
23 |
|
|
return niveau_optimisation; |
24 |
|
|
} |
25 |
|
|
|
26 |
francois |
448 |
void MAILLEUR2D_OPTIMISATION::optimise(MG_VOLUME* mgvolume) |
27 |
|
|
{ |
28 |
|
|
LISTE_MG_TRIANGLE::iterator ittr; |
29 |
|
|
TPL_MAP_ENTITE<M3D_TRIANGLE*> lsttrim3d; |
30 |
|
|
for (MG_TRIANGLE* tri=mg_maillage->get_premier_triangle(ittr);tri!=NULL;tri=mg_maillage->get_suivant_triangle(ittr)) |
31 |
|
|
{ |
32 |
|
|
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()); |
33 |
|
|
lsttrim3d.ajouter(nvtri); |
34 |
|
|
} |
35 |
francois |
447 |
|
36 |
francois |
448 |
TPL_MAP_ENTITE<M3D_TRIANGLE*>::ITERATEUR it2; |
37 |
francois |
454 |
TPL_MAP_ENTITE<MG_NOEUD*> liste_noeud; |
38 |
francois |
448 |
|
39 |
francois |
454 |
|
40 |
francois |
448 |
for (M3D_TRIANGLE* tri=lsttrim3d.get_premier(it2);tri!=NULL;tri=lsttrim3d.get_suivant(it2)) |
41 |
|
|
{ |
42 |
|
|
mg_maillage->supprimer_mg_triangleid(tri->get_id()); |
43 |
francois |
454 |
mg_maillage->ajouter_mg_triangle(tri); |
44 |
|
|
liste_noeud.ajouter(tri->get_noeud1()); |
45 |
|
|
liste_noeud.ajouter(tri->get_noeud2()); |
46 |
|
|
liste_noeud.ajouter(tri->get_noeud3()); |
47 |
francois |
448 |
} |
48 |
|
|
|
49 |
|
|
int nbcoquille=mgvolume->get_nb_mg_coquille(); |
50 |
|
|
for (int i=0;i<nbcoquille;i++) |
51 |
|
|
{ |
52 |
|
|
MG_COQUILLE* coq=mgvolume->get_mg_coquille(i); |
53 |
|
|
int nbface=coq->get_nb_mg_coface(); |
54 |
|
|
for (int j=0;j<nbface;j++) |
55 |
|
|
{ |
56 |
|
|
MG_FACE* face=coq->get_mg_coface(j)->get_face(); |
57 |
francois |
454 |
optimise_avec_calcul_uv(face); |
58 |
francois |
448 |
} |
59 |
|
|
} |
60 |
|
|
|
61 |
|
|
} |
62 |
|
|
|
63 |
francois |
573 |
|
64 |
|
|
void MAILLEUR2D_OPTIMISATION::optimise(MG_COQUE* mgcoque) |
65 |
|
|
{ |
66 |
|
|
LISTE_MG_TRIANGLE::iterator ittr; |
67 |
|
|
TPL_MAP_ENTITE<M3D_TRIANGLE*> lsttrim3d; |
68 |
|
|
for (MG_TRIANGLE* tri=mg_maillage->get_premier_triangle(ittr);tri!=NULL;tri=mg_maillage->get_suivant_triangle(ittr)) |
69 |
|
|
{ |
70 |
|
|
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()); |
71 |
|
|
lsttrim3d.ajouter(nvtri); |
72 |
|
|
} |
73 |
|
|
|
74 |
|
|
TPL_MAP_ENTITE<M3D_TRIANGLE*>::ITERATEUR it2; |
75 |
|
|
TPL_MAP_ENTITE<MG_NOEUD*> liste_noeud; |
76 |
|
|
|
77 |
|
|
|
78 |
|
|
for (M3D_TRIANGLE* tri=lsttrim3d.get_premier(it2);tri!=NULL;tri=lsttrim3d.get_suivant(it2)) |
79 |
|
|
{ |
80 |
|
|
mg_maillage->supprimer_mg_triangleid(tri->get_id()); |
81 |
|
|
mg_maillage->ajouter_mg_triangle(tri); |
82 |
|
|
liste_noeud.ajouter(tri->get_noeud1()); |
83 |
|
|
liste_noeud.ajouter(tri->get_noeud2()); |
84 |
|
|
liste_noeud.ajouter(tri->get_noeud3()); |
85 |
|
|
} |
86 |
|
|
|
87 |
|
|
int nbcoquille=mgcoque->get_nb_mg_coquille(); |
88 |
|
|
for (int i=0;i<nbcoquille;i++) |
89 |
|
|
{ |
90 |
|
|
MG_COQUILLE* coq=mgcoque->get_mg_coquille(i); |
91 |
|
|
int nbface=coq->get_nb_mg_coface(); |
92 |
|
|
for (int j=0;j<nbface;j++) |
93 |
|
|
{ |
94 |
|
|
MG_FACE* face=coq->get_mg_coface(j)->get_face(); |
95 |
|
|
optimise_avec_calcul_uv(face); |
96 |
|
|
} |
97 |
|
|
} |
98 |
|
|
|
99 |
|
|
} |
100 |
francois |
454 |
void MAILLEUR2D_OPTIMISATION::optimise_avec_calcul_uv(MG_FACE* mgface) |
101 |
|
|
{ |
102 |
|
|
TPL_MAP_ENTITE<MG_NOEUD*> liste_noeud; |
103 |
|
|
TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it; |
104 |
|
|
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)) |
105 |
|
|
{ |
106 |
|
|
if (mg_maillage->get_mg_triangleid(mgtri->get_id())!=mgtri) continue; |
107 |
|
|
liste_noeud.ajouter(mgtri->get_noeud1()); |
108 |
|
|
liste_noeud.ajouter(mgtri->get_noeud2()); |
109 |
|
|
liste_noeud.ajouter(mgtri->get_noeud3()); |
110 |
|
|
} |
111 |
|
|
TPL_MAP_ENTITE<MG_NOEUD*>::ITERATEUR it2; |
112 |
|
|
for (MG_NOEUD* no=liste_noeud.get_premier(it2);no!=NULL;no=liste_noeud.get_suivant(it2)) |
113 |
|
|
{ |
114 |
|
|
double uv[2]; |
115 |
|
|
double *xyz=no->get_coord(); |
116 |
|
|
mgface->inverser(uv,xyz); |
117 |
|
|
no->change_u(uv[0]); |
118 |
|
|
no->change_v(uv[1]); |
119 |
|
|
} |
120 |
|
|
optimise(mgface); |
121 |
|
|
} |
122 |
|
|
|
123 |
|
|
|
124 |
|
|
|
125 |
|
|
|
126 |
|
|
|
127 |
|
|
|
128 |
|
|
|
129 |
|
|
|
130 |
francois |
447 |
void MAILLEUR2D_OPTIMISATION::optimise(MG_FACE* mgface) |
131 |
|
|
{ |
132 |
|
|
TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it; |
133 |
|
|
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)) |
134 |
|
|
{ |
135 |
francois |
448 |
if (mg_maillage->get_mg_triangleid(mgtri->get_id())!=mgtri) continue; |
136 |
francois |
447 |
M3D_TRIANGLE* mtri=(M3D_TRIANGLE*)mgtri; |
137 |
|
|
double qual=OPERATEUR::qualite_triangle(mtri->get_noeud1()->get_coord(),mtri->get_noeud2()->get_coord(),mtri->get_noeud3()->get_coord()); |
138 |
|
|
mtri->change_qualite(qual); |
139 |
|
|
if (mtri->get_qualite()<0.1*niveau_optimisation) |
140 |
|
|
{ |
141 |
|
|
std::pair<const double,M3D_TRIANGLE*> tmp(mtri->get_qualite(),mtri); |
142 |
|
|
lst_tri_qual.insert(tmp); |
143 |
|
|
} |
144 |
|
|
} |
145 |
|
|
periode_u=mgface->get_surface()->get_periode_u(); |
146 |
|
|
periode_v=mgface->get_surface()->get_periode_v(); |
147 |
|
|
decalage=new OT_DECALAGE_PARAMETRE(periode_u,periode_v); |
148 |
|
|
for (int phase=0;phase<2;phase++) |
149 |
|
|
{ |
150 |
|
|
ORDRE_TRIANGLE& lst=lst_tri_qual; |
151 |
|
|
if (phase==1) |
152 |
|
|
lst=lst_tri_qual2; |
153 |
|
|
int ok=0; |
154 |
|
|
do |
155 |
|
|
{ |
156 |
|
|
ORDRE_TRIANGLE::iterator i=lst.begin(); |
157 |
|
|
if (i==lst.end()) |
158 |
|
|
{ |
159 |
|
|
ok=1; |
160 |
|
|
continue; |
161 |
|
|
} |
162 |
|
|
M3D_TRIANGLE* tri=(*i).second; |
163 |
francois |
448 |
if (tri->get_qualite()<0.1*niveau_optimisation) |
164 |
francois |
447 |
{ |
165 |
|
|
MG_NOEUD* no[3]; |
166 |
|
|
no[0]=tri->get_noeud1(); |
167 |
|
|
no[1]=tri->get_noeud2(); |
168 |
|
|
no[2]=tri->get_noeud3(); |
169 |
|
|
double crit[3],u[3],v[3],x[3],y[3],z[3]; |
170 |
|
|
int ierr=bouge_point(mgface,no[0],crit[0],u[0],v[0],x[0],y[0],z[0]); |
171 |
|
|
if (ierr==0) crit[0]=0.; |
172 |
|
|
ierr=bouge_point(mgface,no[1],crit[1],u[1],v[1],x[1],y[1],z[1]); |
173 |
|
|
if (ierr==0) crit[1]=0.; |
174 |
|
|
ierr=bouge_point(mgface,no[2],crit[2],u[2],v[2],x[2],y[2],z[2]); |
175 |
|
|
if (ierr==0) crit[2]=0.; |
176 |
|
|
double critopt=std::max(crit[0],crit[1]); |
177 |
|
|
critopt=std::max(critopt,crit[2]); |
178 |
|
|
int num=-1; |
179 |
|
|
if (critopt>tri->get_qualite()) |
180 |
|
|
{ |
181 |
|
|
if (critopt==crit[0]) num=0; |
182 |
|
|
if (critopt==crit[1]) num=1; |
183 |
|
|
if (critopt==crit[2]) num=2; |
184 |
|
|
} |
185 |
|
|
if (num!=-1) |
186 |
|
|
{ |
187 |
|
|
no[num]->change_u(u[num]); |
188 |
|
|
no[num]->change_v(v[num]); |
189 |
|
|
no[num]->change_x(x[num]); |
190 |
|
|
no[num]->change_y(y[num]); |
191 |
|
|
no[num]->change_z(z[num]); |
192 |
|
|
int nb_tri=no[num]->get_lien_triangle()->get_nb(); |
193 |
|
|
for (int i=0;i<nb_tri;i++) |
194 |
|
|
{ |
195 |
|
|
M3D_TRIANGLE* mtri=(M3D_TRIANGLE*)no[num]->get_lien_triangle()->get(i); |
196 |
|
|
double qual=OPERATEUR::qualite_triangle(mtri->get_noeud1()->get_coord(),mtri->get_noeud2()->get_coord(),mtri->get_noeud3()->get_coord()); |
197 |
|
|
mtri->change_qualite(qual); |
198 |
|
|
} |
199 |
|
|
} |
200 |
|
|
} |
201 |
|
|
else ok=1; |
202 |
|
|
if ((tri->get_qualite()<0.1*niveau_optimisation) && (phase==0)) |
203 |
|
|
{ |
204 |
|
|
std::pair<const double,M3D_TRIANGLE*> tmp(1./tri->get_qualite(),tri); |
205 |
|
|
lst_tri_qual2.insert(tmp); |
206 |
|
|
} |
207 |
|
|
lst.erase(i); |
208 |
|
|
} |
209 |
|
|
while (ok==0); |
210 |
|
|
} |
211 |
|
|
delete decalage; |
212 |
|
|
} |
213 |
|
|
|
214 |
|
|
|
215 |
|
|
|
216 |
|
|
int MAILLEUR2D_OPTIMISATION::bouge_point(MG_FACE* mgface,MG_NOEUD* mg_noeud,double& crit,double &u,double& v,double& x,double& y, double& z) |
217 |
|
|
{ |
218 |
|
|
if (mg_noeud->get_lien_topologie()!=mgface) return 0; |
219 |
|
|
if (mg_noeud->get_origine()==IMPOSE) return 0; |
220 |
|
|
double du=decalage->calcul_decalage_parametre_u(mg_noeud->get_u()); |
221 |
|
|
double dv=decalage->calcul_decalage_parametre_v(mg_noeud->get_v()); |
222 |
|
|
double u1=decalage->decalage_parametre_u(mg_noeud->get_u(),du); |
223 |
|
|
double v1=decalage->decalage_parametre_v(mg_noeud->get_v(),dv); |
224 |
|
|
double uopt=0.; |
225 |
|
|
double vopt=0.; |
226 |
|
|
double qual_dep=1.; |
227 |
|
|
int nb_tri=mg_noeud->get_lien_triangle()->get_nb(); |
228 |
|
|
for (int i=0;i<nb_tri;i++) |
229 |
|
|
{ |
230 |
|
|
M3D_TRIANGLE* tri=(M3D_TRIANGLE*)mg_noeud->get_lien_triangle()->get(i); |
231 |
|
|
qual_dep=std::min(qual_dep,tri->get_qualite()); |
232 |
|
|
MG_NOEUD* no1=tri->get_noeud1(); |
233 |
|
|
MG_NOEUD* no2=tri->get_noeud2(); |
234 |
|
|
MG_NOEUD* no3=tri->get_noeud3(); |
235 |
|
|
MG_NOEUD *noeud1,*noeud2; |
236 |
|
|
if (no1==mg_noeud) |
237 |
|
|
{ |
238 |
|
|
noeud1=no2; |
239 |
|
|
noeud2=no3; |
240 |
|
|
} |
241 |
|
|
if (no2==mg_noeud) |
242 |
|
|
{ |
243 |
|
|
noeud1=no1; |
244 |
|
|
noeud2=no3; |
245 |
|
|
} |
246 |
|
|
if (no3==mg_noeud) |
247 |
|
|
{ |
248 |
|
|
noeud1=no1; |
249 |
|
|
noeud2=no2; |
250 |
|
|
} |
251 |
|
|
double u2=noeud1->get_u()+du; |
252 |
|
|
double v2=noeud1->get_v()+dv; |
253 |
|
|
uopt=uopt+u2; |
254 |
|
|
vopt=vopt+v2; |
255 |
|
|
u2=noeud2->get_u()+du; |
256 |
|
|
v2=noeud2->get_v()+dv; |
257 |
|
|
uopt=uopt+u2; |
258 |
|
|
vopt=vopt+v2; |
259 |
|
|
} |
260 |
|
|
uopt=uopt/2./nb_tri; |
261 |
|
|
vopt=vopt/2./nb_tri; |
262 |
|
|
|
263 |
|
|
double ddeb=sqrt((u1-uopt)*(u1-uopt)+(v1-vopt)*(v1-vopt)); |
264 |
|
|
double alpha=0.5; |
265 |
|
|
double d=alpha*ddeb; |
266 |
|
|
double qual=qual_dep; |
267 |
|
|
double testu[8]={1.,-1.,0.,0.,0.707106781,-0.707106781,-0.707106781,0.707106781}; |
268 |
|
|
double testv[8]={0.,0.,1.,-1.,0.707106781,0.707106781,-0.707106781,-0.707106781}; |
269 |
|
|
double uu=u1; |
270 |
|
|
double vv=v1; |
271 |
|
|
while (alpha>0.09) |
272 |
|
|
{ |
273 |
|
|
double qualcoq=0.; |
274 |
|
|
for (int nb_essai=0;nb_essai<8;nb_essai++) |
275 |
|
|
{ |
276 |
|
|
double uv[2]; |
277 |
|
|
double xyz[3]; |
278 |
|
|
uv[0]=uu+d*testu[nb_essai]-du; |
279 |
|
|
uv[1]=vv+d*testv[nb_essai]-dv; |
280 |
|
|
int valide1=mgface->valide_parametre_u(uv[0]); |
281 |
|
|
int valide2=mgface->valide_parametre_v(uv[1]); |
282 |
|
|
if (!((valide1) && (valide2) )) break; |
283 |
|
|
mgface->evaluer(uv,xyz); |
284 |
|
|
double qual1=1.; |
285 |
|
|
for (int i=0;i<nb_tri;i++) |
286 |
|
|
{ |
287 |
|
|
M3D_TRIANGLE* tri=(M3D_TRIANGLE*)mg_noeud->get_lien_triangle()->get(i); |
288 |
|
|
MG_NOEUD* no1=tri->get_noeud1(); |
289 |
|
|
MG_NOEUD* no2=tri->get_noeud2(); |
290 |
|
|
MG_NOEUD* no3=tri->get_noeud3(); |
291 |
|
|
double *xyz1=no1->get_coord(); |
292 |
|
|
double *xyz2=no2->get_coord(); |
293 |
|
|
double *xyz3=no3->get_coord(); |
294 |
|
|
if (no1==mg_noeud) xyz1=xyz; |
295 |
|
|
if (no2==mg_noeud) xyz2=xyz; |
296 |
|
|
if (no3==mg_noeud) xyz3=xyz; |
297 |
|
|
double qualtmp=OPERATEUR::qualite_triangle(xyz1,xyz2,xyz3); |
298 |
|
|
OT_VECTEUR_3D n1n3(xyz1,xyz3); |
299 |
|
|
OT_VECTEUR_3D n1n2(xyz1,xyz2); |
300 |
|
|
double xyznormal[3]; |
301 |
|
|
mgface->calcul_normale_unitaire(uv,xyznormal); |
302 |
|
|
OT_VECTEUR_3D normalface(xyznormal); |
303 |
|
|
OT_VECTEUR_3D normal=normalface&n1n3; |
304 |
|
|
normal.norme(); |
305 |
|
|
n1n2.norme(); |
306 |
|
|
if (normal*n1n2<0.0001) qualtmp=0.; |
307 |
|
|
if (qualtmp<qual1) qual1=qualtmp; |
308 |
|
|
} |
309 |
|
|
if (qual1>qualcoq) |
310 |
|
|
{ |
311 |
|
|
qualcoq=qual1; |
312 |
|
|
crit=qualcoq; |
313 |
|
|
u=uv[0]+du; |
314 |
|
|
v=uv[1]+dv; |
315 |
|
|
} |
316 |
|
|
} |
317 |
|
|
|
318 |
|
|
if (qualcoq<qual+0.0001) alpha=alpha-0.1; |
319 |
|
|
else |
320 |
|
|
{ |
321 |
|
|
qual=qualcoq; |
322 |
|
|
uu=u; |
323 |
|
|
vv=v; |
324 |
|
|
} |
325 |
|
|
d=ddeb*alpha; |
326 |
|
|
|
327 |
|
|
} |
328 |
|
|
if (qual>qual_dep) |
329 |
|
|
{ |
330 |
|
|
u=decalage->decalage_parametre_u(u,-du); |
331 |
|
|
v=decalage->decalage_parametre_v(v,-dv); |
332 |
|
|
double uv[2]; |
333 |
|
|
uv[0]=u; |
334 |
|
|
uv[1]=v; |
335 |
|
|
double xyz[3]; |
336 |
|
|
mgface->evaluer(uv,xyz); |
337 |
|
|
x=xyz[0]; |
338 |
|
|
y=xyz[1]; |
339 |
|
|
z=xyz[2]; |
340 |
|
|
return 1; |
341 |
|
|
} |
342 |
|
|
return 0; |
343 |
|
|
} |