ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/diamesh/src/p3d_envel.cpp
Revision: 5
Committed: Tue Jun 12 20:26:34 2007 UTC (17 years, 11 months ago)
Original Path: magic/lib/diamesh/diamesh/src/p3d_envel.cpp
File size: 7242 byte(s)
Log Message:

File Contents

# User Rev Content
1 5
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