Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
boulep.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
35#include "mmgcommon_private.h"
36
37extern MMG5_Info info;
38
52int MMG5_boulep(MMG5_pMesh mesh,MMG5_int start,int ip,MMG5_int *adja, MMG5_int *list, MMG5_int *tlist) {
53 MMG5_pTria pt;
54 int ilist;
55 MMG5_int *adj,k;
56 int8_t i,i1,i2;
57
58 pt = &mesh->tria[start];
59 if ( !MG_EOK(pt) ) return 0;
60 list[0] = pt->v[ip];
61 ilist = 0;
62
63 /* store neighbors */
64 k = start;
65 i = ip;
66 i1 = MMG5_inxt2[i];
67 i2 = MMG5_iprv2[i];
68 do {
69 if ( ilist > MMG5_LMAX-2 ) return -ilist;
70 tlist[ilist] = k;
71 ilist++;
72 list[ilist] = pt->v[i2];
73
74 adj = &adja[3*(k-1)+1];
75 k = adj[i1] / 3;
76 i2 = adj[i1] % 3;
77 i1 = MMG5_iprv2[i2];
78 pt = &mesh->tria[k];
79
80 }
81 while ( k && k != start );
82 if ( k > 0 ) return ilist;
83
84 /* reverse loop */
85 k = start;
86 i = ip;
87 pt = &mesh->tria[k];
88 i1 = MMG5_inxt2[i];
89 i2 = MMG5_inxt2[i1];
90 do {
91 if ( ilist > MMG5_LMAX-2 ) return -ilist;
92 ilist++;
93 list[ilist] = pt->v[i1];
94
95 adj = &adja[3*(k-1)+1];
96 k = adj[i2] / 3;
97 i1 = adj[i2] % 3;
98 i2 = MMG5_iprv2[i1];
99 pt = &mesh->tria[k];
100
101 tlist[ilist-1] = k;
102 }
103 while ( k > 0 );
104
105 return ilist;
106}
107
119int MMG5_boulen(MMG5_pMesh mesh,MMG5_int *adjt,MMG5_int start,int ip,double *nn) {
120 MMG5_pTria pt;
121 double n[3],dd;
122 MMG5_int *adja,k;
123 int8_t i,i1,i2;
124
125 pt = &mesh->tria[start];
126 if ( !MG_EOK(pt) ) return 0;
127 nn[0] = nn[1] = nn[2] = 0.0;
128
129 /* Ensure point is manifold (i.e., all edges passing through point are
130 * manifold */
131 assert ( (!(MG_NOM & mesh->point[pt->v[ip]].tag)) && "Unexpected non-manifold point" );
132
133 /* store neighbors */
134 k = start;
135 i = ip;
136 i1 = MMG5_inxt2[i];
137 do {
138 pt = &mesh->tria[k];
139 MMG5_nortri(mesh,pt,n);
140 nn[0] += n[0]; nn[1] += n[1]; nn[2] += n[2];
141
142 if ( pt->tag[i1] & MG_GEO ) {
143 k = 0;
144 break;
145 }
146 adja = &adjt[3*(k-1)+1];
147 k = adja[i1] / 3;
148 i2 = adja[i1] % 3;
149 i1 = MMG5_iprv2[i2];
150 }
151 while ( k && k != start );
152
153 if ( k == 0 ) {
154 k = start;
155 i = ip;
156 i2 = MMG5_iprv2[i];
157 pt = &mesh->tria[k];
158 do {
159 if ( pt->tag[i2] & MG_GEO ) break;
160
161 adja = &adjt[3*(k-1)+1];
162 k = adja[i2] / 3;
163 if ( k == 0 ) break;
164 i1 = adja[i2] % 3;
165 i2 = MMG5_inxt2[i1];
166 pt = &mesh->tria[k];
167
168 MMG5_nortri(mesh,pt,n);
169
170 nn[0] += n[0]; nn[1] += n[1]; nn[2] += n[2];
171 }
172 while ( k && k != start );
173 }
174
175 /* normalize */
176 dd = nn[0]*nn[0] + nn[1]*nn[1] + nn[2]*nn[2];
177 if ( dd > MMG5_EPSD2 ) {
178 dd = 1.0 / sqrt(dd);
179 nn[0] *= dd;
180 nn[1] *= dd;
181 nn[2] *= dd;
182 return 1;
183 }
184
185 return 0;
186}
187
199int MMG5_boulec(MMG5_pMesh mesh,MMG5_int *adjt,MMG5_int start,int ip,double *tt) {
200 MMG5_pTria pt;
201 MMG5_pPoint p0,p1,p2;
202 double dd;
203 MMG5_int *adja,k;
204 int8_t i,i1,i2;
205
206 pt = &mesh->tria[start];
207 if ( !MG_EOK(pt) ) return 0;
208 p0 = &mesh->point[pt->v[ip]];
209 if ( !MG_EDG(p0->tag) ) return 0;
210
211 /* check other triangle vertices */
212 k = start;
213 i = ip;
214 i1 = MMG5_inxt2[i];
215 i2 = MMG5_iprv2[i];
216 p1 = p2 = 0;
217 do {
218 pt = &mesh->tria[k];
219 if ( MG_EDG(pt->tag[i1]) ) {
220 p1 = &mesh->point[pt->v[i2]];
221 k = 0;
222 break;
223 }
224 adja = &adjt[3*(k-1)+1];
225 k = adja[i1] / 3;
226 i2 = adja[i1] % 3;
227 i1 = MMG5_iprv2[i2];
228 }
229 while ( k && k != start );
230
231 /* check if open boundary hit */
232 if ( k == 0 ) {
233 k = start;
234 i = ip;
235 i1 = MMG5_inxt2[i];
236 i2 = MMG5_iprv2[i];
237 do {
238 pt = &mesh->tria[k];
239 if ( MG_EDG(pt->tag[i2]) ) {
240 p2 = &mesh->point[pt->v[i1]];
241 break;
242 }
243 adja = &adjt[3*(k-1)+1];
244 k = adja[i2] / 3;
245 i1 = adja[i2] % 3;
246 i2 = MMG5_inxt2[i1];
247 }
248 while ( k );
249 }
250
251 if ( !p1 || !p2 )
252 return 0;
253 else if ( p1 == p2 )
254 p2 = p0;
255
256 /* tangent approx */
257 tt[0] = p2->c[0] - p1->c[0];
258 tt[1] = p2->c[1] - p1->c[1];
259 tt[2] = p2->c[2] - p1->c[2];
260 dd = tt[0]*tt[0] + tt[1]*tt[1] + tt[2]*tt[2];
261 if ( dd > MMG5_EPSD2 ) {
262 dd = 1.0 / sqrt(dd);
263 tt[0] *= dd;
264 tt[1] *= dd;
265 tt[2] *= dd;
266 }
267
268 return 1;
269}
270
287int MMG5_bouler(MMG5_pMesh mesh,MMG5_int *adjt,MMG5_int start,int ip,
288 MMG5_int *list,MMG5_int *listref,int *ng,int *nr,int lmax) {
289 MMG5_pTria pt;
290 MMG5_int *adja,k;
291 MMG5_int ns;
292 int8_t i,i1,i2;
293
294 pt = &mesh->tria[start];
295 if ( !MG_EOK(pt) ) return 0;
296
297 /* check other triangle vertices */
298 k = start;
299 i = ip;
300 *ng = *nr = ns = 0;
301 do {
302 i1 = MMG5_inxt2[i];
303 if ( MG_EDG(pt->tag[i1])) {
304 i2 = MMG5_iprv2[i];
305 if ( pt->tag[i1] & MG_GEO )
306 *ng = *ng + 1;
307 else if ( pt->tag[i1] & MG_REF )
308 *nr = *nr + 1;
309 ns++;
310 list[ns] = pt->v[i2];
311 listref[ns] = pt->edg[i1];
312 if ( ns > lmax-2 ) return -ns;
313 }
314 adja = &adjt[3*(k-1)+1];
315 k = adja[i1] / 3;
316 i = adja[i1] % 3;
317 i = MMG5_inxt2[i];
318 pt = &mesh->tria[k];
319 }
320 while ( k && k != start );
321
322 /* reverse loop */
323 if ( k != start ) {
324 k = start;
325 i = ip;
326 do {
327 pt = &mesh->tria[k];
328 i2 = MMG5_iprv2[i];
329 if ( MG_EDG(pt->tag[i2]) ) {
330 i1 = MMG5_inxt2[i];
331 if ( pt->tag[i2] & MG_GEO )
332 *ng = *ng + 1;
333 else if ( pt->tag[i2] & MG_REF )
334 *nr = *nr + 1;
335 ns++;
336 list[ns] = pt->v[i1];
337 listref[ns] = pt->edg[i2];
338 if ( ns > lmax-2 ) return -ns;
339 }
340 adja = &adjt[3*(k-1)+1];
341 k = adja[i2] / 3;
342 i = adja[i2] % 3;
343 i = MMG5_iprv2[i];
344 }
345 while ( k && k != start );
346 }
347 return ns;
348}
349
363int MMG5_boulet(MMG5_pMesh mesh,MMG5_int start,int ip,MMG5_int *list,int8_t s,int8_t *opn) {
364 MMG5_int *adja,k;
365 int ilist;
366 int8_t i,i1,i2;
367
368 ilist = 0;
369 *opn = 0;
370
371 /* store neighbors */
372 k = start;
373 i = ip;
374 do {
375 if ( ilist > MMG5_TRIA_LMAX-2 ) return 0;
376 list[ilist] = 3*k + i;
377 ++ilist;
378
379 adja = &mesh->adja[3*(k-1)+1];
380 i1 = MMG5_inxt2[i];
381 k = adja[i1] / 3;
382 i = adja[i1] % 3;
383 i = MMG5_inxt2[i];
384 }
385 while ( k && k != start );
386 if ( k > 0 ) return ilist;
387
388 if ( s ) {
389 MMG5_pTria pt;
390 MMG5_pPoint ppt;
391 pt = &mesh->tria[start];
392 ppt = &mesh->point[pt->v[ip]];
393
394 /* Point along non-manifold edge: we are not able to loop around edge */
395 if ( ppt->tag & MG_NOM )
396 return 0;
397 }
398
399 /* check if boundary hit */
400 k = start;
401 i = ip;
402 *opn = 1;
403 do {
404 adja = &mesh->adja[3*(k-1)+1];
405 i2 = MMG5_iprv2[i];
406 k = adja[i2] / 3;
407 if ( k == 0 ) break;
408 i = adja[i2] % 3;
409 i = MMG5_iprv2[i];
410
411 if ( ilist > MMG5_TRIA_LMAX-2 ) return 0;
412 list[ilist] = 3*k + i;
413 ilist++;
414 }
415 while ( k );
416
417 return ilist;
418}
MMG5_pMesh * mesh
int MMG5_boulec(MMG5_pMesh mesh, MMG5_int *adjt, MMG5_int start, int ip, double *tt)
Definition: boulep.c:199
MMG5_Info info
int MMG5_boulet(MMG5_pMesh mesh, MMG5_int start, int ip, MMG5_int *list, int8_t s, int8_t *opn)
Definition: boulep.c:363
int MMG5_boulep(MMG5_pMesh mesh, MMG5_int start, int ip, MMG5_int *adja, MMG5_int *list, MMG5_int *tlist)
Definition: boulep.c:52
int MMG5_bouler(MMG5_pMesh mesh, MMG5_int *adjt, MMG5_int start, int ip, MMG5_int *list, MMG5_int *listref, int *ng, int *nr, int lmax)
Definition: boulep.c:287
int MMG5_boulen(MMG5_pMesh mesh, MMG5_int *adjt, MMG5_int start, int ip, double *nn)
Definition: boulep.c:119
#define MG_GEO
#define MG_EOK(pt)
#define MG_EDG(tag)
static const uint8_t MMG5_iprv2[3]
#define MMG5_TRIA_LMAX
#define MMG5_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
#define MMG5_EPSD2
#define MG_REF
Store input parameters of the run.
Definition: libmmgtypes.h:516
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_pPoint point
Definition: libmmgtypes.h:641
MMG5_int * adja
Definition: libmmgtypes.h:624
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
double c[3]
Definition: libmmgtypes.h:271
MMG5_int edg[3]
Definition: libmmgtypes.h:339
int16_t tag[3]
Definition: libmmgtypes.h:342
MMG5_int v[3]
Definition: libmmgtypes.h:334