Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
locate_2d.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*/
32#include "libmmg2d_private.h"
33#define EPST -1e-18
34
35/* Calculate the barycentric coordinates of point P(c[0],c[1]) in tria pt and the associated determinant */
36/* l1 = barycentric coordinate with respect to p1, l2 = barycentric coordinate with respect to p2 */
37int MMG2D_coorbary(MMG5_pMesh mesh,MMG5_pTria pt,double c[2],double* det,double* l1,double* l2) {
38 MMG5_pPoint p1,p2,p3;
39 double b2,b3;
40 static int8_t mmgWarn0=0;
41
42 p1 = &mesh->point[pt->v[0]];
43 p2 = &mesh->point[pt->v[1]];
44 p3 = &mesh->point[pt->v[2]];
45
46 /* Calculate det (p2-p1,p3-p1) */
47 *det = (p2->c[0]-p1->c[0])*(p3->c[1]-p1->c[1]) - (p2->c[1]-p1->c[1])*(p3->c[0]-p1->c[0]);
48 if ( *det < MMG5_EPSD ) {
49 if ( !mmgWarn0 ) {
50 mmgWarn0 = 1;
51 fprintf(stderr,"\n ## Warning: %s: at least 1 flat triangle. abort.\n",
52 __func__);
53 }
54 return 0;
55 }
56 *det = 1.0 / (*det);
57
58 b2 = (c[0]-p1->c[0])*(p3->c[1]-p1->c[1]) - (c[1]-p1->c[1])*(p3->c[0]-p1->c[0]);
59 b3 = (p2->c[0]-p1->c[0])*(c[1]-p1->c[1]) -(p2->c[1]-p1->c[1])*(c[0]-p1->c[0]);
60 b2 *= (*det);
61 b3 *= (*det);
62 *l1 = 1.0 - (b2+b3);
63 *l2 = b2;
64
65 return 1;
66}
67
69MMG5_int MMG2D_isInTriangle(MMG5_pMesh mesh,MMG5_int k,double c[2]) {
70 MMG5_pTria pt;
71 double det,l1,l2,l3;
72 int8_t ier;
73
74 pt = &mesh->tria[k];
75 if ( !MG_EOK(pt) ) return 0;
76
77 ier = MMG2D_coorbary(mesh,pt,&c[0],&det,&l1,&l2);
78 if ( !ier )
79 return 0;
80
81 l3 = 1.0 - (l1+l2);
82 if ( l3>EPST && l1>EPST && l2>EPST) return k;
83 else return 0;
84}
85
86/* Check whether edge ppa-ppb crosses triangles pt (in the sense that two edges
87 of this triangle are crossed by (ppa-ppb), or only one, and ppa or ppb is a
88 vertex of pt; if at least one edge is crossed by ia-ib, return i+1, where i
89 is the index of one of the crossed edges */
91 double la[3],lb[3],det;
92 int icompt,ireturn;
93 int8_t ier,i;
94
95 ier = MMG2D_coorbary(mesh,pt,ppa->c,&det,&la[0],&la[1]);
96 if ( !ier ) return 0;
97 la[2] = 1.0-(la[0]+la[1]);
98
99 ier = MMG2D_coorbary(mesh,pt,ppb->c,&det,&lb[0],&lb[1]);
100 if ( !ier ) return 0;
101 lb[2] = 1.0-(lb[0]+lb[1]);
102
103 /* Check whether ppa or ppb is a vertex of pt */
104 for (i=0; i<3; i++) {
105 if ( fabs(la[i]-1.0) < 1.0e-12 ) {
106 if ( lb[i] < 0.0 ) return i+1;
107 else return 0;
108 }
109 if ( fabs(lb[i]-1.0) < 1.0e-12) {
110 if ( la[i] < 0.0 ) return i+1;
111 else return 0;
112 }
113 }
114
115 icompt = 0;
116 for (i=0; i<3; i++) {
117 if ( ( la[i] >= 0.0 && lb[i] <= 0.0 ) || ( la[i] <= 0.0 && lb[i] >= 0.0 ) ) {
118 ireturn = i+1;
119 icompt++;
120 }
121 }
122
123 if ( icompt > 1 ) return ireturn;
124 return 0;
125}
126
127/* Return i+1>0 if Edge ia-ib intersects triangle k at edge i, 0 if
128 it does not intersect k, and return -3 if edge ia-ib is one edge of k*/
129int MMG2D_cutEdgeTriangle(MMG5_pMesh mesh,MMG5_int k,MMG5_int ia,MMG5_int ib) {
130 MMG5_pTria pt;
131 MMG5_pPoint p1,p2,p3,ppa,ppb;
132 double a11,a21,a12,a22,area1,area2,area3,prod1,prod2,prod3;
133 int ibreak,iare;
134 int8_t i;
135
136 ppa = &mesh->point[ia];
137 ppb = &mesh->point[ib];
138
139 pt = &mesh->tria[k];
140 if ( !MG_EOK(pt) ) return 0;
141 ibreak = 0;
142
143 if ( pt->v[0] == ib || pt->v[1] == ib || pt->v[2] == ib) ibreak = 1;
144
145 p1 = &mesh->point[pt->v[0]];
146 p2 = &mesh->point[pt->v[1]];
147 p3 = &mesh->point[pt->v[2]];
148
149 /* Calculation of the areas ia,ib,pi*/
150 a11 = ppb->c[0] - ppa->c[0];
151 a21 = ppb->c[1] - ppa->c[1];
152
153 a12 = p1->c[0] - ppa->c[0];
154 a22 = p1->c[1] - ppa->c[1];
155 area1 = a11*a22 - a12*a21;
156
157 a12 = p2->c[0] - ppa->c[0];
158 a22 = p2->c[1] - ppa->c[1];
159 area2 = a11*a22 - a12*a21;
160
161 a12 = p3->c[0] - ppa->c[0];
162 a22 = p3->c[1] - ppa->c[1];
163 area3 = a11*a22 - a12*a21;
164
165 prod1 = area1*area2;
166 prod2 = area3*area2;
167 prod3 = area3*area1;
168
169 /* Both edges p2p3 and p1p3 corresponding to prod2 and prod3 are cut by edge ia,ib */
170 if ( prod1 > 0 && ((prod2 < 0 || prod3 < 0))) {
171 if ( (iare = MMG2D_cutEdge(mesh,pt,ppa,ppb)) ) {
172 return iare;
173 }
174 }
175
176 /* Both edges corresponding to prod1 and prod3 are cut by edge ia,ib */
177 if ( prod2 > 0 && ((prod1 < 0 || prod3 < 0))) {
178 if ( (iare = MMG2D_cutEdge(mesh,pt,ppa,ppb)) ) {
179 return iare;
180 }
181 }
182
183 /* Both edges corresponding to prod1 and prod2 are cut by edge ia,ib */
184 if ( prod3 > 0 && ((prod2 < 0 || prod1 < 0))) {
185 if ( (iare = MMG2D_cutEdge(mesh,pt,ppa,ppb)) ) {
186 return iare;
187 }
188 }
189
190 /* Case where one vertex of pt is ia */
191 for(i=0; i<3; i++){
192 if ( pt->v[i] == ia || ibreak ) {
193 /* One vertex is ia, and the opposite edge is frankly crossed */
194 if ( (prod1 < 0) || (prod2 < 0) || (prod3 < 0) ) {
195 if ( (iare = MMG2D_cutEdge(mesh,pt,ppa,ppb)) ) {
196 return iare;
197 }
198 }
199 else {
200 /*check if ia-ib edge de pt*/
201 if ( ibreak && ( pt->v[(i+1)%3] == ia || pt->v[(i+2)%3] == ia ) ) {
202 return -3;
203 }
204 else if ( pt->v[i] == ia && ( pt->v[(i+1)%3] == ib || pt->v[(i+2)%3] == ib ) ) {
205 return -3;
206 }
207 }
208 }
209 }
210
211 return 0;
212}
213
221MMG5_int MMG2D_findTria(MMG5_pMesh mesh,MMG5_int ip) {
222 MMG5_pTria pt,pt1;
223 MMG5_int iel,base,iadr,*adja,iter,ier;
224 int mvDir[3],jel,i;
225 double l1,l2,l3,det,eps;
226 static int8_t mmgWarn0 = 0;
227
228 ++mesh->base;
229 base = ++mesh->base;
230 iter = 0;
231 iel = 1;
232 do {
233 mvDir[0] = mvDir[1] = mvDir[2] = 0;
234 iter++;
235 pt = &mesh->tria[iel];
236 if ( !MG_EOK(pt) ) {
237 iel++;
238 if ( iel > mesh->nt ) return 0;
239 continue;
240 }
241
242 if ( pt->base == base) {
243 if ( !mmgWarn0 ) {
244 mmgWarn0 = 1;
245 fprintf(stderr,"\n ## Warning: %s: numerical problem, please make"
246 " a bug report.\n",__func__);
247 }
248 return iel;
249 }
250 /* Check whether ip is one of the vertices of pt */
251 if ( (pt->v[0] == ip) || (pt->v[1] == ip) || (pt->v[2] == ip) ) return iel;
252
253 pt->base = base;
254 iadr = 3*(iel-1)+1;
255 adja = &mesh->adja[iadr];
256
257 /*compute the barycentric coordinates*/
258 ier = MMG2D_coorbary(mesh,pt,mesh->point[ip].c,&det,&l1,&l2);
259 if ( !ier ) return 0;
260
261 l3 = 1-l1-l2;
262 /*warning -1e12 is too strict*/
263 eps = (-1e-9)*MMG2D_quickcal(mesh,pt);
264
265 /*find in which direction we can move*/
266 if (l1<eps)
267 mvDir[0] = 1;
268 if (l2<eps)
269 mvDir[1] = 1;
270 if (l3<eps)
271 mvDir[2] = 1;
272
273 /*if all the barycentric coordinates are positive, we find the triangle*/
274 if(!mvDir[0] && !mvDir[1] && !mvDir[2]) {
275 break;
276 }
277
278 /*first, try to move in an optimal direction*/
279 iel = 0;
280 for(i=0;i<3; i++) {
281 if (!mvDir[i]) continue;
282 jel = adja[i]/3;
283
284 if (!jel) continue;
285 pt1 = &mesh->tria[jel];
286
287 if(pt1->base == mesh->base) continue;
288 iel = jel;
289 break;
290 }
291
292 /*second, the optimal move is not possible, so try to move in one direction*/
293 if(i==3) {
294 for(i=0;i<3; i++) {
295 if (mvDir[i]) continue;
296 jel = adja[i]/3;
297 if (!jel) continue;
298 pt1 = &mesh->tria[jel];
299 if(pt1->base == mesh->base) continue;
300 iel = jel;
301 break;
302 }
303 }
304
305 /*we already see all the adj triangle so we can do nothing*/
306 if (iel == 0) {
307 iter = mesh->nt+1;
308 }
309 } while ( iter<=mesh->nt );
310
311 return iel;
312}
313
329int MMG2D_locateEdge(MMG5_pMesh mesh,MMG5_int ia,MMG5_int ib,MMG5_int* kdep,MMG5_int* list) {
330 MMG5_pTria pt;
331 MMG5_pPoint ppt1,ppt2,ppt3,ppt4,ppa,ppb;
332 double a[3],a11,a21,a12,a22,area1,area2,area3,prod1,prod2,prod3;
333 double niaib,npti;
334 MMG5_int iadr,*adja,k,ibreak,i,ncompt,lon,iare,ivert;
335 static int8_t mmgWarn=0;
336 //int ktemp;
337
338 k = *kdep;
339 ncompt = 0;
340 lon = 0;
341 ppa = &mesh->point[ia];
342 ppb = &mesh->point[ib];
343
344 pt = &mesh->tria[k];
345
346 ivert = 0;
347 if(pt->v[0]==ia || pt->v[1]==ia || pt->v[2]==ia) ivert = 1;
348
349 if ( !ivert ) {
350
351 if ( !(k = MMG2D_findTria(mesh,ia) ) ) {
352 return 0;
353 }
354 *kdep = k;
355 }
356
357 if ( mesh->info.ddebug || mesh->info.imprim > 6 )
358 printf(" Try to enforce edge %" MMG5_PRId " %" MMG5_PRId "\n",ia,ib);
359
360 mesh->base += 2;
361 do {
362 pt = &mesh->tria[k];
363
364 pt->base = mesh->base;
365 iadr = 3*(k-1)+1;
366 adja = &mesh->adja[iadr];
367 ibreak = 0;
368 ncompt++;
369
370 /* ib is a vertex of the current triangle */
371 if ( pt->v[0] == ib || pt->v[1] == ib || pt->v[2] == ib ) ibreak = 1;
372
373 ppt1 = &mesh->point[pt->v[0]];
374 ppt2 = &mesh->point[pt->v[1]];
375 ppt3 = &mesh->point[pt->v[2]];
376
377 /* Calculate the 3 areas (ia,ib,pi)*/
378 a11 = ppb->c[0] - ppa->c[0];
379 a21 = ppb->c[1] - ppa->c[1];
380 a12 = ppt1->c[0] - ppa->c[0];
381 a22 = ppt1->c[1] - ppa->c[1];
382 area1 = a11*a22 - a12*a21;
383
384 a12 = ppt2->c[0] - ppa->c[0];
385 a22 = ppt2->c[1] - ppa->c[1];
386 area2 = a11*a22 - a12*a21;
387
388 a12 = ppt3->c[0] - ppa->c[0];
389 a22 = ppt3->c[1] - ppa->c[1];
390 area3 = a11*a22 - a12*a21;
391
399 prod1 = area1*area2;
400 prod2 = area3*area2;
401 prod3 = area3*area1;
402
403 a[0] = area1;
404 a[1] = area2;
405 a[2] = area3;
406
408 /* Both edges p2p3 and p1p3 in pt have franck intersections with edge (ia - ib) */
409 if ( prod1 > 0.0 && ((prod2 < 0.0 || prod3 < 0.0))) { /*le tr est coupe par la droite ia-ib*/
410 if ( (iare = MMG2D_cutEdge(mesh,pt,ppa,ppb)) ) {
411 pt->base = mesh->base+1;
412 list[lon++] = 3*k + iare-1;
413 }
414 k = adja[0] / 3;
415 if ( ( mesh->tria[k].base >= mesh->base ) || !k ) {
416 k = adja[1] / 3;
417 if ( !iare && (mesh->tria[k].base >= mesh->base || !k ) ) {
418 k = adja[2] / 3;
419 if ( ( mesh->tria[k].base >= mesh->base ) )
420 k = 0;
421 }
422 else if ( ( mesh->tria[k].base >= mesh->base ) )
423 k = 0;
424 }
425 if ( ibreak ) break;
426 continue;
427 }
428
429 /* Both edges p1p2 and p1p3 in pt have franck intersections with edge (ia - ib) */
430 if ( prod2 > 0.0 && ((prod1 < 0.0 || prod3 < 0.0 ))) {
431 if ( (iare = MMG2D_cutEdge(mesh,pt,ppa,ppb)) ) {
432 pt->base = mesh->base+1;
433 list[lon++] = 3*k + iare-1;
434 }
435 k = adja[1] / 3;
436 if ((mesh->tria[k].base >= mesh->base) || !k) {
437 k = adja[2] / 3;
438 if ( !iare && (!k || mesh->tria[k].base >= mesh->base) ) {
439 k = adja[0] / 3;
440 if ( ( mesh->tria[k].base >= mesh->base ) )
441 k = 0;
442 }
443 else if ( ( mesh->tria[k].base >= mesh->base ) )
444 k = 0;
445 }
446 if ( ibreak ) break;
447 continue;
448 }
449
450 /* Both edges p1p2 and p2p3 in pt have franck intersections with edge (ia - ib) */
451 if ( prod3 > 0.0 && ((prod2 < 0.0 || prod1 < 0.0 ))) {
452 if ( (iare = MMG2D_cutEdge(mesh,pt,ppa,ppb)) ) {
453 pt->base = mesh->base+1;
454 list[lon++] = 3*k + iare-1;
455 }
456 k = adja[2] / 3;
457 if ( ( mesh->tria[k].base >= mesh->base ) || !k ) {
458 k = adja[0] / 3;
459 if ( !iare && (!k || mesh->tria[k].base >= mesh->base) ) {
460 k = adja[1] / 3;
461 if((mesh->tria[k].base >= mesh->base))
462 k = 0;
463 }
464 else if ( (mesh->tria[k].base >= mesh->base) )
465 k = 0;
466 }
467 if( ibreak ) break;
468 continue;
469 }
470
471 /* Case where ia or ib is one vertex in pt */
472 for(i=0; i<3; i++) {
473 iare = 0;
474 if ( pt->v[i] == ia || ibreak ) {
475 if ( (prod1 < 0.0) || (prod2 < 0.0) || (prod3 < 0.0) ) {
476 if ( (iare = MMG2D_cutEdge(mesh,pt,ppa,ppb)) ) {
477 pt->base = mesh->base+1;
478 list[lon++] = 3*k + iare-1;
479 }
480 else ibreak = 0;
481 }
482 else {
483 /* Check whether ia-ib is an edge in pt*/
484 if ( ibreak && ( pt->v[(i+1)%3] == ia || pt->v[(i+2)%3] == ia) ){
485 pt->base = mesh->base+1;
486 list[lon++] = 3*k;
487 ibreak = 3;
488 }
489 else if ( pt->v[i] == ia && ( pt->v[(i+1)%3] == ib || pt->v[(i+2)%3] == ib ) ) {
490 pt->base = mesh->base+1;
491 list[lon++] = 3*k;
492 ibreak = 3;
493 }
494 else if ( fabs(prod1)<MMG5_EPSD2 && fabs(prod2)<MMG5_EPSD2 && fabs(prod3)<MMG5_EPSD2) {
495 if ( (a[MMG5_inxt2[i]] < 0.0 && a[MMG5_iprv2[i]] > 0.0 )
496 || (a[MMG5_inxt2[i]] > 0.0 && a[MMG5_iprv2[i]] < 0.0 ) ) {
497
498 pt->base = mesh->base+1;
499 list[lon++] = 3*k;
500 ibreak = 3;
501 }
502 else if ( a[MMG5_inxt2[i]] > 0.0 && a[MMG5_iprv2[i]] > 0.0 ){
503 k = adja[MMG5_iprv2[i]] / 3;
504 //ibreak = 1;
505 break;
506 }
507 else {
508 //calcul de ||iaib|| et de ||ptiib|| avec aire(iaibpti)==0
509 niaib = sqrt(a11*a11+a21*a21 );
510 if ( fabs(a[MMG5_inxt2[i]]) > MMG5_EPSD ) {
511 ppt4 = &mesh->point[pt->v[MMG5_iprv2[i]]];
512 }
513 else {
514 ppt4 = &mesh->point[pt->v[MMG5_inxt2[i]]];
515 }
516 npti = sqrt((ppb->c[0]-ppt4->c[0])*(ppb->c[0]-ppt4->c[0])+
517 (ppb->c[1]-ppt4->c[1])*(ppb->c[1]-ppt4->c[1]));
518 if ( niaib > npti ) {
519 //on rajoute le triangle
520 pt->base = mesh->base+1;
521 list[lon++] = 3*k;
522 // ibreak = 3;
523 }
524 k = adja [MMG5_inxt2[i]] / 3;
525 //ibreak = 1;
526 break;
527 }
528 /* k = adja[ktemp]/3;
529 if (!k || mesh->tria[k].base>=mesh->base) {
530 k = adja[(ktemp+1)%3]/3;
531 if(!k || mesh->tria[k].base>=mesh->base) {
532 k = adja[(ktemp+2)%3]/3;
533 if(mesh->tria[k].base>=mesh->base) k=0;
534 }
535 }
536 ibreak=-10;*/
537 break;
538 } /*end if(fabs(prod1)<MMG5_EPSD2 && fabs(prod2)<MMG5_EPSD2 && fabs(prod3)<MMG5_EPSD2)*/
539 else { /*on choisit de passer par l'arete iaPi si aire(iaibPi) >0*/
540 assert ( pt->v[i] == ia );
541 if ( a[MMG5_inxt2[i]] > 0.0 )
542 iare = MMG5_iprv2[i];
543 else
544 iare = MMG5_inxt2[i];
545
546 k = adja[iare] / 3;
547 ibreak = 1;
548 break;
549 }
550 } /*end else de if((prod1 < 0) || (prod2 < 0) || (prod3 < 0))*/
551
552 if ( iare ) {
553 //ktemp = k;
554 k = adja[i] / 3;
555 if (!k || mesh->tria[k].base>=mesh->base || !mesh->tria[k].v[0]) {
556 k = adja[(i+1)%3]/3;
557 if(!k || mesh->tria[k].base>=mesh->base || !mesh->tria[k].v[0]) {
558 k = adja[(i+2)%3]/3;
559 if(mesh->tria[k].base>=mesh->base || !mesh->tria[k].v[0]) k=0;
560 }
561 }
562 }
563 else {
564 //ktemp = k;
565 k = adja[(i+1)%3] / 3;
566 if (!k || mesh->tria[k].base>=mesh->base || !mesh->tria[k].v[0]) {
567 k = adja[(i+2)%3]/3;
568 if(!k || mesh->tria[k].base>=mesh->base || !mesh->tria[k].v[0]) {
569 k = adja[(i+3)%3]/3;
570 if(mesh->tria[k].base>=mesh->base || !mesh->tria[k].v[0]) k=0;
571 }
572 }
573 }
574 ibreak++;
575 break;
576 }/*end if ia || ibreak;*/
577 }
578
579 if ( ibreak == 1 || ibreak == -10 ) continue;
580 if ( ibreak > 1 ) break;
581
582 /*a-t-on un pts sur l'arete iaib ?*/
583 if (fabs(area1) < MMG5_EPSD || fabs(area2) < MMG5_EPSD || fabs(area3) < MMG5_EPSD) {
584 if ( !mmgWarn ) {
585 mmgWarn = 1;
586 fprintf(stderr,"\n ## Error: %s: unexpected failure."
587 " Check your initial data and/or report the bug. lon:%" MMG5_PRId ". %e %e %e\n"
588 " tria %" MMG5_PRId ": %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId ",\n",
589 __func__,lon, area1,area2,area3,k,mesh->tria[k].v[0],
590 mesh->tria[k].v[1],mesh->tria[k].v[2]);
591 }
592 return 0;
593 }
594
595 //ktemp = k;
596 /* printf("adj (base) pour le tri %" MMG5_PRId " : %" MMG5_PRId "(%" MMG5_PRId ") %" MMG5_PRId "(%" MMG5_PRId ") %" MMG5_PRId "(%" MMG5_PRId ")\n",k,adja[0]/3,mesh->tria[adja[0]/3].base>=mesh->base */
597 /* ,adja[1]/3,mesh->tria[adja[1]/3].base>=mesh->base,adja[2]/3,mesh->tria[adja[2]/3].base>=mesh->base); */
598 k = adja[0] / 3;
599 if ((mesh->tria[k].base>=mesh->base) || !k || !mesh->tria[k].v[0]) {
600 k = adja[1] / 3;
601 if ((mesh->tria[k].base>=mesh->base) || !k || !mesh->tria[k].v[0]) {
602 k = adja[2] / 3;
603 if((mesh->tria[k].base>=mesh->base) || !k || !mesh->tria[k].v[0]) {
604 k=0;
605 }
606 }
607 }
608
609 }
610 while ( ncompt < mesh->nt );
611
612 assert ( ibreak );
613 lon = ( ibreak == 4 ) ? 4 : ((-1)*lon);
614 return lon;
615}
int ier
MMG5_pMesh * mesh
#define MMG5_EPSD
double MMG2D_quickcal(MMG5_pMesh, MMG5_pTria)
Definition: quality_2d.c:46
MMG5_int MMG2D_findTria(MMG5_pMesh mesh, MMG5_int ip)
Definition: locate_2d.c:221
MMG5_int MMG2D_isInTriangle(MMG5_pMesh mesh, MMG5_int k, double c[2])
Definition: locate_2d.c:69
int MMG2D_cutEdge(MMG5_pMesh mesh, MMG5_pTria pt, MMG5_pPoint ppa, MMG5_pPoint ppb)
Definition: locate_2d.c:90
int MMG2D_coorbary(MMG5_pMesh mesh, MMG5_pTria pt, double c[2], double *det, double *l1, double *l2)
Definition: locate_2d.c:37
int MMG2D_locateEdge(MMG5_pMesh mesh, MMG5_int ia, MMG5_int ib, MMG5_int *kdep, MMG5_int *list)
Definition: locate_2d.c:329
#define EPST
Definition: locate_2d.c:33
int MMG2D_cutEdgeTriangle(MMG5_pMesh mesh, MMG5_int k, MMG5_int ia, MMG5_int ib)
Definition: locate_2d.c:129
#define MG_EOK(pt)
static const uint8_t MMG5_iprv2[3]
static const uint8_t MMG5_inxt2[6]
#define MMG5_EPSD2
int8_t ddebug
Definition: libmmgtypes.h:532
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_Info info
Definition: libmmgtypes.h:651
MMG5_pPoint point
Definition: libmmgtypes.h:641
MMG5_int * adja
Definition: libmmgtypes.h:624
MMG5_int base
Definition: libmmgtypes.h:616
MMG5_int nt
Definition: libmmgtypes.h:612
MMG5_pTria tria
Definition: libmmgtypes.h:647
Structure to store points of a MMG mesh.
Definition: libmmgtypes.h:270
double c[3]
Definition: libmmgtypes.h:271
MMG5_int base
Definition: libmmgtypes.h:336
MMG5_int v[3]
Definition: libmmgtypes.h:334