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 |
|
|
MAILLEUR2D_OPTIMISATION::MAILLEUR2D_OPTIMISATION(MG_MAILLAGE* mgmai,int niv):MAILLEUR(),mg_maillage(mgmai),niveau_optimisation(niv) |
9 |
|
|
{ |
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 |
454 |
void MAILLEUR2D_OPTIMISATION::optimise_avec_calcul_uv(MG_FACE* mgface) |
64 |
|
|
{ |
65 |
|
|
TPL_MAP_ENTITE<MG_NOEUD*> liste_noeud; |
66 |
|
|
TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it; |
67 |
|
|
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)) |
68 |
|
|
{ |
69 |
|
|
if (mg_maillage->get_mg_triangleid(mgtri->get_id())!=mgtri) continue; |
70 |
|
|
liste_noeud.ajouter(mgtri->get_noeud1()); |
71 |
|
|
liste_noeud.ajouter(mgtri->get_noeud2()); |
72 |
|
|
liste_noeud.ajouter(mgtri->get_noeud3()); |
73 |
|
|
} |
74 |
|
|
TPL_MAP_ENTITE<MG_NOEUD*>::ITERATEUR it2; |
75 |
|
|
for (MG_NOEUD* no=liste_noeud.get_premier(it2);no!=NULL;no=liste_noeud.get_suivant(it2)) |
76 |
|
|
{ |
77 |
|
|
double uv[2]; |
78 |
|
|
double *xyz=no->get_coord(); |
79 |
|
|
mgface->inverser(uv,xyz); |
80 |
|
|
no->change_u(uv[0]); |
81 |
|
|
no->change_v(uv[1]); |
82 |
|
|
} |
83 |
|
|
optimise(mgface); |
84 |
|
|
} |
85 |
|
|
|
86 |
|
|
|
87 |
|
|
|
88 |
|
|
|
89 |
|
|
|
90 |
|
|
|
91 |
|
|
|
92 |
|
|
|
93 |
francois |
447 |
void MAILLEUR2D_OPTIMISATION::optimise(MG_FACE* mgface) |
94 |
|
|
{ |
95 |
|
|
TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it; |
96 |
|
|
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)) |
97 |
|
|
{ |
98 |
francois |
448 |
if (mg_maillage->get_mg_triangleid(mgtri->get_id())!=mgtri) continue; |
99 |
francois |
447 |
M3D_TRIANGLE* mtri=(M3D_TRIANGLE*)mgtri; |
100 |
|
|
double qual=OPERATEUR::qualite_triangle(mtri->get_noeud1()->get_coord(),mtri->get_noeud2()->get_coord(),mtri->get_noeud3()->get_coord()); |
101 |
|
|
mtri->change_qualite(qual); |
102 |
|
|
if (mtri->get_qualite()<0.1*niveau_optimisation) |
103 |
|
|
{ |
104 |
|
|
std::pair<const double,M3D_TRIANGLE*> tmp(mtri->get_qualite(),mtri); |
105 |
|
|
lst_tri_qual.insert(tmp); |
106 |
|
|
} |
107 |
|
|
} |
108 |
|
|
periode_u=mgface->get_surface()->get_periode_u(); |
109 |
|
|
periode_v=mgface->get_surface()->get_periode_v(); |
110 |
|
|
decalage=new OT_DECALAGE_PARAMETRE(periode_u,periode_v); |
111 |
|
|
for (int phase=0;phase<2;phase++) |
112 |
|
|
{ |
113 |
|
|
ORDRE_TRIANGLE& lst=lst_tri_qual; |
114 |
|
|
if (phase==1) |
115 |
|
|
lst=lst_tri_qual2; |
116 |
|
|
int ok=0; |
117 |
|
|
do |
118 |
|
|
{ |
119 |
|
|
ORDRE_TRIANGLE::iterator i=lst.begin(); |
120 |
|
|
if (i==lst.end()) |
121 |
|
|
{ |
122 |
|
|
ok=1; |
123 |
|
|
continue; |
124 |
|
|
} |
125 |
|
|
M3D_TRIANGLE* tri=(*i).second; |
126 |
francois |
448 |
if (tri->get_qualite()<0.1*niveau_optimisation) |
127 |
francois |
447 |
{ |
128 |
|
|
MG_NOEUD* no[3]; |
129 |
|
|
no[0]=tri->get_noeud1(); |
130 |
|
|
no[1]=tri->get_noeud2(); |
131 |
|
|
no[2]=tri->get_noeud3(); |
132 |
|
|
double crit[3],u[3],v[3],x[3],y[3],z[3]; |
133 |
|
|
int ierr=bouge_point(mgface,no[0],crit[0],u[0],v[0],x[0],y[0],z[0]); |
134 |
|
|
if (ierr==0) crit[0]=0.; |
135 |
|
|
ierr=bouge_point(mgface,no[1],crit[1],u[1],v[1],x[1],y[1],z[1]); |
136 |
|
|
if (ierr==0) crit[1]=0.; |
137 |
|
|
ierr=bouge_point(mgface,no[2],crit[2],u[2],v[2],x[2],y[2],z[2]); |
138 |
|
|
if (ierr==0) crit[2]=0.; |
139 |
|
|
double critopt=std::max(crit[0],crit[1]); |
140 |
|
|
critopt=std::max(critopt,crit[2]); |
141 |
|
|
int num=-1; |
142 |
|
|
if (critopt>tri->get_qualite()) |
143 |
|
|
{ |
144 |
|
|
if (critopt==crit[0]) num=0; |
145 |
|
|
if (critopt==crit[1]) num=1; |
146 |
|
|
if (critopt==crit[2]) num=2; |
147 |
|
|
} |
148 |
|
|
if (num!=-1) |
149 |
|
|
{ |
150 |
|
|
no[num]->change_u(u[num]); |
151 |
|
|
no[num]->change_v(v[num]); |
152 |
|
|
no[num]->change_x(x[num]); |
153 |
|
|
no[num]->change_y(y[num]); |
154 |
|
|
no[num]->change_z(z[num]); |
155 |
|
|
int nb_tri=no[num]->get_lien_triangle()->get_nb(); |
156 |
|
|
for (int i=0;i<nb_tri;i++) |
157 |
|
|
{ |
158 |
|
|
M3D_TRIANGLE* mtri=(M3D_TRIANGLE*)no[num]->get_lien_triangle()->get(i); |
159 |
|
|
double qual=OPERATEUR::qualite_triangle(mtri->get_noeud1()->get_coord(),mtri->get_noeud2()->get_coord(),mtri->get_noeud3()->get_coord()); |
160 |
|
|
mtri->change_qualite(qual); |
161 |
|
|
} |
162 |
|
|
} |
163 |
|
|
} |
164 |
|
|
else ok=1; |
165 |
|
|
if ((tri->get_qualite()<0.1*niveau_optimisation) && (phase==0)) |
166 |
|
|
{ |
167 |
|
|
std::pair<const double,M3D_TRIANGLE*> tmp(1./tri->get_qualite(),tri); |
168 |
|
|
lst_tri_qual2.insert(tmp); |
169 |
|
|
} |
170 |
|
|
lst.erase(i); |
171 |
|
|
} |
172 |
|
|
while (ok==0); |
173 |
|
|
} |
174 |
|
|
delete decalage; |
175 |
|
|
} |
176 |
|
|
|
177 |
|
|
|
178 |
|
|
|
179 |
|
|
int MAILLEUR2D_OPTIMISATION::bouge_point(MG_FACE* mgface,MG_NOEUD* mg_noeud,double& crit,double &u,double& v,double& x,double& y, double& z) |
180 |
|
|
{ |
181 |
|
|
if (mg_noeud->get_lien_topologie()!=mgface) return 0; |
182 |
|
|
if (mg_noeud->get_origine()==IMPOSE) return 0; |
183 |
|
|
double du=decalage->calcul_decalage_parametre_u(mg_noeud->get_u()); |
184 |
|
|
double dv=decalage->calcul_decalage_parametre_v(mg_noeud->get_v()); |
185 |
|
|
double u1=decalage->decalage_parametre_u(mg_noeud->get_u(),du); |
186 |
|
|
double v1=decalage->decalage_parametre_v(mg_noeud->get_v(),dv); |
187 |
|
|
double uopt=0.; |
188 |
|
|
double vopt=0.; |
189 |
|
|
double qual_dep=1.; |
190 |
|
|
int nb_tri=mg_noeud->get_lien_triangle()->get_nb(); |
191 |
|
|
for (int i=0;i<nb_tri;i++) |
192 |
|
|
{ |
193 |
|
|
M3D_TRIANGLE* tri=(M3D_TRIANGLE*)mg_noeud->get_lien_triangle()->get(i); |
194 |
|
|
qual_dep=std::min(qual_dep,tri->get_qualite()); |
195 |
|
|
MG_NOEUD* no1=tri->get_noeud1(); |
196 |
|
|
MG_NOEUD* no2=tri->get_noeud2(); |
197 |
|
|
MG_NOEUD* no3=tri->get_noeud3(); |
198 |
|
|
MG_NOEUD *noeud1,*noeud2; |
199 |
|
|
if (no1==mg_noeud) |
200 |
|
|
{ |
201 |
|
|
noeud1=no2; |
202 |
|
|
noeud2=no3; |
203 |
|
|
} |
204 |
|
|
if (no2==mg_noeud) |
205 |
|
|
{ |
206 |
|
|
noeud1=no1; |
207 |
|
|
noeud2=no3; |
208 |
|
|
} |
209 |
|
|
if (no3==mg_noeud) |
210 |
|
|
{ |
211 |
|
|
noeud1=no1; |
212 |
|
|
noeud2=no2; |
213 |
|
|
} |
214 |
|
|
double u2=noeud1->get_u()+du; |
215 |
|
|
double v2=noeud1->get_v()+dv; |
216 |
|
|
uopt=uopt+u2; |
217 |
|
|
vopt=vopt+v2; |
218 |
|
|
u2=noeud2->get_u()+du; |
219 |
|
|
v2=noeud2->get_v()+dv; |
220 |
|
|
uopt=uopt+u2; |
221 |
|
|
vopt=vopt+v2; |
222 |
|
|
} |
223 |
|
|
uopt=uopt/2./nb_tri; |
224 |
|
|
vopt=vopt/2./nb_tri; |
225 |
|
|
|
226 |
|
|
double ddeb=sqrt((u1-uopt)*(u1-uopt)+(v1-vopt)*(v1-vopt)); |
227 |
|
|
double alpha=0.5; |
228 |
|
|
double d=alpha*ddeb; |
229 |
|
|
double qual=qual_dep; |
230 |
|
|
double testu[8]={1.,-1.,0.,0.,0.707106781,-0.707106781,-0.707106781,0.707106781}; |
231 |
|
|
double testv[8]={0.,0.,1.,-1.,0.707106781,0.707106781,-0.707106781,-0.707106781}; |
232 |
|
|
double uu=u1; |
233 |
|
|
double vv=v1; |
234 |
|
|
while (alpha>0.09) |
235 |
|
|
{ |
236 |
|
|
double qualcoq=0.; |
237 |
|
|
for (int nb_essai=0;nb_essai<8;nb_essai++) |
238 |
|
|
{ |
239 |
|
|
double uv[2]; |
240 |
|
|
double xyz[3]; |
241 |
|
|
uv[0]=uu+d*testu[nb_essai]-du; |
242 |
|
|
uv[1]=vv+d*testv[nb_essai]-dv; |
243 |
|
|
int valide1=mgface->valide_parametre_u(uv[0]); |
244 |
|
|
int valide2=mgface->valide_parametre_v(uv[1]); |
245 |
|
|
if (!((valide1) && (valide2) )) break; |
246 |
|
|
mgface->evaluer(uv,xyz); |
247 |
|
|
double qual1=1.; |
248 |
|
|
for (int i=0;i<nb_tri;i++) |
249 |
|
|
{ |
250 |
|
|
M3D_TRIANGLE* tri=(M3D_TRIANGLE*)mg_noeud->get_lien_triangle()->get(i); |
251 |
|
|
MG_NOEUD* no1=tri->get_noeud1(); |
252 |
|
|
MG_NOEUD* no2=tri->get_noeud2(); |
253 |
|
|
MG_NOEUD* no3=tri->get_noeud3(); |
254 |
|
|
double *xyz1=no1->get_coord(); |
255 |
|
|
double *xyz2=no2->get_coord(); |
256 |
|
|
double *xyz3=no3->get_coord(); |
257 |
|
|
if (no1==mg_noeud) xyz1=xyz; |
258 |
|
|
if (no2==mg_noeud) xyz2=xyz; |
259 |
|
|
if (no3==mg_noeud) xyz3=xyz; |
260 |
|
|
double qualtmp=OPERATEUR::qualite_triangle(xyz1,xyz2,xyz3); |
261 |
|
|
OT_VECTEUR_3D n1n3(xyz1,xyz3); |
262 |
|
|
OT_VECTEUR_3D n1n2(xyz1,xyz2); |
263 |
|
|
double xyznormal[3]; |
264 |
|
|
mgface->calcul_normale_unitaire(uv,xyznormal); |
265 |
|
|
OT_VECTEUR_3D normalface(xyznormal); |
266 |
|
|
OT_VECTEUR_3D normal=normalface&n1n3; |
267 |
|
|
normal.norme(); |
268 |
|
|
n1n2.norme(); |
269 |
|
|
if (normal*n1n2<0.0001) qualtmp=0.; |
270 |
|
|
if (qualtmp<qual1) qual1=qualtmp; |
271 |
|
|
} |
272 |
|
|
if (qual1>qualcoq) |
273 |
|
|
{ |
274 |
|
|
qualcoq=qual1; |
275 |
|
|
crit=qualcoq; |
276 |
|
|
u=uv[0]+du; |
277 |
|
|
v=uv[1]+dv; |
278 |
|
|
} |
279 |
|
|
} |
280 |
|
|
|
281 |
|
|
if (qualcoq<qual+0.0001) alpha=alpha-0.1; |
282 |
|
|
else |
283 |
|
|
{ |
284 |
|
|
qual=qualcoq; |
285 |
|
|
uu=u; |
286 |
|
|
vv=v; |
287 |
|
|
} |
288 |
|
|
d=ddeb*alpha; |
289 |
|
|
|
290 |
|
|
} |
291 |
|
|
if (qual>qual_dep) |
292 |
|
|
{ |
293 |
|
|
u=decalage->decalage_parametre_u(u,-du); |
294 |
|
|
v=decalage->decalage_parametre_v(v,-dv); |
295 |
|
|
double uv[2]; |
296 |
|
|
uv[0]=u; |
297 |
|
|
uv[1]=v; |
298 |
|
|
double xyz[3]; |
299 |
|
|
mgface->evaluer(uv,xyz); |
300 |
|
|
x=xyz[0]; |
301 |
|
|
y=xyz[1]; |
302 |
|
|
z=xyz[2]; |
303 |
|
|
return 1; |
304 |
|
|
} |
305 |
|
|
return 0; |
306 |
|
|
} |