Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
boulep_s.c
Go to the documentation of this file.
1/* =============================================================================
2** This file is part of the mmg software package for the tetrahedral
3** mesh modification.
4** Copyright (c) Bx INP/CNRS/Inria/UBordeaux/UPMC, 2004-
5**
6** mmg is free software: you can redistribute it and/or modify it
7** under the terms of the GNU Lesser General Public License as published
8** by the Free Software Foundation, either version 3 of the License, or
9** (at your option) any later version.
10**
11** mmg is distributed in the hope that it will be useful, but WITHOUT
12** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13** FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14** License for more details.
15**
16** You should have received a copy of the GNU Lesser General Public
17** License and of the GNU General Public License along with mmg (in
18** files COPYING.LESSER and COPYING). If not, see
19** <http://www.gnu.org/licenses/>. Please read their terms carefully and
20** use this copy of the mmg distribution only if you accept them.
21** =============================================================================
22*/
23
36#include "libmmgs_private.h"
37
51int boulechknm(MMG5_pMesh mesh,MMG5_int start,int ip,MMG5_int *list) {
52 MMG5_pTria pt;
53 MMG5_pPoint ppt;
54 MMG5_int *adja,k,iel,base;
55 int ilist;
56 int8_t i,i1,i2,ia,iq,voy;
57
58 base = ++mesh->base;
59
60 pt = &mesh->tria[start];
61 ia = MMG5_iprv2[ip];
62 iq = MMG5_inxt2[ip];
63 if ( !MG_EOK(pt) ) return 0;
64 ppt = &mesh->point[pt->v[ip]];
65 if ( ppt->tag & MG_NOM ) return 0;
66 ilist = 0;
67
68 /* store neighbors */
69 k = start;
70 i = ip;
71 do {
72 if ( ilist > MMG5_TRIA_LMAX-2 ) return -ilist;
73 list[ilist] = 3*k + i;
74 ++ilist;
75
76 pt = &mesh->tria[k];
77
78 i1 = MMG5_inxt2[i];
79 i2 = MMG5_iprv2[i];
80 ppt = &mesh->point[pt->v[i1]];
81 ppt->s = base;
82 ppt = &mesh->point[pt->v[i2]];
83 ppt->s = base;
84
85 adja = &mesh->adja[3*(k-1)+1];
86 k = adja[i1] / 3;
87 i = adja[i1] % 3;
88 i = MMG5_inxt2[i];
89 }
90 while ( k && k != start );
91
92 /* check if boundary hit */
93 if ( k <= 0 ) {
94 k = start;
95 i = ip;
96 do {
97 adja = &mesh->adja[3*(k-1)+1];
98 i1 = MMG5_inxt2[i];
99 i2 = MMG5_iprv2[i];
100
101 pt = &mesh->tria[k];
102 ppt = &mesh->point[pt->v[i1]];
103 ppt->s = base;
104 ppt = &mesh->point[pt->v[i2]];
105 ppt->s = base;
106
107 k = adja[i2] / 3;
108 if ( k == 0 ) break;
109 i = adja[i2] % 3;
110 i = MMG5_iprv2[i];
111
112 if ( ilist > MMG5_TRIA_LMAX-2 ) return -ilist;
113 list[ilist] = 3*k + i;
114 ilist++;
115 }
116 while ( k );
117 }
118
119 pt = &mesh->tria[start];
120 i1 = MMG5_inxt2[ip];
121 i2 = MMG5_iprv2[ip];
122 ppt = &mesh->point[pt->v[i1]];
123 ppt->s = 0;
124 ppt = &mesh->point[pt->v[i2]];
125 ppt->s = 0;
126
127 adja = &mesh->adja[3*(start-1)+1];
128 iel = adja[ia] / 3;
129 voy = adja[ia] % 3;
130
131 if( iel ) {
132 pt = &mesh->tria[iel];
133 ppt = &mesh->point[pt->v[voy]];
134 ppt->s = 0;
135 }
136
137 /* check if a collapse may lead to a non-convex situation */
138 k = start;
139 i = iq;
140 do {
141 pt = &mesh->tria[k];
142
143 i1 = MMG5_inxt2[i];
144 i2 = MMG5_iprv2[i];
145 ppt = &mesh->point[pt->v[i1]];
146 if ( ppt->s == base ) return 0;
147 ppt = &mesh->point[pt->v[i2]];
148 if ( ppt->s == base ) return 0;
149
150 adja = &mesh->adja[3*(k-1)+1];
151 k = adja[i1] / 3;
152 i = adja[i1] % 3;
153 i = MMG5_inxt2[i];
154 }
155 while ( k && k != start );
156 if( k > 0 ) return ilist;
157
158 /* check if boundary hit */
159 k = start;
160 i = iq;
161 do {
162 adja = &mesh->adja[3*(k-1)+1];
163 i1 = MMG5_inxt2[i];
164 i2 = MMG5_iprv2[i];
165
166 pt = &mesh->tria[k];
167 ppt = &mesh->point[pt->v[i1]];
168 if ( ppt->s == base ) return 0;
169 ppt = &mesh->point[pt->v[i2]];
170 if ( ppt->s == base ) return 0;
171
172 k = adja[i2] / 3;
173 if ( k == 0 ) break;
174 i = adja[i2] % 3;
175 i = MMG5_iprv2[i];
176 }
177 while ( k );
178
179 return ilist;
180}
181
201int bouletrid(MMG5_pMesh mesh,MMG5_int start,MMG5_int ip,int *il1,MMG5_int *l1,int *il2,MMG5_int *l2,MMG5_int *ip0,MMG5_int *ip1) {
202 MMG5_pTria pt;
203 MMG5_pPoint ppt;
204 MMG5_int idp,k,kold,*adja,iel,*list1,*list2,aux;
205 int *ilist1,*ilist2;
206 uint8_t i,iold,i1,i2,ipn;
207 double *n1,*n2,nt[3],ps1,ps2;
208
209 pt = &mesh->tria[start];
210 if ( !MG_EOK(pt) ) return 0;
211
212 idp = pt->v[ip];
213 ppt = &mesh->point[idp];
214 assert( ppt->tag & MG_GEO );
215
216 /* set pointers: first manifold is on side of triangle */
217 if ( !MMG5_nortri(mesh,pt,nt) ) return 0;
218
219 n1 = &(mesh->xpoint[ppt->xp].n1[0]);
220 n2 = &(mesh->xpoint[ppt->xp].n2[0]);
221 ps1 = n1[0]*nt[0] + n1[1]*nt[1] + n1[2]*nt[2];
222 ps2 = n2[0]*nt[0] + n2[1]*nt[1] + n2[2]*nt[2];
223
224 if ( fabs(ps1) < fabs(ps2) ) {
225 list1 = l2;
226 list2 = l1;
227 ilist1 = il2;
228 ilist2 = il1;
229 }
230 else {
231 list1 = l1;
232 list2 = l2;
233 ilist1 = il1;
234 ilist2 = il2;
235 }
236 *ilist1 = 0;
237
238 /* First ball, first side (via i1)*/
239 k = start;
240 i = ip;
241 do {
242 pt = &mesh->tria[k];
243 adja = &mesh->adja[3*(k-1)+1];
244 i1 = MMG5_inxt2[i];
245 i2 = MMG5_iprv2[i];
246 kold = k;
247 iold = i;
248 k = adja[i1] / 3;
249 i = adja[i1] % 3;
250 i = MMG5_inxt2[i];
251 }
252 // Remark: here the test k!=start is a security bound: theorically it is
253 // useless but in case of bad edge tag, it ensure that the loop is not
254 // infinite.
255 while ( k && !(pt->tag[i1] & MG_GEO) && k != start );
256 *ip0 = pt->v[i2];
257
258 /* Store the needed elements to start back in the new area,
259 and complete first ball, second side (via i2) */
260 iel = k;
261 ipn = i;
262 k = kold;
263 i = iold;
264 do {
265 pt = &mesh->tria[k];
266 adja = &mesh->adja[3*(k-1)+1];
267 if ( (*ilist1) > MMG5_TRIA_LMAX-2 ) return 0;
268 list1[(*ilist1)] = 3*k+i;
269 (*ilist1)++;
270 i1 = MMG5_inxt2[i];
271 i2 = MMG5_iprv2[i];
272 k = adja[i2] / 3;
273 i = adja[i2] % 3;
274 i = MMG5_iprv2[i];
275 }
276 while ( k && !(MG_GEO & pt->tag[i2]) );
277 *ip1 = pt->v[i1];
278
279 /* Invert the order in list1, so that it is enumerated in DIRECT order */
280 for (k=0; k<(*ilist1) / 2;k++) {
281 aux = list1[k];
282 list1[k] = list1[*ilist1-1-k];
283 list1[*ilist1-1-k] = aux;
284 }
285 /* At this point, either something has been stored in iel or an open boundary has been hit */
286 *ilist2 = 0;
287 if ( !iel ) return 1;
288
289 /* Else, start back from the hit boundary, until another boundary is hit */
290 k = iel;
291 i = ipn;
292 do {
293 pt = &mesh->tria[k];
294 adja = &mesh->adja[3*(k-1)+1];
295 if ( *ilist2 > MMG5_TRIA_LMAX-2 ) return 0;
296 list2[*ilist2] = 3*k+i;
297 (*ilist2)++;
298 i1 = MMG5_inxt2[i];
299 k = adja[i1] / 3;
300 i = adja[i1] % 3;
301 i = MMG5_inxt2[i];
302 }
303 while ( k && !(MG_GEO & pt->tag[i1]) );
304
305 if ( !(MG_GEO & pt->tag[i1]) )
306 return 0;
307 else
308 return 1;
309}
MMG5_pMesh * mesh
int boulechknm(MMG5_pMesh mesh, MMG5_int start, int ip, MMG5_int *list)
Definition: boulep_s.c:51
int bouletrid(MMG5_pMesh mesh, MMG5_int start, MMG5_int ip, int *il1, MMG5_int *l1, int *il2, MMG5_int *l2, MMG5_int *ip0, MMG5_int *ip1)
Definition: boulep_s.c:201
#define MG_GEO
#define MG_EOK(pt)
static const uint8_t MMG5_iprv2[3]
#define MMG5_TRIA_LMAX
static const uint8_t MMG5_inxt2[6]
int MMG5_nortri(MMG5_pMesh mesh, MMG5_pTria pt, double *n)
Definition: tools.c:209
#define MG_NOM
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_pPoint point
Definition: libmmgtypes.h:641
MMG5_int * adja
Definition: libmmgtypes.h:624
MMG5_pxPoint xpoint
Definition: libmmgtypes.h:642
MMG5_int base
Definition: libmmgtypes.h:616
MMG5_pTria tria
Definition: libmmgtypes.h:647
Structure to store points of a MMG mesh.
Definition: libmmgtypes.h:270
int16_t tag
Definition: libmmgtypes.h:284
MMG5_int xp
Definition: libmmgtypes.h:279
MMG5_int s
Definition: libmmgtypes.h:283
int16_t tag[3]
Definition: libmmgtypes.h:342
MMG5_int v[3]
Definition: libmmgtypes.h:334
double n2[3]
Definition: libmmgtypes.h:295
double n1[3]
Definition: libmmgtypes.h:295