1 |
/*****************************************************************
|
2 |
|
3 |
o3d.cpp Type:Func
|
4 |
|
5 |
Optimisateur de maillage 3D
|
6 |
|
7 |
Date de creation : 16-4-1999 16 :18 :57
|
8 |
Derniere version : 16-4-1999 16 :18 :57
|
9 |
|
10 |
Vincent FRANCOIS
|
11 |
|
12 |
*****************************************************************/
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
/**************************/
|
19 |
/* include */
|
20 |
#include <stdio.h>
|
21 |
#include <math.h>
|
22 |
#include "const.h"
|
23 |
#include "memoire.h"
|
24 |
#include "struct.h"
|
25 |
#include "struct3d.h"
|
26 |
#include "prototype.h"
|
27 |
|
28 |
/**************************/
|
29 |
/* variables globales */
|
30 |
extern struct environnement env;
|
31 |
extern struct s_mesh *mesh;
|
32 |
int tab_solution[7][1430][8];
|
33 |
int tab_face[7][120][3];
|
34 |
|
35 |
extern int test_front(void);
|
36 |
|
37 |
/**************************/
|
38 |
/* programme principal */
|
39 |
|
40 |
|
41 |
void o3d(void)
|
42 |
{
|
43 |
int i,j;
|
44 |
int cas,num,fin,fin2;
|
45 |
struct s_tetra *tet,*tet1,*tmp,*tmp2;
|
46 |
struct s_noeud *no[4];
|
47 |
float coord[12];
|
48 |
float crit[6],crit_avant,crit_opt,nv_crit;
|
49 |
struct coquille coque[6];
|
50 |
float vec12[4],vec13[4],vec14[4],vec23[4],vec24[4],vec34[4];
|
51 |
float l1,l2,l3,l4,l5,l6;
|
52 |
int k;
|
53 |
int iordre[6];
|
54 |
float ordre_exec[6];
|
55 |
int nbclass;
|
56 |
|
57 |
for (i=0;i<mesh->nb_tetra;i++)
|
58 |
{
|
59 |
tet=ADRESSE(i,tetra,mesh->);
|
60 |
tet->opt=0;
|
61 |
}
|
62 |
o3d_data();
|
63 |
o3d_data2();
|
64 |
aff_text(M3D_OPTI1);
|
65 |
for (i=0;i<env.opti;i++)
|
66 |
{
|
67 |
fin=0;
|
68 |
while (fin==0)
|
69 |
{
|
70 |
voir();
|
71 |
tet=mesh->tete_tetra[i];
|
72 |
if (tet==NULL) {fin=1;fin2=1;} else fin2=0;
|
73 |
while (fin2==0)
|
74 |
{
|
75 |
if ((tet->opt!=0)||(tet->etat!=ACTIF))
|
76 |
{
|
77 |
tet=tet->suivant;
|
78 |
if (tet==NULL) {fin=1;fin2=1;}
|
79 |
}
|
80 |
else fin2=1;
|
81 |
}
|
82 |
if (fin==1) continue;
|
83 |
if (tet->etat!=ACTIF) continue;
|
84 |
/* premier essai bouge de point */
|
85 |
crit_avant=tet->crit;
|
86 |
crit[0]=-1.;
|
87 |
crit[1]=-1.;
|
88 |
crit[2]=-1.;
|
89 |
crit[3]=-1.;
|
90 |
no[0]=ADRESSE(tet->n1,noeud,mesh->);
|
91 |
no[1]=ADRESSE(tet->n2,noeud,mesh->);
|
92 |
no[2]=ADRESSE(tet->n3,noeud,mesh->);
|
93 |
no[3]=ADRESSE(tet->n4,noeud,mesh->);
|
94 |
o3d_move(no[0]->num,coord,crit);
|
95 |
o3d_move(no[1]->num,coord+3,crit+1);
|
96 |
o3d_move(no[2]->num,coord+6,crit+2);
|
97 |
o3d_move(no[3]->num,coord+9,crit+3);
|
98 |
MAXI(crit_opt,crit[0],crit[1]);
|
99 |
MAXI(crit_opt,crit_opt,crit[2]);
|
100 |
MAXI(crit_opt,crit_opt,crit[3]);
|
101 |
if (crit_opt>crit_avant)
|
102 |
{
|
103 |
if (crit_opt==crit[0]) num=0;
|
104 |
if (crit_opt==crit[1]) num=1;
|
105 |
if (crit_opt==crit[2]) num=2;
|
106 |
if (crit_opt==crit[3]) num=3;
|
107 |
no[num]->x=coord[3*num];
|
108 |
no[num]->y=coord[3*num+1];
|
109 |
no[num]->z=coord[3*num+2];
|
110 |
for (j=0;j<no[num]->nb_tetra;j++)
|
111 |
{
|
112 |
tet1=no[num]->tetra[j];
|
113 |
cas=(int)(tet1->crit*10.);
|
114 |
tet1->crit=m3d_cal_qual(tet1->n1,tet1->n2,tet1->n3,tet1->n4);
|
115 |
tmp=tet1->suivant;
|
116 |
tmp2=tet1->precedent;
|
117 |
if (tet1->precedent!=NULL) tet1->precedent->suivant=tmp;
|
118 |
else mesh->tete_tetra[cas]=tmp;
|
119 |
if (tet1->suivant!=NULL) tet1->suivant->precedent=tmp2;
|
120 |
else mesh->queue_tetra[cas]=tmp2;
|
121 |
tet1->precedent=NULL;
|
122 |
tet1->suivant=NULL;
|
123 |
m3d_ord_tet(tet1);
|
124 |
}
|
125 |
}
|
126 |
tet->opt=1;
|
127 |
MAXI(crit_opt,crit_opt,crit_avant);
|
128 |
/* deuxieme essai remaillage d'une coquille */
|
129 |
if (crit_opt<0.1*env.opti)
|
130 |
{
|
131 |
o3d_mail_coq(tet->n1,tet->n2,crit,coque);
|
132 |
o3d_mail_coq(tet->n1,tet->n3,crit+1,coque+1);
|
133 |
o3d_mail_coq(tet->n1,tet->n4,crit+2,coque+2);
|
134 |
o3d_mail_coq(tet->n2,tet->n3,crit+3,coque+3);
|
135 |
o3d_mail_coq(tet->n2,tet->n4,crit+4,coque+4);
|
136 |
o3d_mail_coq(tet->n3,tet->n4,crit+5,coque+5);
|
137 |
MAXI(nv_crit,crit[0],crit[1]);
|
138 |
MAXI(nv_crit,nv_crit,crit[2]);
|
139 |
MAXI(nv_crit,nv_crit,crit[3]);
|
140 |
MAXI(nv_crit,nv_crit,crit[4]);
|
141 |
MAXI(nv_crit,nv_crit,crit[5]);
|
142 |
if (nv_crit>crit_opt)
|
143 |
{
|
144 |
if (nv_crit==crit[0]) o3d_update_coq(coque);
|
145 |
else if (nv_crit==crit[1]) o3d_update_coq(coque+1);
|
146 |
else if (nv_crit==crit[2]) o3d_update_coq(coque+2);
|
147 |
else if (nv_crit==crit[3]) o3d_update_coq(coque+3);
|
148 |
else if (nv_crit==crit[4]) o3d_update_coq(coque+4);
|
149 |
else if (nv_crit==crit[5]) o3d_update_coq(coque+5);
|
150 |
}
|
151 |
/* troisieme essai suppression d une face */
|
152 |
/* troisieme essai suppression d une face */
|
153 |
else if (!o3d_inv_face(tet))
|
154 |
/* quatrieme essai suppression d un noeud et d une arete */
|
155 |
{
|
156 |
VEC(vec12,no[0],no[1]);
|
157 |
VEC(vec13,no[0],no[2]);
|
158 |
VEC(vec14,no[0],no[3]);
|
159 |
VEC(vec23,no[1],no[2]);
|
160 |
VEC(vec24,no[1],no[3]);
|
161 |
VEC(vec34,no[2],no[3]);
|
162 |
l1=PSCA(vec12,vec12);
|
163 |
l2=PSCA(vec13,vec13);
|
164 |
l3=PSCA(vec14,vec14);
|
165 |
l4=PSCA(vec23,vec23);
|
166 |
l5=PSCA(vec24,vec24);
|
167 |
l6=PSCA(vec34,vec34);
|
168 |
MINI(ordre_exec[0],l1,l2);
|
169 |
MINI(ordre_exec[0],ordre_exec[0],l3);
|
170 |
MINI(ordre_exec[1],l1,l4);
|
171 |
MINI(ordre_exec[1],ordre_exec[1],l5);
|
172 |
MINI(ordre_exec[2],l2,l4);
|
173 |
MINI(ordre_exec[2],ordre_exec[2],l6);
|
174 |
MINI(ordre_exec[3],l3,l5);
|
175 |
MINI(ordre_exec[3],ordre_exec[3],l6);
|
176 |
nbclass=4;
|
177 |
for (k=0;k<nbclass;k++) iordre[k]=k+1;
|
178 |
trirea(ordre_exec,&nbclass,iordre);
|
179 |
if (!o3d_deraffine(no[iordre[0]-1]))
|
180 |
if (!o3d_deraffine(no[iordre[1]-1]))
|
181 |
if (!o3d_deraffine(no[iordre[2]-1]))
|
182 |
o3d_deraffine(no[iordre[3]-1]);
|
183 |
}
|
184 |
}
|
185 |
}
|
186 |
}
|
187 |
aff_text(M3D_OPTI2);
|
188 |
for (i=env.opti-1;i>-1;i--)
|
189 |
{
|
190 |
fin=0;
|
191 |
while (fin==0)
|
192 |
{
|
193 |
voir();
|
194 |
tet=mesh->tete_tetra[i];
|
195 |
if (tet==NULL) {fin=1;fin2=1;} else fin2=0;
|
196 |
while (fin2==0)
|
197 |
{
|
198 |
if ((tet->opt==2) ||(tet->etat!=ACTIF))
|
199 |
{
|
200 |
tet=tet->suivant;
|
201 |
if (tet==NULL) {fin=1;fin2=1;}
|
202 |
}
|
203 |
else fin2=1;
|
204 |
}
|
205 |
if (fin==1) continue;
|
206 |
if (tet->etat!=ACTIF) continue;
|
207 |
crit_avant=tet->crit;
|
208 |
crit[0]=-1.;
|
209 |
crit[1]=-1.;
|
210 |
crit[2]=-1.;
|
211 |
crit[3]=-1.;
|
212 |
no[0]=ADRESSE(tet->n1,noeud,mesh->);
|
213 |
no[1]=ADRESSE(tet->n2,noeud,mesh->);
|
214 |
no[2]=ADRESSE(tet->n3,noeud,mesh->);
|
215 |
no[3]=ADRESSE(tet->n4,noeud,mesh->);
|
216 |
o3d_move(no[0]->num,coord,crit);
|
217 |
o3d_move(no[1]->num,coord+3,crit+1);
|
218 |
o3d_move(no[2]->num,coord+6,crit+2);
|
219 |
o3d_move(no[3]->num,coord+9,crit+3);
|
220 |
MAXI(crit_opt,crit[0],crit[1]);
|
221 |
MAXI(crit_opt,crit_opt,crit[2]);
|
222 |
MAXI(crit_opt,crit_opt,crit[3]);
|
223 |
if (crit_opt>crit_avant)
|
224 |
{
|
225 |
if (crit_opt==crit[0]) num=0;
|
226 |
if (crit_opt==crit[1]) num=1;
|
227 |
if (crit_opt==crit[2]) num=2;
|
228 |
if (crit_opt==crit[3]) num=3;
|
229 |
no[num]->x=coord[3*num];
|
230 |
no[num]->y=coord[3*num+1];
|
231 |
no[num]->z=coord[3*num+2];
|
232 |
for (j=0;j<no[num]->nb_tetra;j++)
|
233 |
{
|
234 |
tet1=no[num]->tetra[j];
|
235 |
tet1->crit=m3d_cal_qual(tet1->n1,tet1->n2,tet1->n3,tet1->n4);
|
236 |
cas=(int)(tet1->crit*10.);
|
237 |
tmp=tet1->suivant;
|
238 |
tmp2=tet1->precedent;
|
239 |
if (tet1->precedent!=NULL) tet1->precedent->suivant=tmp;
|
240 |
else mesh->tete_tetra[cas]=tmp;
|
241 |
if (tet1->suivant!=NULL) tet1->suivant->precedent=tmp2;
|
242 |
else mesh->queue_tetra[cas]=tmp2;
|
243 |
tet1->precedent=NULL;
|
244 |
tet1->suivant=NULL;
|
245 |
m3d_ord_tet(tet1);
|
246 |
}
|
247 |
}
|
248 |
tet->opt=2;
|
249 |
MAXI(crit_opt,crit_opt,crit_avant);
|
250 |
if (crit_opt<0.1*env.opti)
|
251 |
{
|
252 |
o3d_mail_coq(tet->n1,tet->n2,crit,coque);
|
253 |
o3d_mail_coq(tet->n1,tet->n3,crit+1,coque+1);
|
254 |
o3d_mail_coq(tet->n1,tet->n4,crit+2,coque+2);
|
255 |
o3d_mail_coq(tet->n2,tet->n3,crit+3,coque+3);
|
256 |
o3d_mail_coq(tet->n2,tet->n4,crit+4,coque+4);
|
257 |
o3d_mail_coq(tet->n3,tet->n4,crit+5,coque+5);
|
258 |
MAXI(nv_crit,crit[0],crit[1]);
|
259 |
MAXI(nv_crit,nv_crit,crit[2]);
|
260 |
MAXI(nv_crit,nv_crit,crit[3]);
|
261 |
MAXI(nv_crit,nv_crit,crit[4]);
|
262 |
MAXI(nv_crit,nv_crit,crit[5]);
|
263 |
if (nv_crit>crit_opt)
|
264 |
{
|
265 |
if (nv_crit==crit[0]) o3d_update_coq(coque);
|
266 |
else if (nv_crit==crit[1]) o3d_update_coq(coque+1);
|
267 |
else if (nv_crit==crit[2]) o3d_update_coq(coque+2);
|
268 |
else if (nv_crit==crit[3]) o3d_update_coq(coque+3);
|
269 |
else if (nv_crit==crit[4]) o3d_update_coq(coque+4);
|
270 |
else if (nv_crit==crit[5]) o3d_update_coq(coque+5);
|
271 |
}
|
272 |
else
|
273 |
o3d_inv_face(tet);
|
274 |
}
|
275 |
|
276 |
}
|
277 |
}
|
278 |
|
279 |
}
|