1 |
francois |
283 |
|
2 |
|
|
#include <stdio.h> |
3 |
|
|
#include <math.h> |
4 |
|
|
#include <stdlib.h> |
5 |
|
|
#include "p3d_cst.h" |
6 |
|
|
#include "m3d_struct.h" |
7 |
|
|
#include "m3d_hotes.h" |
8 |
|
|
#include "m3d_erreur.h" |
9 |
|
|
#include "prototype.h" |
10 |
|
|
extern GEST_MEM *gest ; |
11 |
|
|
extern int debug ; |
12 |
|
|
int p3d_envel(void) |
13 |
|
|
{ |
14 |
|
|
/* ************************************************* */ |
15 |
|
|
/* declaration des variables internes a la procedure */ |
16 |
|
|
ELEMENT *tete;/* tete des elements du front */ |
17 |
|
|
SURFACE *surf, *surf_ext ; |
18 |
|
|
int i, num, gtrouve, k, ierr ; |
19 |
|
|
int is_ok, nb_inter, nb, j, nb_reel, jmax ; |
20 |
|
|
float vec_posi[NB_MAX_INTER], vmax, *v_inter ; |
21 |
|
|
int iordre[NB_MAX_INTER], is ; |
22 |
|
|
int ipair, nb_neg, k1, k2 ; |
23 |
|
|
|
24 |
|
|
/* debut du code executable */ |
25 |
|
|
|
26 |
|
|
ierr = 0 ; |
27 |
|
|
gest->nb_surf = 0 ; |
28 |
|
|
/* determination du nombre de surfaces par un algorithme frontal */ |
29 |
|
|
if (!p3d_nbsurf()) |
30 |
|
|
{ |
31 |
|
|
if (debug) printf("%s\n"," erreur p3d_nbsurf P3D_ENVEL ") ; |
32 |
|
|
return(FAUX) ; |
33 |
|
|
} |
34 |
|
|
|
35 |
|
|
/* creation et orientation des surfaces, creations des volumes enveloppes */ |
36 |
|
|
gest->tab_surf = (SURFACE *)calloc(gest->nb_surf,sizeof(SURFACE)) ; |
37 |
|
|
ERREUR_ALLOC(gest->tab_surf) |
38 |
|
|
|
39 |
|
|
for (i=0;i<gest->nb_surf;i++) |
40 |
|
|
{ |
41 |
|
|
(gest->tab_surf[i]).etat = UNKNOWN ; |
42 |
|
|
(gest->tab_surf[i]).ele = NULL ; |
43 |
|
|
(gest->tab_surf[i]).suivant = NULL ; |
44 |
|
|
(gest->tab_surf[i]).envel = NULL ; |
45 |
|
|
} |
46 |
|
|
|
47 |
|
|
/* affecter les elements aux surfaces */ |
48 |
|
|
for (i=0;i<gest->nb_2d;i++) |
49 |
|
|
{ |
50 |
|
|
/* pointeur element i */ |
51 |
|
|
tete = &(gest->tab_ele[i]) ; |
52 |
|
|
/* surface d'appartenance */ |
53 |
|
|
surf = &(gest->tab_surf[(tete->mark)-1]) ;/* pointeur sur la surface */ |
54 |
|
|
INSERE_TETE(surf->ele,tete) |
55 |
|
|
/* insertion en tete de l'element tete dans la liste d'elements surface->ele */ |
56 |
|
|
} |
57 |
|
|
|
58 |
|
|
for (i=0;i<gest->nb_2d;i++) (gest->tab_ele[i]).mark = 0 ; |
59 |
|
|
|
60 |
|
|
/* a ce stade. on a cree des surfaces reperees dans tab_surf et on leur a affecte des listes d'elements */ |
61 |
|
|
/* orientation des surfaces */ |
62 |
|
|
for (is=0;is<gest->nb_surf;is++) |
63 |
|
|
{ |
64 |
|
|
surf = &(gest->tab_surf[is]) ; |
65 |
|
|
/* on choisit un element sur la surface */ |
66 |
|
|
tete = surf->ele ; |
67 |
|
|
/* tete de liste des elements de la surface */ |
68 |
|
|
/* orientation de la surface surf */ |
69 |
|
|
while (tete!=NULL) |
70 |
|
|
{ |
71 |
|
|
nb = 0 ; |
72 |
|
|
nb_reel = 0 ; |
73 |
|
|
nb_neg = 0 ; |
74 |
|
|
/* INTERSECTION entre la droite passant par le barycentre de l'element et |
75 |
|
|
de vecteur directeur la normale a l'element et la surface reperee par tab_surf[j] */ |
76 |
|
|
/* en sortie nb, nombre de points d'intersection */ |
77 |
|
|
/* strategie pour les points doubles : on les evite pour le moment en choisissant |
78 |
|
|
un autre element sur la surface */ |
79 |
|
|
/* on pourra par la suite trier les points doubles, voir triples */ |
80 |
|
|
p3d_inter(gest->vcorg,gest->tabele,surf,tete,&nb,&nb_reel,&nb_neg,vec_posi,&ierr) ; |
81 |
|
|
/* erreur */ |
82 |
|
|
if (ierr==VRAI) |
83 |
|
|
{ |
84 |
|
|
if (debug) printf("%s\n"," erreur p3d_inter P3D_ENVEL ") ; |
85 |
|
|
return(FAUX) ; |
86 |
|
|
} |
87 |
|
|
if (nb==UNKNOWN) |
88 |
|
|
{ |
89 |
|
|
tete=tete->suivant ; |
90 |
|
|
} |
91 |
|
|
else |
92 |
|
|
{ |
93 |
|
|
/* l'element n'a pas permis de conclure (is_ok==FAUX), il faut passer au suivant |
94 |
|
|
sinon on passe a la surface suivante */ |
95 |
|
|
|
96 |
|
|
for (i=0;i<nb_reel;i++) iordre[i] = i+1 ;/* attention passage c fortran */ |
97 |
|
|
trirea(vec_posi,&nb_reel,iordre) ; |
98 |
|
|
/* on oriente la surface */ |
99 |
|
|
/* test sur la parite du nombre d'intersections */ |
100 |
|
|
/* recherche dans vec_posi */ |
101 |
|
|
i = 0 ; |
102 |
|
|
while (i<=nb_reel) |
103 |
|
|
{ |
104 |
|
|
i++ ; |
105 |
|
|
if ((float)fabs((double)vec_posi[i-1])<EPSILON) |
106 |
|
|
{ |
107 |
|
|
break ; |
108 |
|
|
} |
109 |
|
|
} |
110 |
|
|
ipair = i - 2 *(int)(i/2) ; |
111 |
|
|
if (ipair==1) /* normale interieure */ |
112 |
|
|
{ |
113 |
|
|
/* on change l'orientation d'un element en inversant une arete */ |
114 |
|
|
num = gest->tabele[3*(tete->num)] ; |
115 |
|
|
/* premier noeud de l'element */ |
116 |
|
|
gest->tabele[3*(tete->num)]=gest->tabele[3*(tete->num)+1] ; |
117 |
|
|
gest->tabele[3*(tete->num)+1] = num ; |
118 |
|
|
} |
119 |
|
|
/* ORIENTATION SUIVANT UN ALGORITHME FRONTAL */ |
120 |
|
|
if (!p3d_orient(tete->num)) |
121 |
|
|
{ |
122 |
|
|
if (debug) printf("%s\n"," erreur p3d_orient P3D_ENVEL ") ; |
123 |
|
|
return(FAUX) ; |
124 |
|
|
} |
125 |
|
|
break ; |
126 |
|
|
} |
127 |
|
|
} |
128 |
|
|
} |
129 |
|
|
/* position relative des surfaces */ |
130 |
|
|
/* pour chacune des surfaces, on doit determiner si la surface est exterieur, ou interieur */ |
131 |
|
|
/* pour chacune des surfaces, on determine le nombre d'intersections dont l'abscisse curviligne est |
132 |
|
|
strictement negative : |
133 |
|
|
- avec toutes les autres surfaces --------> k1 |
134 |
|
|
- avec la surface elle meme --------------> k2 |
135 |
|
|
|
136 |
|
|
si k1 + k2 est pair, la surface est exterieure et on peut creer un volume sinon la surface est exterieure |
137 |
|
|
et on chaine celle ci avec la surface exterieure associee */ |
138 |
|
|
/* parcours de tab_surf */ |
139 |
|
|
|
140 |
|
|
gest->v_inter = (float*)calloc(gest->nb_surf * gest->nb_surf,sizeof(float)) ; |
141 |
|
|
ERREUR_ALLOC(gest->v_inter) ; |
142 |
|
|
if (gest->nb_surf>1) |
143 |
|
|
{ |
144 |
|
|
for (i=0;i<gest->nb_surf;i++) |
145 |
|
|
{ |
146 |
|
|
/* changer l'implementation voir ci dessus */ |
147 |
|
|
k1 = 0 ;/* nombre d'intersections avec toutes les autres surfaces */ |
148 |
|
|
k2 = 0 ;/* nombre d'intersections avec la surface elle meme */ |
149 |
|
|
surf = &(gest->tab_surf[i]) ; |
150 |
|
|
/* on choisit un element sur la surface */ |
151 |
|
|
tete = surf->ele ;/* tete de liste des elements de la surface */ |
152 |
|
|
/* boucle sur les autres surfaces */ |
153 |
|
|
for (j=0;j<gest->nb_surf;j++) |
154 |
|
|
{ |
155 |
|
|
nb = 0 ; |
156 |
|
|
nb_reel = 0 ; |
157 |
|
|
nb_neg = 0 ; |
158 |
|
|
/* intersection surface i, surface j */ |
159 |
|
|
p3d_inter(gest->vcorg,gest->tabele,&(gest->tab_surf[j]),tete,&nb,&nb_reel,&nb_neg,vec_posi,&ierr) ; |
160 |
|
|
if ((ierr==VRAI) || (nb==UNKNOWN)) |
161 |
|
|
{ |
162 |
|
|
if (debug) printf("%s\n"," erreur p3d_inter P3D_ENVEL ") ; |
163 |
|
|
return(FAUX) ; |
164 |
|
|
} |
165 |
|
|
/* tester la parite de nb_neg */ |
166 |
|
|
ipair = nb_neg - 2 * (int)(nb_neg/2) ; |
167 |
|
|
if (ipair==0) |
168 |
|
|
{ |
169 |
|
|
/* nombre d'intersections paire */ |
170 |
|
|
gest->v_inter[gest->nb_surf*j+i] = 123456789. ; |
171 |
|
|
} |
172 |
|
|
else gest->v_inter[gest->nb_surf*j+i] = vec_posi[0] ;/* valeur mini car vec_posi est trie */ |
173 |
|
|
if (i==j) |
174 |
|
|
{ |
175 |
|
|
k2 = nb_neg ; |
176 |
|
|
} |
177 |
|
|
k1 = k1 + nb_neg ; |
178 |
|
|
} |
179 |
|
|
ipair = (k1 + k2) - 2 *(int)((k1+k2)/2) ; |
180 |
|
|
if (ipair==0) |
181 |
|
|
{ |
182 |
|
|
(gest->tab_surf[i]).etat= EXTERIEUR ; |
183 |
|
|
} |
184 |
|
|
else (gest->tab_surf[i]).etat = INTERIEUR ; |
185 |
|
|
} |
186 |
|
|
} |
187 |
|
|
else (gest->tab_surf[0]).etat = EXTERIEUR ; |
188 |
|
|
|
189 |
|
|
gest->envel = p3d_c_envel() ;/* creation du volume enveloppe */ |
190 |
|
|
surf_ext = NULL ; |
191 |
|
|
if (gest->envel == NULL) |
192 |
|
|
{ |
193 |
|
|
if (debug) printf("%s\n"," erreur P3D_ENVEL ") ; |
194 |
|
|
return(FAUX) ; |
195 |
|
|
} |
196 |
|
|
i = 0 ; |
197 |
|
|
while ((i<gest->nb_surf) /*&& (surf_ext == NULL)*/) |
198 |
|
|
{ |
199 |
|
|
if ((gest->tab_surf[i]).etat == EXTERIEUR) |
200 |
|
|
{ |
201 |
|
|
surf_ext = &(gest->tab_surf[i]) ; |
202 |
|
|
surf_ext->suivant=(gest->envel)->surf_ext; |
203 |
|
|
(gest->envel)->surf_ext = surf_ext ;/* on affecte la surface ext au volume */ |
204 |
|
|
surf_ext->envel = gest->envel ;/* puis on affecte le volume a la surface ext */ |
205 |
|
|
} |
206 |
|
|
i++ ; |
207 |
|
|
} |
208 |
|
|
if (surf_ext == NULL) |
209 |
|
|
{ |
210 |
|
|
return(FAUX) ; |
211 |
|
|
} |
212 |
|
|
|
213 |
|
|
/* traitement des surfaces interieures */ |
214 |
|
|
for (i=0;i<gest->nb_surf;i++) |
215 |
|
|
{ |
216 |
|
|
if ((gest->tab_surf[i]).etat == INTERIEUR) |
217 |
|
|
{ |
218 |
|
|
surf = &(gest->tab_surf[i]) ;/* surface interieure */ |
219 |
|
|
/* insertion en tete de liste des surfaces interieures liees au volume enveloppe */ |
220 |
|
|
surf->suivant = (gest->envel)->surf_int ; |
221 |
|
|
(gest->envel)->surf_int = surf ; |
222 |
|
|
} |
223 |
|
|
} |
224 |
|
|
|
225 |
|
|
free(gest->v_inter) ; |
226 |
|
|
gest->v_inter = NULL ; |
227 |
|
|
return(VRAI) ; |
228 |
|
|
} |
229 |
|
|
|