1 |
/*****************************************************************
|
2 |
|
3 |
o3d_mail_coq.cpp Type:Func
|
4 |
|
5 |
Remaillage d une coquille
|
6 |
|
7 |
Date de creation : 22-4-1999 9 :5 :7
|
8 |
Derniere version : 22-4-1999 9 :5 :7
|
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 |
extern int tab_solution[7][1430][8];
|
33 |
extern int tab_face[7][120][3];
|
34 |
|
35 |
|
36 |
|
37 |
/**************************/
|
38 |
/* programme principal */
|
39 |
|
40 |
void o3d_mail_coq(int n1,int n2, float *crit, struct coquille *coque)
|
41 |
{
|
42 |
int i,j,nb_coq,coq[20];
|
43 |
int poly[20];
|
44 |
int tet_noeud[40];
|
45 |
int nb_tet_noeud;
|
46 |
int nb_poly;
|
47 |
int nsolution,nface;
|
48 |
struct s_tetra *tet;
|
49 |
struct s_noeud *no1,*noa,*nob,*noc,*nod,*noe;
|
50 |
struct s_noeud *no2;
|
51 |
float crit_face[120],eps;
|
52 |
float crit1,crit2,crit_solution[1430];
|
53 |
float volume,volume_ori;
|
54 |
float ab[4],ac[4],ad[4],vec[4];
|
55 |
int numero_solution;
|
56 |
float crit_opt;
|
57 |
|
58 |
|
59 |
no1=ADRESSE(n1,noeud,mesh->);
|
60 |
no2=ADRESSE(n2,noeud,mesh->);
|
61 |
/* validite du segment */
|
62 |
for (i=0;i<no1->nb_segment;i++)
|
63 |
for (j=0;j<no2->nb_segment;j++)
|
64 |
if (no1->segment[i]->num==no2->segment[j]->num)
|
65 |
if (no1->segment[i]->type!=BODY)
|
66 |
{
|
67 |
*crit=0.;
|
68 |
coque->n=0;
|
69 |
return;
|
70 |
}
|
71 |
|
72 |
/* recherche de la coquille */
|
73 |
nb_coq=0;
|
74 |
for (i=0;i<no1->nb_tetra;i++)
|
75 |
{
|
76 |
if (no1->tetra[i]->etat==ACTIF)
|
77 |
for (j=0;j<no2->nb_tetra;j++)
|
78 |
{
|
79 |
if (no2->tetra[j]->etat==ACTIF)
|
80 |
if (no1->tetra[i]->num==no2->tetra[j]->num)
|
81 |
{
|
82 |
coq[nb_coq]=no1->tetra[i]->num;
|
83 |
nb_coq++;
|
84 |
}
|
85 |
}
|
86 |
}
|
87 |
if ((nb_coq<4) || (nb_coq>10))
|
88 |
{
|
89 |
*crit=0.;
|
90 |
coque->n=0;
|
91 |
return;
|
92 |
}
|
93 |
/* on repere les noeuds libres de chaque tetra */
|
94 |
nb_tet_noeud=0;
|
95 |
volume_ori=0.;
|
96 |
coque->n=nb_coq;
|
97 |
for (i=0;i<nb_coq;i++)
|
98 |
{
|
99 |
tet=ADRESSE(coq[i],tetra,mesh->);
|
100 |
coque->tet[i]=tet;
|
101 |
if ((tet->n1!=n1) && (tet->n1!=n2)) tet_noeud[nb_tet_noeud++]=tet->n1;
|
102 |
if ((tet->n2!=n1) && (tet->n2!=n2)) tet_noeud[nb_tet_noeud++]=tet->n2;
|
103 |
if ((tet->n3!=n1) && (tet->n3!=n2)) tet_noeud[nb_tet_noeud++]=tet->n3;
|
104 |
if ((tet->n4!=n1) && (tet->n4!=n2)) tet_noeud[nb_tet_noeud++]=tet->n4;
|
105 |
noa=ADRESSE(tet->n1,noeud,mesh->);
|
106 |
nob=ADRESSE(tet->n2,noeud,mesh->);
|
107 |
noc=ADRESSE(tet->n3,noeud,mesh->);
|
108 |
nod=ADRESSE(tet->n4,noeud,mesh->);
|
109 |
VEC(ab,noa,nob);
|
110 |
VEC(ac,noa,noc);
|
111 |
VEC(ad,noa,nod);
|
112 |
PVEC(vec,ab,ac);
|
113 |
volume_ori=volume_ori+(float)fabs((double)PSCA(vec,ad));
|
114 |
}
|
115 |
/* numeratation de la coquille */
|
116 |
poly[0]=tet_noeud[0];tet_noeud[0]=(-1);
|
117 |
poly[1]=tet_noeud[1];tet_noeud[1]=(-1);
|
118 |
nb_poly=2;
|
119 |
while (nb_poly!=(nb_coq+1))
|
120 |
{
|
121 |
for (j=0;j<nb_coq;j++)
|
122 |
{
|
123 |
if (tet_noeud[2*j]==poly[nb_poly-1])
|
124 |
{
|
125 |
poly[nb_poly++]=tet_noeud[2*j+1];
|
126 |
tet_noeud[2*j]=(-1);
|
127 |
tet_noeud[2*j+1]=(-1);
|
128 |
}
|
129 |
if (tet_noeud[2*j+1]==poly[nb_poly-1])
|
130 |
{
|
131 |
poly[nb_poly++]=tet_noeud[2*j];
|
132 |
tet_noeud[2*j]=(-1);
|
133 |
tet_noeud[2*j+1]=(-1);
|
134 |
}
|
135 |
}
|
136 |
}
|
137 |
/* qualite de chaque solution */
|
138 |
if (nb_coq==4) {nsolution=2;nface=4;}
|
139 |
if (nb_coq==5) {nsolution=5;nface=10;}
|
140 |
if (nb_coq==6) {nsolution=14;nface=20;}
|
141 |
if (nb_coq==7) {nsolution=42;nface=35;}
|
142 |
if (nb_coq==8) {nsolution=132;nface=56;}
|
143 |
if (nb_coq==9) {nsolution=429;nface=84;}
|
144 |
if (nb_coq==10) {nsolution=1430;nface=120;}
|
145 |
|
146 |
for (i=0;i<nface;i++)
|
147 |
{
|
148 |
crit1=o3d_cal_qual(poly[tab_face[nb_coq-4][i][0]],poly[tab_face[nb_coq-4][i][1]],poly[tab_face[nb_coq-4][i][2]],n1);
|
149 |
crit2=o3d_cal_qual(poly[tab_face[nb_coq-4][i][0]],poly[tab_face[nb_coq-4][i][1]],poly[tab_face[nb_coq-4][i][2]],n2);
|
150 |
MINI(crit_face[i],crit1,crit2);
|
151 |
}
|
152 |
/* examen de chaque solution */
|
153 |
crit_opt=0.;
|
154 |
numero_solution=(-1);
|
155 |
for (i=0;i<nsolution;i++)
|
156 |
{
|
157 |
volume=0.;
|
158 |
for (j=0;j<nb_coq-2;j++)
|
159 |
{
|
160 |
noa=ADRESSE(poly[tab_face[nb_coq-4][tab_solution[nb_coq-4][i][j]][0]],noeud,mesh->);
|
161 |
nob=ADRESSE(poly[tab_face[nb_coq-4][tab_solution[nb_coq-4][i][j]][1]],noeud,mesh->);
|
162 |
noc=ADRESSE(poly[tab_face[nb_coq-4][tab_solution[nb_coq-4][i][j]][2]],noeud,mesh->);
|
163 |
nod=ADRESSE(n1,noeud,mesh->);
|
164 |
VEC(ab,noa,nob);
|
165 |
VEC(ac,noa,noc);
|
166 |
VEC(ad,noa,nod);
|
167 |
PVEC(vec,ab,ac);
|
168 |
volume=volume+(float)fabs((double)PSCA(vec,ad));
|
169 |
nod=ADRESSE(n2,noeud,mesh->);
|
170 |
VEC(ad,noa,nod);
|
171 |
volume=volume+(float)fabs((double)PSCA(vec,ad));
|
172 |
}
|
173 |
eps=0.0018*(float)pow((double)volume,0.666666666);
|
174 |
if (EGAL(volume,volume_ori,eps))
|
175 |
{
|
176 |
crit_solution[i]=1.;
|
177 |
for (j=0;j<nb_coq-2;j++)
|
178 |
MINI(crit_solution[i],crit_solution[i],crit_face[tab_solution[nb_coq-4][i][j]]);
|
179 |
}
|
180 |
else crit_solution[i]=0.;
|
181 |
if (crit_opt<crit_solution[i])
|
182 |
{
|
183 |
crit_opt=crit_solution[i];
|
184 |
numero_solution=i;
|
185 |
}
|
186 |
|
187 |
}
|
188 |
/* bonne solution */
|
189 |
if (numero_solution==(-1))
|
190 |
{
|
191 |
*crit=0.;
|
192 |
coque->n=0;
|
193 |
return;
|
194 |
}
|
195 |
*crit=crit_opt;
|
196 |
nod=ADRESSE(n1,noeud,mesh->);
|
197 |
noe=ADRESSE(n2,noeud,mesh->);
|
198 |
for (j=0;j<nb_coq-2;j++)
|
199 |
{
|
200 |
noa=ADRESSE(poly[tab_face[nb_coq-4][tab_solution[nb_coq-4][numero_solution][j]][0]],noeud,mesh->);
|
201 |
nob=ADRESSE(poly[tab_face[nb_coq-4][tab_solution[nb_coq-4][numero_solution][j]][1]],noeud,mesh->);
|
202 |
noc=ADRESSE(poly[tab_face[nb_coq-4][tab_solution[nb_coq-4][numero_solution][j]][2]],noeud,mesh->);
|
203 |
coque->new_tetra[8*j]=noa->num;
|
204 |
coque->new_tetra[8*j+1]=nob->num;
|
205 |
coque->new_tetra[8*j+2]=noc->num;
|
206 |
coque->new_tetra[8*j+3]=nod->num;
|
207 |
coque->new_tetra[8*j+4]=noa->num;
|
208 |
coque->new_tetra[8*j+5]=nob->num;
|
209 |
coque->new_tetra[8*j+6]=noc->num;
|
210 |
coque->new_tetra[8*j+7]=noe->num;
|
211 |
}
|
212 |
}
|