Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
enforcement_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*/
23#include "libmmg2d_private.h"
24
25
35 MMG5_pTria pt,pt1;
36 MMG5_pEdge ped;
37 MMG5_pPoint ppt;
38 MMG5_int list[MMG5_TRIA_LMAX],list2[3];
39 MMG5_int k,l,kk,nex,kdep,lon,iel;
40 int iare,ied;
41 MMG5_int ia,ib,ilon,rnd,idep,*adja,ir,adj;
42 int8_t i,i1,i2,j;
43// int iadr2,*adja2,ndel,iadr,ped0,ped1;
44 static int8_t mmgWarn0=0,mmgWarn1=0,mmgWarn2=0,mmgWarn3=0;
45 static int8_t mmgWarn4=0,mmgWarn5=0,mmgWarn6=0,mmgWarn7=0;
46 static int8_t mmgWarn8=0;
47
48 nex = 0;
49
50 /* Associate seed to each point in the mesh */
51 for (k=1; k<=mesh->np; k++) {
52 ppt = &mesh->point[k];
53 if ( MG_VOK(ppt) ) ppt->s = 0;
54 }
55
56 for (k=1; k<=mesh->nt; k++) {
57 pt = &mesh->tria[k];
58 if ( !MG_EOK(pt) ) continue;
59 for (i=0; i<3; i++)
60 mesh->point[pt->v[i]].s = k;
61 }
62
63 /* Check for the existing edges in the mesh */
64 /* No command for identifying whether an edge is valid or not? */
65 for(k=1; k<=mesh->na; k++) {
66 ped = &mesh->edge[k];
67 if ( !ped->a ) continue;
68 if ( ped->base < 0 ) {
69 nex++;
70 continue;
71 }
72
73 ppt = &mesh->point[ped->a];
74 kdep = ppt->s;
75 pt = &mesh->tria[kdep];
76
77 if ( pt->v[0] == ped->a )
78 j=0;
79 else if ( pt->v[1] == ped->a )
80 j=1;
81 else
82 j=2;
83
84 int8_t dummy;
85 lon = MMG5_boulet(mesh,kdep,j,list,0,&dummy);
86
87 if ( lon <= 0 ) {
88 if ( !mmgWarn0 ) {
89 mmgWarn0=1;
90 fprintf(stderr,"\n ## Error: %s: at least 1 wrong ball "
91 "(point %" MMG5_PRId " of triangle %" MMG5_PRId ").\n",__func__,
92 MMG2D_indPt(mesh, mesh->tria[kdep].v[j]),MMG2D_indElt(mesh,kdep));
93 }
94 return 0;
95 }
96
97 for (l=0; l<lon; l++) {
98 iel = list[l] / 3;
99 pt = &mesh->tria[iel];
100 i = list[l] % 3;
101 i1 = MMG5_inxt2[i];
102 i2 = MMG5_iprv2[i];
103
104 if ( pt->v[i1] == ped->b ) {
105 ped->base = -1;
106 nex++;
107 break;
108 }
109 else if ( pt->v[i2] == ped->b ) {
110 ped->base = -1;
111 nex++;
112 break;
113 }
114 }
115
116 if ( l >= lon ) {
117 if ( (mesh->info.imprim > 5) && (!mmgWarn1) ) {
118 mmgWarn1 = 1;
119 fprintf(stderr,"\n ## Warning: %s: at least 1 missing edge (%" MMG5_PRId " %" MMG5_PRId ").\n",
120 __func__,MMG2D_indPt(mesh,ped->a),MMG2D_indPt(mesh,ped->b));
121 }
122 ped->base = kdep;
123 }
124 }
125
127 if ( nex != mesh->na ) {
128 if(mesh->info.imprim > 5)
129 printf(" ** number of missing edges : %" MMG5_PRId "\n",mesh->na-nex);
130
131 for (kk=1; kk<=mesh->na; kk++) {
132 ped = &mesh->edge[kk];
133 if ( !ped->a || ped->base < 0 ) continue;
134 ia = ped->a;
135 ib = ped->b;
136 kdep = ped->base;
137
138 if(mesh->info.ddebug)
139 printf("\n -- edge enforcement %" MMG5_PRId " %" MMG5_PRId "\n",ia,ib);
140
141 /* List of the triangles intersected by the edge */
142 if ( !(lon=MMG2D_locateEdge(mesh,ia,ib,&kdep,list)) ) {
143 if ( mesh->info.ddebug && (!mmgWarn2) ) {
144 fprintf(stderr,"\n ## Error: %s: at least 1 edge not found.\n",
145 __func__);
146 mmgWarn2=1;
147 }
148 return 0;
149 }
150
151 /* Failure */
152 if ( !( lon < 0 || lon == 4 ) ) {
153 if ( mesh->info.ddebug && (!mmgWarn3) ) {
154 mmgWarn3=1;
155 fprintf(stderr,"\n ## Error: %s: Unable to force at least"
156 " 1 edge (%" MMG5_PRId " %" MMG5_PRId " -- %" MMG5_PRId ").\n",__func__,MMG2D_indPt(mesh,ia),
157 MMG2D_indPt(mesh,ib),lon);
158 }
159 return 0;
160 }
161
162 /* Insertion of the edge */
163 lon = -lon;
164
165 /* Considered edge actually exists */
166 if ( lon == 4 ) {
167 if ( mesh->info.ddebug && (!mmgWarn4) ) {
168 mmgWarn4=1;
169 fprintf(stderr,"\n ## Warning: %s: existing edge.\n",__func__);
170 }
171 }
172 if( (!mmgWarn5) && (lon>MMG5_TRIA_LMAX) ) {
173 mmgWarn5 = 1;
174 fprintf(stderr,"\n ## Error: %s: at least 1 edge intersecting too many"
175 " triangles (%" MMG5_PRId ")\n",__func__,lon);
176 }
177 if ( lon<2 ) {
178 if ( mesh->info.ddebug && (!mmgWarn6) ) {
179 mmgWarn6 = 1;
180 fprintf(stderr,"\n ## Warning: %s: few edges... %" MMG5_PRId "\n",__func__,lon);
181 }
182 }
183
184 /* Randomly swap edges in the list, while... */
185 ilon = lon;
186 srand(time(NULL));
187
188 while ( ilon > 0 ) {
189 rnd = ( rand() % lon );
190 k = list[rnd] / 3;
191
192 /* Check for triangle k in the pipe until one triangle with base+1 is met (indicating that it is
193 crossed by the considered edge) */
194 l = 0;
195 while ( l++ < lon ) {
196 pt = &mesh->tria[k];
197 if ( pt->base == mesh->base+1 ) break;
198 k = list[(++rnd)%lon] / 3;
199 }
200
201 assert ( l <= lon );
202 idep = list[rnd] % 3;
203 // if(mesh->info.ddebug) printf("i= %" MMG5_PRId " < %" MMG5_PRId " ? on demarre avec %" MMG5_PRId "\n",i,lon+1,k);
204 adja = &mesh->adja[3*(k-1)+1];
205
206 for (i=0; i<3; i++) {
207 ir = (idep+i) % 3;
208
209 /* Check the adjacent triangle in the pipe */
210 adj = adja[ir] / 3;
211 pt1 = &mesh->tria[adj];
212 if ( pt1->base != (mesh->base+1) ) continue;
213
214 /* Swap edge ir in triangle k, corresponding to a situation where both triangles are to base+1 */
215 if ( !MMG2D_swapdelone(mesh,sol,k,ir,1e+4,list2) ) {
216 if ( mesh->info.ddebug && (!mmgWarn7) ) {
217 mmgWarn7 = 1;
218 fprintf(stderr,"\n ## Warning: %s: unable to swap at least 1"
219 " edge.\n",__func__);
220 }
221 continue;
222 }
223
224 /* Is new triangle intersected by ia-ib ?? */
225 for (ied=1; ied<3; ied++) {
226 iare = MMG2D_cutEdgeTriangle(mesh,list2[ied],ia,ib);
227 if ( !iare ) {
228 /* tr not in pipe */
229 ilon--;
230 if ( mesh->info.ddebug && (!mmgWarn8) ) {
231 mmgWarn8 = 1;
232 fprintf(stderr,"\n ## Warning: %s: at least 1 triangle (%" MMG5_PRId ")"
233 " not intersected ==> %" MMG5_PRId "\n",__func__,
234 MMG2D_indElt(mesh,list2[ied]),ilon);
235 }
236 mesh->tria[list2[ied]].base = mesh->base;
237 }
238 else if ( iare < 0 ) {
239 /* ia-ib is one edge of k */
240 mesh->tria[list2[ied]].base = mesh->base;
241 ilon -= 2;
242 }
243 else {
244 if ( mesh->info.ddebug )
245 printf(" ** tr intersected %" MMG5_PRId " \n",list2[ied]);
246 mesh->tria[list2[ied]].base = mesh->base+1;
247 }
248 }
249 break;
250 }
251 }
252 }
253 }
254
255 /* Reset ->s field of vertices */
256 for (k=1; k<=mesh->np; k++) {
257 ppt = &mesh->point[k];
258 if ( MG_VOK(ppt) ) ppt->s = 0;
259 }
260
261/* //check if there are more bdry edges.. and delete tr */
262/* #warning a optimiser en mettant un pile et un while */
263/* //printf("tr 1 : %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",mesh->tria[1].v[0],mesh->tria[1].v[1],mesh->tria[1].v[2]); */
264/* do { */
265/* ndel=0; */
266/* for(k=1 ; k<=mesh->nt ; k++) { */
267/* pt = &mesh->tria[k]; */
268/* if(!pt->v[0]) continue; */
269/* iadr = 3*(k-1) + 1; */
270/* adja = &mesh->adja[iadr]; */
271
272/* for(i=0 ; i<3 ; i++) { */
273/* if(adja[i]) continue; */
274/* ped0 = pt->v[MMG2D_iare[i][0]]; */
275/* ped1 = pt->v[MMG2D_iare[i][1]]; */
276/* for(j=1 ; j<=mesh->na ; j++) { */
277/* ped = &mesh->edge[j]; */
278/* if((ped->a == ped0 && ped->b==ped1) || (ped->b == ped0 && ped->a==ped1)) break; */
279/* } */
280/* if(j<=mesh->na) */
281/* continue; */
282/* else */
283/* break; */
284/* } */
285/* if(i==3) continue; */
286 /* fprintf(stdout,"WARNING BDRY EDGES MISSING : DO YOU HAVE DUPLICATED VERTEX ? %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n", */
287/* pt->v[0],pt->v[1],pt->v[2]); */
288/* for(i=0 ; i<3 ; i++) { */
289/* if(!adja[i]) continue; */
290/* iadr2 = 3*(adja[i]/3-1) + 1; */
291/* adja2 = &mesh->adja[iadr2]; */
292/* adja2[adja[i]%3] = 0; */
293/* } */
294/* MMG2D_delElt(mesh,k); */
295/* ndel++; */
296
297/* } */
298/* } while(ndel); */
299
300 return 1;
301}
MMG5_pMesh MMG5_pSol * sol
MMG5_pMesh * mesh
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 MMG2D_bdryenforcement(MMG5_pMesh mesh, MMG5_pSol sol)
MMG5_int MMG2D_indPt(MMG5_pMesh mesh, MMG5_int kp)
Definition: tools_2d.c:70
int MMG2D_swapdelone(MMG5_pMesh, MMG5_pSol, MMG5_int, int8_t, double, MMG5_int *)
Definition: swapar_2d.c:39
int MMG2D_cutEdgeTriangle(MMG5_pMesh, MMG5_int, MMG5_int, MMG5_int)
Definition: locate_2d.c:129
int MMG2D_locateEdge(MMG5_pMesh, MMG5_int, MMG5_int, MMG5_int *, MMG5_int *)
Definition: locate_2d.c:329
MMG5_int MMG2D_indElt(MMG5_pMesh mesh, MMG5_int kel)
Definition: tools_2d.c:46
#define MG_EOK(pt)
static const uint8_t MMG5_iprv2[3]
#define MMG5_TRIA_LMAX
static const uint8_t MMG5_inxt2[6]
#define MG_VOK(ppt)
Structure to store edges of a MMG mesh.
Definition: libmmgtypes.h:305
MMG5_int b
Definition: libmmgtypes.h:306
MMG5_int base
Definition: libmmgtypes.h:308
MMG5_int a
Definition: libmmgtypes.h:306
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
MMG5_int np
Definition: libmmgtypes.h:612
MMG5_pEdge edge
Definition: libmmgtypes.h:649
MMG5_int na
Definition: libmmgtypes.h:612
Structure to store points of a MMG mesh.
Definition: libmmgtypes.h:270
MMG5_int s
Definition: libmmgtypes.h:283
MMG5_int base
Definition: libmmgtypes.h:336
MMG5_int v[3]
Definition: libmmgtypes.h:334