1 |
francois |
1082 |
#include "mailleur_stl.h" |
2 |
|
|
#include "mg_maillage.h" |
3 |
|
|
#include "tpl_fonctions_generiques.h" |
4 |
|
|
#include "fct_taille.h" |
5 |
|
|
#include <tpl_map_entite.h> |
6 |
|
|
#include <mg_maillage_outils.h> |
7 |
|
|
#include <fct_taille_fem_solution_generateur_gradient.h> |
8 |
|
|
|
9 |
|
|
|
10 |
|
|
|
11 |
|
|
MAILLEUR_STL::MAILLEUR_STL(MG_MAILLAGE* maiori, MG_GESTIONNAIRE* gt, FCT_TAILLE* carte,double limite,double angle1,double angle2):MAILLEUR(false),maiin(maiori),gest(gt),metrique(carte),limite_discretisation(limite),angle_arete(angle1),angle_limite(angle2),pas(4),nx(25),ny(25),nz(25),qualmaxaopt(0.5),nbcoucheopt(1) |
12 |
|
|
{ |
13 |
|
|
} |
14 |
|
|
|
15 |
|
|
MAILLEUR_STL::MAILLEUR_STL(MAILLEUR_STL& mdd):MAILLEUR(mdd),maiin(mdd.maiin),mai(mdd.mai),metrique(mdd.metrique),pas(mdd.pas),angle_arete(mdd.angle_arete),angle_limite(mdd.angle_limite),limite_discretisation(mdd.limite_discretisation),nx(mdd.nx),ny(mdd.ny),nz(mdd.nz),qualmaxaopt(mdd.qualmaxaopt),nbcoucheopt(mdd.nbcoucheopt) |
16 |
|
|
{ |
17 |
|
|
} |
18 |
|
|
|
19 |
|
|
|
20 |
|
|
|
21 |
|
|
MAILLEUR_STL::~MAILLEUR_STL() |
22 |
|
|
{ |
23 |
|
|
delete gesttmp; |
24 |
|
|
} |
25 |
|
|
|
26 |
|
|
|
27 |
|
|
|
28 |
|
|
|
29 |
|
|
int MAILLEUR_STL::maille(class MG_GROUPE_TOPOLOGIQUE* mggt) |
30 |
|
|
{ |
31 |
|
|
|
32 |
|
|
affiche((char*)" Parametre du mailleur"); |
33 |
|
|
char mess[255]; |
34 |
|
|
sprintf(mess,(char*)" Ratio limite de discrétisation = %f",limite_discretisation); |
35 |
|
|
affiche(mess); |
36 |
|
|
sprintf(mess,(char*)" Ratio limite angle arete = %f",angle_arete); |
37 |
|
|
affiche(mess); |
38 |
|
|
sprintf(mess,(char*)" Ratio limite angle de la cavité de Delaunay = %f",angle_limite); |
39 |
|
|
affiche(mess); |
40 |
|
|
affiche((char*)" Duplication du maillage original"); |
41 |
|
|
//mai=maiin->dupliquer(gest); |
42 |
|
|
mai=maiin->detacher(gest); |
43 |
|
|
affiche((char*)" Adaptation de la carte de taille"); |
44 |
|
|
adapte_carte(); |
45 |
|
|
affiche((char*)" Prepartion de la projection"); |
46 |
|
|
prepare_projection(); |
47 |
|
|
affiche((char*)" Determination des arêtes"); |
48 |
|
|
determine_arete(); |
49 |
|
|
affiche((char*)" Maillage"); |
50 |
|
|
cree_maillage(); |
51 |
|
|
affiche((char*)" Optimisation de maillage"); |
52 |
|
|
int oldnb=mai->get_nb_mg_triangle(); |
53 |
|
|
for (int i=0;i<nbcoucheopt;i++) |
54 |
|
|
{ |
55 |
|
|
sprintf(mess," Passe numero %d",i+1); |
56 |
|
|
affiche(mess); |
57 |
|
|
int nb=optimise_maillage(); |
58 |
|
|
if ((nb==1)||(nb==oldnb)) i=nbcoucheopt; |
59 |
|
|
oldnb=nb; |
60 |
|
|
} |
61 |
|
|
return OK; |
62 |
|
|
} |
63 |
|
|
|
64 |
|
|
int MAILLEUR_STL::optimise_maillage(void) |
65 |
|
|
{ |
66 |
|
|
std::multimap<double,MG_TRIANGLE*> lsttriaopt; |
67 |
|
|
LISTE_MG_TRIANGLE::iterator it; |
68 |
|
|
for (MG_TRIANGLE* tri=mai->get_premier_triangle(it);tri!=NULL;tri=mai->get_suivant_triangle(it)) |
69 |
|
|
{ |
70 |
|
|
double val=OPERATEUR::qualite_triangle(tri->get_noeud1()->get_coord(),tri->get_noeud2()->get_coord(),tri->get_noeud3()->get_coord()); |
71 |
|
|
lsttriaopt.insert(std::pair<double,MG_TRIANGLE*>(val,tri)); |
72 |
|
|
tri->change_solution(val); |
73 |
|
|
} |
74 |
|
|
int ok=0; |
75 |
|
|
int compteur_iter=0; |
76 |
|
|
do |
77 |
|
|
{ |
78 |
|
|
compteur_iter++; |
79 |
|
|
if (lsttriaopt.begin()->first<qualmaxaopt) |
80 |
|
|
{ |
81 |
|
|
MG_TRIANGLE *tri=lsttriaopt.begin()->second; |
82 |
|
|
double crit1,crit2,crit3; |
83 |
|
|
double x1,y1,z1; |
84 |
|
|
double x2,y2,z2; |
85 |
|
|
double x3,y3,z3; |
86 |
|
|
int res1=bouge_point(tri->get_noeud1(),crit1,x1,y1,z1); |
87 |
|
|
int res2=bouge_point(tri->get_noeud2(),crit2,x2,y2,z2); |
88 |
|
|
int res3=bouge_point(tri->get_noeud3(),crit3,x3,y3,z3); |
89 |
|
|
double critmax=0; |
90 |
|
|
double nvx,nvy,nvz; |
91 |
|
|
MG_NOEUD* nno; |
92 |
|
|
if (res1==1) |
93 |
|
|
if (crit1>critmax) |
94 |
|
|
{critmax=crit1;nvx=x1;nvy=y1;nvz=z1;nno=tri->get_noeud1();} |
95 |
|
|
if (res2==1) |
96 |
|
|
if (crit2>critmax) |
97 |
|
|
{critmax=crit2;nvx=x2;nvy=y2;nvz=z2;nno=tri->get_noeud2();} |
98 |
|
|
if (res3==1) |
99 |
|
|
if (crit3>critmax) |
100 |
|
|
{critmax=crit3;nvx=x3;nvy=y3;nvz=z3;nno=tri->get_noeud3();} |
101 |
|
|
if (critmax>lsttriaopt.begin()->first) |
102 |
|
|
{ |
103 |
|
|
projete_point_sur_triangulation(nvx,nvy,nvz,nvx,nvy,nvz); |
104 |
|
|
nno->change_x(nvx); |
105 |
|
|
nno->change_y(nvy); |
106 |
|
|
nno->change_z(nvz); |
107 |
|
|
for (int i=0;i<nno->get_lien_triangle()->get_nb();i++) |
108 |
|
|
{ |
109 |
|
|
MG_TRIANGLE* tri=nno->get_lien_triangle()->get(i); |
110 |
|
|
double *xyz1=tri->get_noeud1()->get_coord(); |
111 |
|
|
double *xyz2=tri->get_noeud2()->get_coord(); |
112 |
|
|
double *xyz3=tri->get_noeud3()->get_coord(); |
113 |
|
|
double val=OPERATEUR::qualite_triangle(xyz1,xyz2,xyz3); |
114 |
|
|
std::multimap<double,MG_TRIANGLE*>:: iterator it=lsttriaopt.lower_bound(tri->get_solution()); |
115 |
|
|
int trouve=0; |
116 |
|
|
while (trouve==0) |
117 |
|
|
if (it->first>tri->get_solution()) trouve=-1; |
118 |
|
|
else if (it->second==tri) trouve=1; |
119 |
|
|
else it++; |
120 |
|
|
if (trouve==1) lsttriaopt.erase(it); |
121 |
|
|
//lsttriaopt.insert(std::pair<double,MG_TRIANGLE*>(val,tri)); |
122 |
|
|
//tri->change_solution(val); |
123 |
|
|
} |
124 |
|
|
|
125 |
|
|
} |
126 |
|
|
else lsttriaopt.erase(lsttriaopt.begin()); |
127 |
|
|
|
128 |
|
|
|
129 |
|
|
} |
130 |
|
|
else |
131 |
|
|
ok=1; |
132 |
|
|
} |
133 |
|
|
while (ok==0); |
134 |
|
|
char chaine[500]; |
135 |
|
|
sprintf(chaine," %d iterations effectuées",compteur_iter); |
136 |
|
|
affiche(chaine); |
137 |
|
|
return(compteur_iter); |
138 |
|
|
} |
139 |
|
|
|
140 |
|
|
|
141 |
|
|
void MAILLEUR_STL::adapte_carte(void) |
142 |
|
|
{ |
143 |
|
|
LISTE_MG_SEGMENT::iterator it; |
144 |
|
|
std::vector<double> lstraf; |
145 |
|
|
for (MG_SEGMENT* seg=mai->get_premier_segment(it);seg!=NULL;seg=mai->get_suivant_segment(it)) |
146 |
|
|
{ |
147 |
|
|
double val=metrique->calcul_distance_metrique(seg,pas); |
148 |
|
|
if (val<1.) |
149 |
|
|
{ |
150 |
|
|
double l=seg->get_longueur()/limite_discretisation/1.01; |
151 |
|
|
double *xyz=seg->get_noeud1()->get_coord(); |
152 |
|
|
lstraf.push_back(xyz[0]); |
153 |
|
|
lstraf.push_back(xyz[1]); |
154 |
|
|
lstraf.push_back(xyz[2]); |
155 |
|
|
lstraf.push_back(l); |
156 |
|
|
xyz=seg->get_noeud2()->get_coord(); |
157 |
|
|
lstraf.push_back(xyz[0]); |
158 |
|
|
lstraf.push_back(xyz[1]); |
159 |
|
|
lstraf.push_back(xyz[2]); |
160 |
|
|
lstraf.push_back(l); |
161 |
|
|
} |
162 |
|
|
} |
163 |
|
|
gesttmp=new MG_GESTIONNAIRE(); |
164 |
|
|
FCT_TAILLE_FEM_SOLUTION_GENERATEUR_GRADIENT* metriquetmp=new FCT_TAILLE_FEM_SOLUTION_GENERATEUR_GRADIENT(gesttmp,mai,metrique,2,nx,ny,nz,(char*)"carteadapte.sol",lstraf); |
165 |
|
|
metriquetmp->construit(); |
166 |
|
|
metrique2=metrique; |
167 |
|
|
metrique=metriquetmp; |
168 |
|
|
} |
169 |
|
|
|
170 |
|
|
|
171 |
|
|
|
172 |
|
|
void MAILLEUR_STL::prepare_projection() |
173 |
|
|
{ |
174 |
|
|
LISTE_MG_NOEUD::iterator it; |
175 |
|
|
MG_NOEUD* no=maiin->get_premier_noeud(it); |
176 |
|
|
BOITE_3D boite(no->get_boite_3D()); |
177 |
|
|
TPL_LISTE_ENTITE<MG_NOEUD*> lstini; |
178 |
|
|
for (MG_NOEUD* no=maiin->get_premier_noeud(it);no!=NULL;no=maiin->get_suivant_noeud(it)) |
179 |
|
|
{ |
180 |
|
|
boite=no->get_boite_3D()+boite; |
181 |
|
|
lstini.ajouter(no); |
182 |
|
|
} |
183 |
|
|
boite.change_grosseur(1.2); |
184 |
|
|
octree.initialiser(&lstini,1,boite.get_xmin(),boite.get_ymin(),boite.get_zmin(),boite.get_xmax(),boite.get_ymax(),boite.get_zmax()); |
185 |
|
|
LISTE_MG_TRIANGLE::iterator itt; |
186 |
|
|
for (MG_TRIANGLE* tri=maiin->get_premier_triangle(itt);tri!=NULL;tri=maiin->get_suivant_triangle(itt)) |
187 |
|
|
octree.inserer(tri); |
188 |
|
|
} |
189 |
|
|
|
190 |
|
|
|
191 |
|
|
|
192 |
|
|
void MAILLEUR_STL::determine_arete(void) |
193 |
|
|
{ |
194 |
|
|
LISTE_MG_SEGMENT::iterator it; |
195 |
|
|
int nbsegmentarete=0; |
196 |
|
|
for (MG_SEGMENT* seg=mai->get_premier_segment(it);seg!=NULL;seg=mai->get_suivant_segment(it)) |
197 |
|
|
{ |
198 |
|
|
int nbtri=seg->get_lien_triangle()->get_nb(); |
199 |
|
|
if (nbtri!=2) |
200 |
|
|
{ |
201 |
|
|
char chaine[500]; |
202 |
|
|
sprintf(chaine," Maillage STL invalide : segment à %d voisin : noeud 1 %lu noeud 2 %lu ",nbtri,seg->get_noeud1()->get_id(),seg->get_noeud2()->get_id()); |
203 |
|
|
affiche(chaine); |
204 |
|
|
} |
205 |
|
|
if (nbtri==2) |
206 |
|
|
{ |
207 |
|
|
MG_TRIANGLE *tri1=seg->get_lien_triangle()->get(0); |
208 |
|
|
MG_TRIANGLE *tri2=seg->get_lien_triangle()->get(1); |
209 |
|
|
double angle=get_angle_par_noeud<MG_NOEUD*>(tri1->get_noeud1(),tri1->get_noeud2(),tri1->get_noeud3(),tri2->get_noeud1(),tri2->get_noeud2(),tri2->get_noeud3()); |
210 |
|
|
if ((angle<M_PI-angle_arete) || (angle > M_PI+angle_arete)) |
211 |
|
|
{ |
212 |
|
|
seg->change_origine(MAGIC::ORIGINE::TRIANGULATION_ARETEORIGINE); |
213 |
|
|
seg->get_noeud1()->change_origine(MAGIC::ORIGINE::TRIANGULATION_ARETEORIGINE); |
214 |
|
|
seg->get_noeud2()->change_origine(MAGIC::ORIGINE::TRIANGULATION_ARETEORIGINE); |
215 |
|
|
nbsegmentarete++; |
216 |
|
|
} |
217 |
|
|
ajouter_seg_a_discretiser(seg); |
218 |
|
|
} |
219 |
|
|
} |
220 |
|
|
char mess[255]; |
221 |
|
|
sprintf(mess,(char*)" Nombre de segments aretes = %d",nbsegmentarete); |
222 |
|
|
affiche(mess); |
223 |
|
|
} |
224 |
|
|
|
225 |
|
|
|
226 |
|
|
void MAILLEUR_STL::calcul_nouveau_noeud_et_etoile(MG_SEGMENT* seg,double& x, double& y, double& z,OT_VECTEUR_3D &normale, TPL_LISTE_ENTITE<MG_TRIANGLE*> &listuniquetri,std::map<unsigned long,std::pair<MG_SEGMENT*,int> > &lstsegment) |
227 |
|
|
{ |
228 |
|
|
MG_TRIANGLE *tri1=seg->get_lien_triangle()->get(0); |
229 |
|
|
MG_TRIANGLE *tri2=seg->get_lien_triangle()->get(1); |
230 |
|
|
double xyz1[3],xyz2[3]; |
231 |
|
|
tri1->normal(xyz1); |
232 |
|
|
tri2->normal(xyz2); |
233 |
|
|
OT_VECTEUR_3D nor1(xyz1); |
234 |
|
|
OT_VECTEUR_3D nor2(xyz2); |
235 |
|
|
normale=0.5*nor1+0.5*nor2; |
236 |
|
|
MG_NOEUD* no1=seg->get_noeud1(); |
237 |
|
|
MG_NOEUD* no2=seg->get_noeud2(); |
238 |
|
|
x=0.5*(no1->get_x()+no2->get_x()); |
239 |
|
|
y=0.5*(no1->get_y()+no2->get_y()); |
240 |
|
|
z=0.5*(no1->get_z()+no2->get_z()); |
241 |
|
|
listuniquetri.ajouter(tri1); |
242 |
|
|
listuniquetri.ajouter(tri2); |
243 |
|
|
for (int i=0;i<listuniquetri.get_nb();i++) |
244 |
|
|
{ |
245 |
|
|
MG_TRIANGLE* tri=listuniquetri.get(i); |
246 |
|
|
for (int cote=1;cote<4;cote++) |
247 |
|
|
{ |
248 |
|
|
MG_TRIANGLE* triv=get_voisin(tri,cote); |
249 |
|
|
if (!(listuniquetri.est_dans_la_liste(triv))) |
250 |
|
|
if (triv!=NULL) |
251 |
|
|
{ |
252 |
|
|
double xyzv[3]; |
253 |
|
|
triv->normal(xyzv); |
254 |
|
|
OT_VECTEUR_3D norv(xyzv); |
255 |
|
|
if (norv*normale>cos(angle_limite)) |
256 |
|
|
{ |
257 |
|
|
bool res=respecte_delaunay(x,y,z,triv); |
258 |
|
|
if (!res) |
259 |
|
|
listuniquetri.ajouter(triv); |
260 |
|
|
} |
261 |
|
|
} |
262 |
|
|
} |
263 |
|
|
|
264 |
|
|
|
265 |
|
|
|
266 |
|
|
} |
267 |
|
|
for (int i=0;i<listuniquetri.get_nb();i++) |
268 |
|
|
{ |
269 |
|
|
MG_TRIANGLE* tri=listuniquetri.get(i); |
270 |
|
|
std::map<unsigned long,std::pair<MG_SEGMENT*,int> >::iterator ptmp; |
271 |
|
|
MG_SEGMENT* seg=tri->get_segment1(); |
272 |
|
|
ptmp=lstsegment.find(seg->get_id()); |
273 |
|
|
if (ptmp==lstsegment.end()) lstsegment[seg->get_id()]=std::pair<MG_SEGMENT*,int>(seg,1); |
274 |
|
|
else ptmp->second.second=ptmp->second.second+1; |
275 |
|
|
seg=tri->get_segment2(); |
276 |
|
|
ptmp=lstsegment.find(seg->get_id()); |
277 |
|
|
if (ptmp==lstsegment.end()) lstsegment[seg->get_id()]=std::pair<MG_SEGMENT*,int>(seg,1); |
278 |
|
|
else ptmp->second.second=ptmp->second.second+1; |
279 |
|
|
seg=tri->get_segment3(); |
280 |
|
|
ptmp=lstsegment.find(seg->get_id()); |
281 |
|
|
if (ptmp==lstsegment.end()) lstsegment[seg->get_id()]=std::pair<MG_SEGMENT*,int>(seg,1); |
282 |
|
|
else ptmp->second.second=ptmp->second.second+1; |
283 |
|
|
} |
284 |
|
|
|
285 |
|
|
|
286 |
|
|
|
287 |
|
|
projete_point_sur_triangulation(x,y,z,x,y,z); |
288 |
|
|
|
289 |
|
|
|
290 |
|
|
bool convergecoquille; |
291 |
|
|
|
292 |
|
|
do |
293 |
|
|
{ |
294 |
|
|
convergecoquille=true; |
295 |
|
|
TPL_LISTE_ENTITE<MG_SEGMENT*> contour; |
296 |
|
|
for (std::map<unsigned long,std::pair<MG_SEGMENT*,int> >::iterator ptmp=lstsegment.begin();ptmp!=lstsegment.end();ptmp++) |
297 |
|
|
if (ptmp->second.second==1) |
298 |
|
|
{ |
299 |
|
|
MG_SEGMENT* seg=ptmp->second.first; |
300 |
|
|
contour.ajouter(seg); |
301 |
|
|
} |
302 |
|
|
|
303 |
|
|
for (int i=0;i<contour.get_nb();i++) |
304 |
|
|
{ |
305 |
|
|
MG_SEGMENT* seg=contour.get(i); |
306 |
|
|
MG_TRIANGLE *triin,*triext; |
307 |
|
|
if (listuniquetri.est_dans_la_liste(seg->get_lien_triangle()->get(0))) |
308 |
|
|
{ |
309 |
|
|
triin=seg->get_lien_triangle()->get(0); |
310 |
|
|
triext=seg->get_lien_triangle()->get(1); |
311 |
|
|
} |
312 |
|
|
else |
313 |
|
|
{ |
314 |
|
|
triin=seg->get_lien_triangle()->get(1); |
315 |
|
|
triext=seg->get_lien_triangle()->get(0); |
316 |
|
|
} |
317 |
|
|
MG_NOEUD* no1=seg->get_noeud1(); |
318 |
|
|
MG_NOEUD* no2=seg->get_noeud2(); |
319 |
|
|
int sens=-1; |
320 |
|
|
if ((triin->get_noeud1()==no1) && (triin->get_noeud2()==no2)) sens=1; |
321 |
|
|
if ((triin->get_noeud2()==no1) && (triin->get_noeud3()==no2)) sens=1; |
322 |
|
|
if ((triin->get_noeud3()==no1) && (triin->get_noeud1()==no2)) sens=1; |
323 |
|
|
double *xyz1,*xyz2; |
324 |
|
|
if (sens==-1) |
325 |
|
|
{ |
326 |
|
|
xyz1=no2->get_coord(); |
327 |
|
|
xyz2=no1->get_coord(); |
328 |
|
|
} |
329 |
|
|
else |
330 |
|
|
{ |
331 |
|
|
xyz1=no1->get_coord(); |
332 |
|
|
xyz2=no2->get_coord(); |
333 |
|
|
} |
334 |
|
|
double xyz3[3]={x,y,z}; |
335 |
|
|
OT_VECTEUR_3D vec1(xyz1,xyz2); |
336 |
|
|
OT_VECTEUR_3D vec2(xyz1,xyz3); |
337 |
|
|
OT_VECTEUR_3D nor=vec1&vec2; |
338 |
|
|
nor.norme(); |
339 |
|
|
double xyzin[3]; |
340 |
|
|
triin->normal(xyzin); |
341 |
|
|
OT_VECTEUR_3D norin(xyzin); |
342 |
|
|
if (nor*norin<0.) |
343 |
|
|
{ |
344 |
|
|
affiche("etoile non conforme"); |
345 |
|
|
listuniquetri.ajouter(triext); |
346 |
|
|
std::map<unsigned long,std::pair<MG_SEGMENT*,int> >::iterator ptmp; |
347 |
|
|
MG_SEGMENT* seg=triext->get_segment1(); |
348 |
|
|
ptmp=lstsegment.find(seg->get_id()); |
349 |
|
|
ptmp=lstsegment.find(seg->get_id()); |
350 |
|
|
if (ptmp==lstsegment.end()) lstsegment[seg->get_id()]=std::pair<MG_SEGMENT*,int>(seg,1); |
351 |
|
|
else ptmp->second.second=ptmp->second.second+1; |
352 |
|
|
seg=triext->get_segment2(); |
353 |
|
|
ptmp=lstsegment.find(seg->get_id()); |
354 |
|
|
if (ptmp==lstsegment.end()) lstsegment[seg->get_id()]=std::pair<MG_SEGMENT*,int>(seg,1); |
355 |
|
|
else ptmp->second.second=ptmp->second.second+1; |
356 |
|
|
seg=triext->get_segment3(); |
357 |
|
|
ptmp=lstsegment.find(seg->get_id()); |
358 |
|
|
if (ptmp==lstsegment.end()) lstsegment[seg->get_id()]=std::pair<MG_SEGMENT*,int>(seg,1); |
359 |
|
|
else ptmp->second.second=ptmp->second.second+1; |
360 |
|
|
convergecoquille=false; |
361 |
|
|
} |
362 |
|
|
} |
363 |
|
|
} |
364 |
|
|
while (convergecoquille==false); |
365 |
|
|
|
366 |
|
|
/* |
367 |
|
|
MG_SEGMENT* segcourant=contour.get(0); |
368 |
|
|
MG_NOEUD* n1=segcourant->get_noeud1(); |
369 |
|
|
MG_NOEUD* n2=segcourant->get_noeud2(); |
370 |
|
|
MG_NOEUD* ns; |
371 |
|
|
MG_NOEUD* premier=n2; |
372 |
|
|
|
373 |
|
|
do |
374 |
|
|
{ |
375 |
|
|
MG_SEGMENT* segsuivant=NULL; |
376 |
|
|
int i=0; |
377 |
|
|
while (segsuivant==NULL) |
378 |
|
|
{ |
379 |
|
|
if (contour.get(i)!=segcourant) |
380 |
|
|
if ((contour.get(i)->get_noeud1()==n2) || ((contour.get(i)->get_noeud2()==n2))) |
381 |
|
|
{ |
382 |
|
|
segsuivant=contour.get(i); |
383 |
|
|
if (segsuivant->get_noeud1()==n2) ns=segsuivant->get_noeud2(); else ns=segsuivant->get_noeud1(); |
384 |
|
|
} |
385 |
|
|
i++; |
386 |
|
|
} |
387 |
|
|
OT_VECTEUR_3D vecbase(n1->get_coord(),n2->get_coord()); |
388 |
|
|
OT_VECTEUR_3D vecsuiv(n2->get_coord(),ns->get_coord()); |
389 |
|
|
OT_VECTEUR_3D vecori(n1->get_coord(),ns->get_coord()); |
390 |
|
|
OT_VECTEUR_3D sens(x-0.5*(n1->get_x()+n2->get_x()),y-0.5*(n1->get_y()+n2->get_y()),z-0.5*(n1->get_z()+n2->get_z())); |
391 |
|
|
vecbase.norme(); |
392 |
|
|
vecsuiv.norme(); |
393 |
|
|
vecori.norme(); |
394 |
|
|
sens.norme(); |
395 |
|
|
OT_VECTEUR_3D norm=vecbase&sens; |
396 |
|
|
sens=norm&vecbase; |
397 |
|
|
double angle=acos((-vecbase)*vecsuiv); |
398 |
|
|
double signe=vecori*sens; |
399 |
|
|
if (signe<0.) angle=2*M_PI-angle; |
400 |
|
|
if (angle>M_PI) |
401 |
|
|
affiche("etoile concave"); |
402 |
|
|
segcourant=segsuivant; |
403 |
|
|
n1=n2; |
404 |
|
|
n2=ns; |
405 |
|
|
} |
406 |
|
|
while (n2!=premier); |
407 |
|
|
*/ |
408 |
|
|
} |
409 |
|
|
|
410 |
|
|
int MAILLEUR_STL::bouge_point(MG_NOEUD* mg_noeud,double& crit,double& x,double& y, double& z) |
411 |
|
|
{ |
412 |
|
|
if (mg_noeud->get_origine()==MAGIC::ORIGINE::TRIANGULATION_ARETEORIGINE) |
413 |
|
|
return 0; |
414 |
|
|
TPL_MAP_ENTITE<MG_NOEUD*> lstnoeud; |
415 |
|
|
double critdep=1.; |
416 |
|
|
for (int i=0;i<mg_noeud->get_lien_triangle()->get_nb();i++) |
417 |
|
|
{ |
418 |
|
|
MG_TRIANGLE* tri=mg_noeud->get_lien_triangle()->get(i); |
419 |
|
|
double val=OPERATEUR::qualite_triangle(tri->get_noeud1()->get_coord(),tri->get_noeud2()->get_coord(),tri->get_noeud3()->get_coord()); |
420 |
|
|
if (val<critdep) critdep=val; |
421 |
|
|
if (tri->get_noeud1()!=mg_noeud) lstnoeud.ajouter(tri->get_noeud1()); |
422 |
|
|
if (tri->get_noeud2()!=mg_noeud) lstnoeud.ajouter(tri->get_noeud2()); |
423 |
|
|
if (tri->get_noeud3()!=mg_noeud) lstnoeud.ajouter(tri->get_noeud3()); |
424 |
|
|
} |
425 |
|
|
TPL_MAP_ENTITE<MG_NOEUD*>::ITERATEUR it; |
426 |
|
|
double xi=0.; |
427 |
|
|
double yi=0.; |
428 |
|
|
double zi=0.; |
429 |
|
|
for (MG_NOEUD* no=lstnoeud.get_premier(it);no!=NULL;no=lstnoeud.get_suivant(it)) |
430 |
|
|
{ |
431 |
|
|
xi=xi+no->get_x(); |
432 |
|
|
yi=yi+no->get_y(); |
433 |
|
|
zi=zi+no->get_z(); |
434 |
|
|
} |
435 |
|
|
xi=xi/lstnoeud.get_nb(); |
436 |
|
|
yi=yi/lstnoeud.get_nb(); |
437 |
|
|
zi=zi/lstnoeud.get_nb(); |
438 |
|
|
OT_VECTEUR_3D dir(xi-mg_noeud->get_x(),yi-mg_noeud->get_y(),zi-mg_noeud->get_z()); |
439 |
|
|
if (dir.get_longueur()<1e-10) return 0; |
440 |
|
|
double alpha=0.1; |
441 |
|
|
bool converge=false; |
442 |
|
|
double critencours=critdep; |
443 |
|
|
int passe=0; |
444 |
|
|
while (converge==false) |
445 |
|
|
{ |
446 |
|
|
double xyz[3]; |
447 |
|
|
xyz[0]=mg_noeud->get_x()+alpha*dir.get_x(); |
448 |
|
|
xyz[1]=mg_noeud->get_y()+alpha*dir.get_y(); |
449 |
|
|
xyz[2]=mg_noeud->get_z()+alpha*dir.get_z(); |
450 |
|
|
double critcourant=1.; |
451 |
|
|
for (int i=0;i<mg_noeud->get_lien_triangle()->get_nb();i++) |
452 |
|
|
{ |
453 |
|
|
MG_TRIANGLE* tri=mg_noeud->get_lien_triangle()->get(i); |
454 |
|
|
double *xyz1=tri->get_noeud1()->get_coord(); |
455 |
|
|
double *xyz2=tri->get_noeud2()->get_coord(); |
456 |
|
|
double *xyz3=tri->get_noeud3()->get_coord(); |
457 |
|
|
if (tri->get_noeud1()==mg_noeud) xyz1=xyz; |
458 |
|
|
if (tri->get_noeud2()==mg_noeud) xyz2=xyz; |
459 |
|
|
if (tri->get_noeud3()==mg_noeud) xyz3=xyz; |
460 |
|
|
double val=OPERATEUR::qualite_triangle(xyz1,xyz2,xyz3); |
461 |
|
|
if (val<critcourant) critcourant=val; |
462 |
|
|
} |
463 |
|
|
if (critencours>critcourant) |
464 |
|
|
{ |
465 |
|
|
converge=true; |
466 |
|
|
return passe; |
467 |
|
|
} |
468 |
|
|
else |
469 |
|
|
{ |
470 |
|
|
alpha=alpha+0.1; |
471 |
|
|
x=xyz[0]; |
472 |
|
|
y=xyz[1]; |
473 |
|
|
z=xyz[2]; |
474 |
|
|
critencours=critcourant; |
475 |
|
|
crit=critencours; |
476 |
|
|
passe=1; |
477 |
|
|
} |
478 |
|
|
|
479 |
|
|
} |
480 |
|
|
return 0; |
481 |
|
|
} |
482 |
|
|
|
483 |
|
|
void MAILLEUR_STL::maillage_et_segadiscretiser_update(MG_SEGMENT* segbase,double x, double y, double z, OT_VECTEUR_3D normale,TPL_LISTE_ENTITE<MG_TRIANGLE *>& listuniquetri, std::map<unsigned long, std::pair<MG_SEGMENT *, int> >& lstsegment) |
484 |
|
|
{ |
485 |
|
|
projete_point_sur_triangulation(x,y,z,x,y,z); |
486 |
|
|
MG_NOEUD *no=mai->ajouter_mg_noeud(NULL,x,y,z,segbase->get_origine()); |
487 |
|
|
MG_NOEUD* nobase1=NULL; |
488 |
|
|
MG_NOEUD* nobase2=NULL; |
489 |
|
|
if (segbase->get_origine()==MAGIC::ORIGINE::TRIANGULATION_ARETEORIGINE) |
490 |
|
|
{ |
491 |
|
|
nobase1=segbase->get_noeud1(); |
492 |
|
|
nobase2=segbase->get_noeud2(); |
493 |
|
|
} |
494 |
|
|
for (std::map<unsigned long,std::pair<MG_SEGMENT*,int> >::iterator ptmp=lstsegment.begin();ptmp!=lstsegment.end();ptmp++) |
495 |
|
|
if (ptmp->second.second==2) |
496 |
|
|
supprimer_seg_a_discretiser(ptmp->second.first); |
497 |
|
|
for (int i=0;i<listuniquetri.get_nb();i++) |
498 |
|
|
{ |
499 |
|
|
MG_TRIANGLE* tri=listuniquetri.get(i); |
500 |
|
|
mai->supprimer_mg_triangleid(tri->get_id()); |
501 |
|
|
} |
502 |
|
|
for (std::map<unsigned long,std::pair<MG_SEGMENT*,int> >::iterator ptmp=lstsegment.begin();ptmp!=lstsegment.end();ptmp++) |
503 |
|
|
if (ptmp->second.second==1) |
504 |
|
|
{ |
505 |
|
|
MG_SEGMENT* seg=ptmp->second.first; |
506 |
|
|
MG_SEGMENT* mgsegment1=mai->get_mg_segment(seg->get_noeud1()->get_id(),seg->get_noeud2()->get_id()); |
507 |
|
|
MG_SEGMENT* mgsegment2=mai->get_mg_segment(seg->get_noeud2()->get_id(),no->get_id()); |
508 |
|
|
MG_SEGMENT* mgsegment3=mai->get_mg_segment(no->get_id(),seg->get_noeud1()->get_id()); |
509 |
|
|
if (mgsegment1==NULL) |
510 |
|
|
{ |
511 |
|
|
mgsegment1=mai->ajouter_mg_segment(NULL,seg->get_noeud1(),seg->get_noeud2(),MAGIC::ORIGINE::TRIANGULATION); |
512 |
|
|
ajouter_seg_a_discretiser(mgsegment1); |
513 |
|
|
} |
514 |
|
|
if (mgsegment2==NULL) |
515 |
|
|
{ |
516 |
|
|
int origine=MAGIC::ORIGINE::TRIANGULATION; |
517 |
|
|
if ((seg->get_noeud2()==nobase1)|| (seg->get_noeud2()==nobase2)) |
518 |
|
|
origine=MAGIC::ORIGINE::TRIANGULATION_ARETEORIGINE; |
519 |
|
|
mgsegment2=mai->ajouter_mg_segment(NULL,seg->get_noeud2(),no,origine); |
520 |
|
|
ajouter_seg_a_discretiser(mgsegment2); |
521 |
|
|
} |
522 |
|
|
if (mgsegment3==NULL) |
523 |
|
|
{ |
524 |
|
|
int origine=MAGIC::ORIGINE::TRIANGULATION; |
525 |
|
|
if ((seg->get_noeud1()==nobase1)|| (seg->get_noeud1()==nobase2)) |
526 |
|
|
origine=MAGIC::ORIGINE::TRIANGULATION_ARETEORIGINE; |
527 |
|
|
mgsegment3=mai->ajouter_mg_segment(NULL,no,seg->get_noeud1(),origine); |
528 |
|
|
ajouter_seg_a_discretiser(mgsegment3); |
529 |
|
|
} |
530 |
|
|
MG_TRIANGLE* nvtri=new MG_TRIANGLE(NULL,seg->get_noeud1(),seg->get_noeud2(),no,mgsegment1,mgsegment2,mgsegment3,MAGIC::ORIGINE::TRIANGULATION); |
531 |
|
|
mai->ajouter_mg_triangle(nvtri); |
532 |
|
|
double xyz[3]; |
533 |
|
|
nvtri->normal(xyz); |
534 |
|
|
OT_VECTEUR_3D nvnor(xyz); |
535 |
|
|
if (nvnor*normale<0) |
536 |
|
|
nvtri->inverse_sens(); |
537 |
|
|
|
538 |
|
|
MG_TRIANGLE* tri1=get_voisin(nvtri,1); |
539 |
|
|
MG_TRIANGLE* tri2=get_voisin(nvtri,2); |
540 |
|
|
MG_TRIANGLE* tri3=get_voisin(nvtri,3); |
541 |
|
|
double nor[3],nor1[3],nor2[3],nor3[3]; |
542 |
|
|
nvtri->normal(nor); |
543 |
|
|
OT_VECTEUR_3D vnor(nor); |
544 |
|
|
if (tri1!=NULL) |
545 |
|
|
{ |
546 |
|
|
tri1->normal(nor1); |
547 |
|
|
OT_VECTEUR_3D vnor1(nor1); |
548 |
|
|
if (vnor*vnor1<0.) |
549 |
|
|
|
550 |
|
|
affiche("Triangle retourne v1"); |
551 |
|
|
|
552 |
|
|
} |
553 |
|
|
if (tri2!=NULL) |
554 |
|
|
{ |
555 |
|
|
tri2->normal(nor2); |
556 |
|
|
OT_VECTEUR_3D vnor2(nor2); |
557 |
|
|
if (vnor*vnor2<0.) |
558 |
|
|
affiche("Triangle retourne v2"); |
559 |
|
|
} |
560 |
|
|
if (tri3!=NULL) |
561 |
|
|
{ |
562 |
|
|
tri3->normal(nor3); |
563 |
|
|
OT_VECTEUR_3D vnor3(nor3); |
564 |
|
|
if (vnor*vnor3<0.) |
565 |
|
|
affiche("Triangle retourne v3"); |
566 |
|
|
} |
567 |
|
|
} |
568 |
|
|
} |
569 |
|
|
|
570 |
|
|
|
571 |
|
|
void MAILLEUR_STL::cree_maillage() |
572 |
|
|
{ |
573 |
|
|
int ok=0; |
574 |
|
|
int compteur_iter=0; |
575 |
|
|
do |
576 |
|
|
{ |
577 |
|
|
compteur_iter++; |
578 |
|
|
if (lstsegadiscretiser.begin()->first>limite_discretisation) |
579 |
|
|
{ |
580 |
|
|
MG_SEGMENT* seg=lstsegadiscretiser.begin()->second; |
581 |
|
|
double x,y,z; |
582 |
|
|
OT_VECTEUR_3D normale; |
583 |
|
|
TPL_LISTE_ENTITE<MG_TRIANGLE*> listtrietoile; |
584 |
|
|
std::map<unsigned long,std::pair<MG_SEGMENT*,int> > lstsegmentetoile; |
585 |
|
|
calcul_nouveau_noeud_et_etoile(seg,x,y,z,normale,listtrietoile,lstsegmentetoile); |
586 |
|
|
maillage_et_segadiscretiser_update(seg,x,y,z,normale,listtrietoile,lstsegmentetoile); |
587 |
|
|
} |
588 |
|
|
else |
589 |
|
|
ok=1; |
590 |
|
|
} |
591 |
|
|
while (ok==0); |
592 |
|
|
char chaine[500]; |
593 |
|
|
sprintf(chaine," %d iterations effectuées",compteur_iter); |
594 |
|
|
affiche(chaine); |
595 |
|
|
} |
596 |
|
|
|
597 |
|
|
|
598 |
|
|
|
599 |
|
|
|
600 |
|
|
bool MAILLEUR_STL::respecte_delaunay(double x, double y, double z, MG_TRIANGLE* tri) |
601 |
|
|
{ |
602 |
|
|
OT_VECTEUR_3D vec1(tri->get_noeud1()->get_coord(),tri->get_noeud2()->get_coord()); |
603 |
|
|
OT_VECTEUR_3D vec2(tri->get_noeud1()->get_coord(),tri->get_noeud3()->get_coord()); |
604 |
|
|
OT_VECTEUR_3D vec3=vec1&vec2; |
605 |
|
|
vec1.norme(); |
606 |
|
|
vec3.norme(); |
607 |
|
|
vec2=vec3&vec1; |
608 |
|
|
OT_MATRICE_3D base(vec1,vec2,vec3); |
609 |
|
|
OT_MATRICE_3D baset=base.transpose();; |
610 |
|
|
OT_VECTEUR_3D pt1(tri->get_noeud1()->get_coord()); |
611 |
|
|
OT_VECTEUR_3D pt2(tri->get_noeud1()->get_coord(),tri->get_noeud2()->get_coord()); |
612 |
|
|
OT_VECTEUR_3D pt3(tri->get_noeud1()->get_coord(),tri->get_noeud3()->get_coord()); |
613 |
|
|
OT_VECTEUR_3D pt1l(0.,0.,0.); |
614 |
|
|
OT_VECTEUR_3D pt2l=baset*pt2; |
615 |
|
|
OT_VECTEUR_3D pt3l=baset*pt3; |
616 |
|
|
|
617 |
|
|
OT_VECTEUR_3D colx(pt1l.get_x(),pt2l.get_x(),pt3l.get_x()); |
618 |
|
|
OT_VECTEUR_3D coly(pt1l.get_y(),pt2l.get_y(),pt3l.get_y()); |
619 |
|
|
OT_VECTEUR_3D colz(1.,1.,1.); |
620 |
|
|
OT_VECTEUR_3D colx2y2(pt1l.get_x()*pt1l.get_x()+pt1l.get_y()*pt1l.get_y(),pt2l.get_x()*pt2l.get_x()+pt2l.get_y()*pt2l.get_y(),pt3l.get_x()*pt3l.get_x()+pt3l.get_y()*pt3l.get_y()); |
621 |
|
|
OT_MATRICE_3D sys1(colx,coly,colz); |
622 |
|
|
double det=2.*sys1.get_determinant(); |
623 |
|
|
OT_MATRICE_3D sys2(colx2y2,coly,colz); |
624 |
|
|
double xcl=sys2.get_determinant()/det; |
625 |
|
|
OT_MATRICE_3D sys3(colx2y2,colx,colz); |
626 |
|
|
double ycl=-sys3.get_determinant()/det; |
627 |
|
|
OT_VECTEUR_3D centrel(xcl,ycl,0.); |
628 |
|
|
OT_VECTEUR_3D centre=pt1+base*centrel; |
629 |
|
|
|
630 |
|
|
OT_VECTEUR_3D r1(centre.get_xyz(),tri->get_noeud1()->get_coord()); |
631 |
|
|
double rayon=r1.get_longueur(); |
632 |
|
|
OT_VECTEUR_3D dist(x,y,z); |
633 |
|
|
dist=dist-centre; |
634 |
|
|
bool rep=true; |
635 |
|
|
if (dist.get_longueur()<rayon) |
636 |
|
|
rep=false; |
637 |
|
|
return rep; |
638 |
|
|
} |
639 |
|
|
|
640 |
|
|
|
641 |
|
|
|
642 |
|
|
void MAILLEUR_STL::projete_point_sur_triangulation(double x, double y, double z, double& nvx, double& nvy, double& nvz) |
643 |
|
|
{ |
644 |
|
|
double mat[9]; |
645 |
|
|
double xyz[3]={x,y,z}; |
646 |
|
|
metrique->evaluer(xyz,mat); |
647 |
|
|
double dref=1./sqrt(mat[0]); |
648 |
|
|
TPL_MAP_ENTITE<MG_TRIANGLE*> lst; |
649 |
|
|
while (lst.get_nb()==0) |
650 |
|
|
{ |
651 |
|
|
octree.rechercher(x,y,z,dref,lst); |
652 |
|
|
dref=dref*1.05; |
653 |
|
|
} |
654 |
|
|
MG_MAILLAGE_OUTILS ot; |
655 |
|
|
TPL_MAP_ENTITE<MG_TRIANGLE*>::ITERATEUR it; |
656 |
|
|
double dis=1e308; |
657 |
|
|
for (MG_TRIANGLE* tri=lst.get_premier(it);tri!=NULL;tri=lst.get_suivant(it)) |
658 |
|
|
{ |
659 |
|
|
double xt,yt,zt; |
660 |
|
|
ot.projetedansletriangle(tri,x,y,z,xt,yt,zt); |
661 |
|
|
OT_VECTEUR_3D vec(x-xt,y-yt,z-zt); |
662 |
|
|
double l=vec.get_longueur(); |
663 |
|
|
if (l<dis) |
664 |
|
|
{ |
665 |
|
|
dis=l; |
666 |
|
|
nvx=xt; |
667 |
|
|
nvy=yt; |
668 |
|
|
nvz=zt; |
669 |
|
|
} |
670 |
|
|
} |
671 |
|
|
} |
672 |
|
|
|
673 |
|
|
|
674 |
|
|
|
675 |
|
|
void MAILLEUR_STL::change_angle_arete(double val) |
676 |
|
|
{ |
677 |
|
|
angle_arete=val; |
678 |
|
|
} |
679 |
|
|
|
680 |
|
|
|
681 |
|
|
double MAILLEUR_STL::get_angle_arete() |
682 |
|
|
{ |
683 |
|
|
return angle_arete; |
684 |
|
|
} |
685 |
|
|
|
686 |
|
|
MG_TRIANGLE * MAILLEUR_STL::get_voisin(MG_TRIANGLE* tri, int cote) |
687 |
|
|
{ |
688 |
|
|
MG_SEGMENT* seg; |
689 |
|
|
if (cote==1) seg=tri->get_segment1(); |
690 |
|
|
if (cote==2) seg=tri->get_segment2(); |
691 |
|
|
if (cote==3) seg=tri->get_segment3(); |
692 |
|
|
if (seg->get_origine()==MAGIC::ORIGINE::TRIANGULATION_ARETEORIGINE) return NULL; |
693 |
|
|
if (seg->get_lien_triangle()->get_nb()!=2) return NULL; |
694 |
|
|
MG_TRIANGLE* tri1=seg->get_lien_triangle()->get(0); |
695 |
|
|
MG_TRIANGLE* tri2=seg->get_lien_triangle()->get(1); |
696 |
|
|
if (tri1==tri) return tri2; |
697 |
|
|
return tri1; |
698 |
|
|
} |
699 |
|
|
|
700 |
|
|
void MAILLEUR_STL::ajouter_seg_a_discretiser(MG_SEGMENT* seg) |
701 |
|
|
{ |
702 |
|
|
double l=metrique->calcul_distance_metrique(seg,pas); |
703 |
|
|
seg->change_distance_metrique(l); |
704 |
|
|
lstsegadiscretiser.insert(std::pair<double,MG_SEGMENT*>(l,seg)); |
705 |
|
|
} |
706 |
|
|
|
707 |
|
|
void MAILLEUR_STL::supprimer_seg_a_discretiser(MG_SEGMENT* seg) |
708 |
|
|
{ |
709 |
|
|
double l; |
710 |
|
|
seg->get_distance_metrique(&l); |
711 |
|
|
std::multimap<double,MG_SEGMENT*,std::greater<double > >:: iterator it=lstsegadiscretiser.lower_bound(l); |
712 |
|
|
while (it->second!=seg) |
713 |
|
|
it++; |
714 |
|
|
lstsegadiscretiser.erase(it); |
715 |
|
|
} |
716 |
|
|
|
717 |
|
|
void MAILLEUR_STL::change_pas(int val) |
718 |
|
|
{ |
719 |
|
|
pas=val; |
720 |
|
|
} |
721 |
|
|
|
722 |
|
|
void MAILLEUR_STL::change_nbpasseoptimisation(int nb) |
723 |
|
|
{ |
724 |
|
|
nbcoucheopt=nb; |
725 |
|
|
} |
726 |
|
|
|
727 |
|
|
|
728 |
|
|
void MAILLEUR_STL::change_nx(int val) |
729 |
|
|
{ |
730 |
|
|
nx=val; |
731 |
|
|
} |
732 |
|
|
|
733 |
|
|
|
734 |
|
|
void MAILLEUR_STL::change_ny(int val) |
735 |
|
|
{ |
736 |
|
|
ny=val; |
737 |
|
|
} |
738 |
|
|
|
739 |
|
|
|
740 |
|
|
void MAILLEUR_STL::change_nz(int val) |
741 |
|
|
{ |
742 |
|
|
nz=val; |
743 |
|
|
} |
744 |
|
|
|
745 |
|
|
void MAILLEUR_STL::change_nxnynz(int nvx, int nvy, int nvz) |
746 |
|
|
{ |
747 |
|
|
nx=nvx; |
748 |
|
|
ny=nvy; |
749 |
|
|
nz=nvz; |
750 |
|
|
} |
751 |
|
|
|
752 |
|
|
|
753 |
|
|
void MAILLEUR_STL::change_qualmaxaoptimiser(double val) |
754 |
|
|
{ |
755 |
|
|
qualmaxaopt=val; |
756 |
|
|
} |