1 |
|
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 |
|
|
}
|