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 |
|
|
|
27 |
|
|
void MAILLEUR2D_OPTIMISATION::optimise(MG_FACE* mgface) |
28 |
|
|
{ |
29 |
|
|
TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it; |
30 |
|
|
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)) |
31 |
|
|
{ |
32 |
|
|
M3D_TRIANGLE* mtri=(M3D_TRIANGLE*)mgtri; |
33 |
|
|
double qual=OPERATEUR::qualite_triangle(mtri->get_noeud1()->get_coord(),mtri->get_noeud2()->get_coord(),mtri->get_noeud3()->get_coord()); |
34 |
|
|
mtri->change_qualite(qual); |
35 |
|
|
if (mtri->get_qualite()<0.1*niveau_optimisation) |
36 |
|
|
{ |
37 |
|
|
std::pair<const double,M3D_TRIANGLE*> tmp(mtri->get_qualite(),mtri); |
38 |
|
|
lst_tri_qual.insert(tmp); |
39 |
|
|
} |
40 |
|
|
} |
41 |
|
|
periode_u=mgface->get_surface()->get_periode_u(); |
42 |
|
|
periode_v=mgface->get_surface()->get_periode_v(); |
43 |
|
|
decalage=new OT_DECALAGE_PARAMETRE(periode_u,periode_v); |
44 |
|
|
for (int phase=0;phase<2;phase++) |
45 |
|
|
{ |
46 |
|
|
ORDRE_TRIANGLE& lst=lst_tri_qual; |
47 |
|
|
if (phase==1) |
48 |
|
|
lst=lst_tri_qual2; |
49 |
|
|
int ok=0; |
50 |
|
|
do |
51 |
|
|
{ |
52 |
|
|
ORDRE_TRIANGLE::iterator i=lst.begin(); |
53 |
|
|
if (i==lst.end()) |
54 |
|
|
{ |
55 |
|
|
ok=1; |
56 |
|
|
continue; |
57 |
|
|
} |
58 |
|
|
M3D_TRIANGLE* tri=(*i).second; |
59 |
|
|
if (tri->get_qualite()<0.5) |
60 |
|
|
{ |
61 |
|
|
MG_NOEUD* no[3]; |
62 |
|
|
no[0]=tri->get_noeud1(); |
63 |
|
|
no[1]=tri->get_noeud2(); |
64 |
|
|
no[2]=tri->get_noeud3(); |
65 |
|
|
double crit[3],u[3],v[3],x[3],y[3],z[3]; |
66 |
|
|
int ierr=bouge_point(mgface,no[0],crit[0],u[0],v[0],x[0],y[0],z[0]); |
67 |
|
|
if (ierr==0) crit[0]=0.; |
68 |
|
|
ierr=bouge_point(mgface,no[1],crit[1],u[1],v[1],x[1],y[1],z[1]); |
69 |
|
|
if (ierr==0) crit[1]=0.; |
70 |
|
|
ierr=bouge_point(mgface,no[2],crit[2],u[2],v[2],x[2],y[2],z[2]); |
71 |
|
|
if (ierr==0) crit[2]=0.; |
72 |
|
|
double critopt=std::max(crit[0],crit[1]); |
73 |
|
|
critopt=std::max(critopt,crit[2]); |
74 |
|
|
int num=-1; |
75 |
|
|
if (critopt>tri->get_qualite()) |
76 |
|
|
{ |
77 |
|
|
if (critopt==crit[0]) num=0; |
78 |
|
|
if (critopt==crit[1]) num=1; |
79 |
|
|
if (critopt==crit[2]) num=2; |
80 |
|
|
} |
81 |
|
|
if (num!=-1) |
82 |
|
|
{ |
83 |
|
|
no[num]->change_u(u[num]); |
84 |
|
|
no[num]->change_v(v[num]); |
85 |
|
|
no[num]->change_x(x[num]); |
86 |
|
|
no[num]->change_y(y[num]); |
87 |
|
|
no[num]->change_z(z[num]); |
88 |
|
|
int nb_tri=no[num]->get_lien_triangle()->get_nb(); |
89 |
|
|
for (int i=0;i<nb_tri;i++) |
90 |
|
|
{ |
91 |
|
|
M3D_TRIANGLE* mtri=(M3D_TRIANGLE*)no[num]->get_lien_triangle()->get(i); |
92 |
|
|
double qual=OPERATEUR::qualite_triangle(mtri->get_noeud1()->get_coord(),mtri->get_noeud2()->get_coord(),mtri->get_noeud3()->get_coord()); |
93 |
|
|
mtri->change_qualite(qual); |
94 |
|
|
} |
95 |
|
|
} |
96 |
|
|
} |
97 |
|
|
else ok=1; |
98 |
|
|
if ((tri->get_qualite()<0.1*niveau_optimisation) && (phase==0)) |
99 |
|
|
{ |
100 |
|
|
std::pair<const double,M3D_TRIANGLE*> tmp(1./tri->get_qualite(),tri); |
101 |
|
|
lst_tri_qual2.insert(tmp); |
102 |
|
|
} |
103 |
|
|
lst.erase(i); |
104 |
|
|
} |
105 |
|
|
while (ok==0); |
106 |
|
|
} |
107 |
|
|
delete decalage; |
108 |
|
|
} |
109 |
|
|
|
110 |
|
|
|
111 |
|
|
|
112 |
|
|
int MAILLEUR2D_OPTIMISATION::bouge_point(MG_FACE* mgface,MG_NOEUD* mg_noeud,double& crit,double &u,double& v,double& x,double& y, double& z) |
113 |
|
|
{ |
114 |
|
|
if (mg_noeud->get_lien_topologie()!=mgface) return 0; |
115 |
|
|
if (mg_noeud->get_origine()==IMPOSE) return 0; |
116 |
|
|
double du=decalage->calcul_decalage_parametre_u(mg_noeud->get_u()); |
117 |
|
|
double dv=decalage->calcul_decalage_parametre_v(mg_noeud->get_v()); |
118 |
|
|
double u1=decalage->decalage_parametre_u(mg_noeud->get_u(),du); |
119 |
|
|
double v1=decalage->decalage_parametre_v(mg_noeud->get_v(),dv); |
120 |
|
|
|
121 |
|
|
double uopt=0.; |
122 |
|
|
double vopt=0.; |
123 |
|
|
double qual_dep=1.; |
124 |
|
|
int nb_tri=mg_noeud->get_lien_triangle()->get_nb(); |
125 |
|
|
for (int i=0;i<nb_tri;i++) |
126 |
|
|
{ |
127 |
|
|
M3D_TRIANGLE* tri=(M3D_TRIANGLE*)mg_noeud->get_lien_triangle()->get(i); |
128 |
|
|
qual_dep=std::min(qual_dep,tri->get_qualite()); |
129 |
|
|
MG_NOEUD* no1=tri->get_noeud1(); |
130 |
|
|
MG_NOEUD* no2=tri->get_noeud2(); |
131 |
|
|
MG_NOEUD* no3=tri->get_noeud3(); |
132 |
|
|
MG_NOEUD *noeud1,*noeud2; |
133 |
|
|
if (no1==mg_noeud) |
134 |
|
|
{ |
135 |
|
|
noeud1=no2; |
136 |
|
|
noeud2=no3; |
137 |
|
|
} |
138 |
|
|
if (no2==mg_noeud) |
139 |
|
|
{ |
140 |
|
|
noeud1=no1; |
141 |
|
|
noeud2=no3; |
142 |
|
|
} |
143 |
|
|
if (no3==mg_noeud) |
144 |
|
|
{ |
145 |
|
|
noeud1=no1; |
146 |
|
|
noeud2=no2; |
147 |
|
|
} |
148 |
|
|
double u2=noeud1->get_u()+du; |
149 |
|
|
double v2=noeud1->get_v()+dv; |
150 |
|
|
uopt=uopt+u2; |
151 |
|
|
vopt=vopt+v2; |
152 |
|
|
u2=noeud2->get_u()+du; |
153 |
|
|
v2=noeud2->get_v()+dv; |
154 |
|
|
uopt=uopt+u2; |
155 |
|
|
vopt=vopt+v2; |
156 |
|
|
} |
157 |
|
|
uopt=uopt/2./nb_tri; |
158 |
|
|
vopt=vopt/2./nb_tri; |
159 |
|
|
|
160 |
|
|
double ddeb=sqrt((u1-uopt)*(u1-uopt)+(v1-vopt)*(v1-vopt)); |
161 |
|
|
double alpha=0.5; |
162 |
|
|
double d=alpha*ddeb; |
163 |
|
|
double qual=qual_dep; |
164 |
|
|
double testu[8]={1.,-1.,0.,0.,0.707106781,-0.707106781,-0.707106781,0.707106781}; |
165 |
|
|
double testv[8]={0.,0.,1.,-1.,0.707106781,0.707106781,-0.707106781,-0.707106781}; |
166 |
|
|
double uu=u1; |
167 |
|
|
double vv=v1; |
168 |
|
|
while (alpha>0.09) |
169 |
|
|
{ |
170 |
|
|
double qualcoq=0.; |
171 |
|
|
for (int nb_essai=0;nb_essai<8;nb_essai++) |
172 |
|
|
{ |
173 |
|
|
double uv[2]; |
174 |
|
|
double xyz[3]; |
175 |
|
|
uv[0]=uu+d*testu[nb_essai]-du; |
176 |
|
|
uv[1]=vv+d*testv[nb_essai]-dv; |
177 |
|
|
int valide1=mgface->valide_parametre_u(uv[0]); |
178 |
|
|
int valide2=mgface->valide_parametre_v(uv[1]); |
179 |
|
|
if (!((valide1) && (valide2) )) break; |
180 |
|
|
mgface->evaluer(uv,xyz); |
181 |
|
|
double qual1=1.; |
182 |
|
|
for (int i=0;i<nb_tri;i++) |
183 |
|
|
{ |
184 |
|
|
M3D_TRIANGLE* tri=(M3D_TRIANGLE*)mg_noeud->get_lien_triangle()->get(i); |
185 |
|
|
MG_NOEUD* no1=tri->get_noeud1(); |
186 |
|
|
MG_NOEUD* no2=tri->get_noeud2(); |
187 |
|
|
MG_NOEUD* no3=tri->get_noeud3(); |
188 |
|
|
double *xyz1=no1->get_coord(); |
189 |
|
|
double *xyz2=no2->get_coord(); |
190 |
|
|
double *xyz3=no3->get_coord(); |
191 |
|
|
if (no1==mg_noeud) xyz1=xyz; |
192 |
|
|
if (no2==mg_noeud) xyz2=xyz; |
193 |
|
|
if (no3==mg_noeud) xyz3=xyz; |
194 |
|
|
double qualtmp=OPERATEUR::qualite_triangle(xyz1,xyz2,xyz3); |
195 |
|
|
OT_VECTEUR_3D n1n3(xyz1,xyz3); |
196 |
|
|
OT_VECTEUR_3D n1n2(xyz1,xyz2); |
197 |
|
|
double xyznormal[3]; |
198 |
|
|
mgface->calcul_normale_unitaire(uv,xyznormal); |
199 |
|
|
OT_VECTEUR_3D normalface(xyznormal); |
200 |
|
|
OT_VECTEUR_3D normal=normalface&n1n3; |
201 |
|
|
normal.norme(); |
202 |
|
|
n1n2.norme(); |
203 |
|
|
if (normal*n1n2<0.0001) qualtmp=0.; |
204 |
|
|
if (qualtmp<qual1) qual1=qualtmp; |
205 |
|
|
} |
206 |
|
|
if (qual1>qualcoq) |
207 |
|
|
{ |
208 |
|
|
qualcoq=qual1; |
209 |
|
|
crit=qualcoq; |
210 |
|
|
u=uv[0]+du; |
211 |
|
|
v=uv[1]+dv; |
212 |
|
|
} |
213 |
|
|
} |
214 |
|
|
|
215 |
|
|
if (qualcoq<qual+0.0001) alpha=alpha-0.1; |
216 |
|
|
else |
217 |
|
|
{ |
218 |
|
|
qual=qualcoq; |
219 |
|
|
uu=u; |
220 |
|
|
vv=v; |
221 |
|
|
} |
222 |
|
|
d=ddeb*alpha; |
223 |
|
|
|
224 |
|
|
} |
225 |
|
|
if (qual>qual_dep) |
226 |
|
|
{ |
227 |
|
|
u=decalage->decalage_parametre_u(u,-du); |
228 |
|
|
v=decalage->decalage_parametre_v(v,-dv); |
229 |
|
|
double uv[2]; |
230 |
|
|
uv[0]=u; |
231 |
|
|
uv[1]=v; |
232 |
|
|
double xyz[3]; |
233 |
|
|
mgface->evaluer(uv,xyz); |
234 |
|
|
x=xyz[0]; |
235 |
|
|
y=xyz[1]; |
236 |
|
|
z=xyz[2]; |
237 |
|
|
return 1; |
238 |
|
|
} |
239 |
|
|
return 0; |
240 |
|
|
} |