Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
chkmsh_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
38
48int MMG5_mmgsChkmsh(MMG5_pMesh mesh,int severe,MMG5_int base) {
49 MMG5_pPoint ppt;
50 MMG5_pTria pt1,pt2;
51 MMG5_int adj,adj1,k,kk,l,nk,ip;
52 MMG5_int *adja,*adjb,list[MMG5_TRIA_LMAX+2];
53 int i,j,lon,len;
54 int8_t voy,voy1,i1,i2,j1,j2;
55 static int8_t mmgErr0=0,mmgErr1=0,mmgErr2=0,mmgErr3=0,mmgErr4=0;
56 static int8_t mmgErr5=0,mmgErr6=0,mmgErr7=0;
57
58 for (k=1; k<=mesh->nt; k++) {
59 pt1 = &mesh->tria[k];
60 if ( !MG_EOK(pt1) ) continue;
61 adja = &mesh->adja[3*(k-1)+1];
62
63 for (i=0; i<3; i++) {
64 if ( !adja[i] ) continue;
65 i1 = MMG5_inxt2[i];
66 i2 = MMG5_iprv2[i];
67 adj = adja[i] / 3;
68 voy = adja[i] % 3;
69 if ( !adj && !(pt1->tag[i] & MG_GEO) ) {
70 if ( !mmgErr0 ) {
71 mmgErr0 = 1;
72 fprintf(stderr," ## Error: %s: 0. at least 1 missing edge"
73 " tag (%" MMG5_PRId " %" MMG5_PRId ")\n",__func__,MMGS_indElt(mesh,k),
74 MMGS_indElt(mesh,adj));
75 fprintf(stderr,"triangle %" MMG5_PRId ": %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " \n",MMGS_indElt(mesh,k),
76 MMGS_indPt(mesh,pt1->v[0]),MMGS_indPt(mesh,pt1->v[1]),
77 MMGS_indPt(mesh,pt1->v[2]));
78 fprintf(stderr,"tag (%" MMG5_PRId "): %d %d %d \n",MMGS_indElt(mesh,k),
79 pt1->tag[0],pt1->tag[1],pt1->tag[2]);
80 }
81 return 0;
82 }
83 if ( adj == k ) {
84 if ( !mmgErr1 ) {
85 mmgErr1 = 1;
86 fprintf(stderr,"\n ## Error: %s: 1. at least 1 wrong adjacency"
87 " (%" MMG5_PRId " %" MMG5_PRId ")\n",
88 __func__,MMGS_indElt(mesh,k),MMGS_indElt(mesh,adj));
89 fprintf(stderr,"triangle %" MMG5_PRId ": %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " \n",MMGS_indElt(mesh,k),
90 MMGS_indPt(mesh,pt1->v[0]),MMGS_indPt(mesh,pt1->v[1]),
91 MMGS_indPt(mesh,pt1->v[2]));
92 fprintf(stderr,"adj (%" MMG5_PRId "): %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " \n",MMGS_indElt(mesh,k),
93 MMGS_indElt(mesh,adja[0]/3),MMGS_indElt(mesh,adja[1]/3),
94 MMGS_indElt(mesh,adja[2]/3));
95 }
96 return 0;
97 }
98 pt2 = &mesh->tria[adj];
99 if ( !MG_EOK(pt2) ) {
100 if ( !mmgErr2 ) {
101 mmgErr2 = 1;
102 fprintf(stderr,"\n ## Error: %s: 4. At least 1 invalid adjacent"
103 " (%" MMG5_PRId " %" MMG5_PRId ")\n",__func__,MMGS_indElt(mesh,adj),
104 MMGS_indElt(mesh,k));
105 fprintf(stderr,"vertices of k %" MMG5_PRId ": %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",
106 MMGS_indElt(mesh,k),MMGS_indPt(mesh,pt1->v[0]),
107 MMGS_indPt(mesh,pt1->v[1]),MMGS_indPt(mesh,pt1->v[2]));
108 fprintf(stderr,"vertices of adj %" MMG5_PRId ": %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " \n",
109 MMGS_indElt(mesh,adj),MMGS_indPt(mesh,pt2->v[0]),
110 MMGS_indPt(mesh,pt2->v[1]),MMGS_indPt(mesh,pt2->v[2]));
111 }
112 return 0;
113 }
114 if ( (pt1->tag[i] != pt2->tag[voy]) || (pt1->edg[i] != pt2->edg[voy] ) ) {
115 fprintf(stderr,"\n ## Error: %s: 3. at least 1 wrong"
116 " tag/ref (%" MMG5_PRId " %" MMG5_PRId ")"
117 " %d - %d\n",__func__,MMGS_indElt(mesh,k),
118 MMGS_indElt(mesh,adj),pt1->tag[i],pt2->tag[voy]);
119 return 0;
120 }
121 adjb = &mesh->adja[3*(adj-1)+1];
122 adj1 = adjb[voy] / 3;
123 voy1 = adjb[voy] % 3;
124 if ( adj1 != k || voy1 != i ) {
125 if ( !mmgErr3 ) {
126 mmgErr3 = 1;
127 fprintf(stderr,"\n ## Error: %s: 2. at least 1 wrong"
128 " adjacency (%" MMG5_PRId " %" MMG5_PRId ")\n",__func__, MMGS_indElt(mesh,k),
129 MMGS_indElt(mesh,adj1));
130 fprintf(stderr,"vertices of %" MMG5_PRId ": %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " \n",MMGS_indElt(mesh,k),
131 MMGS_indPt(mesh,pt1->v[0]),MMGS_indPt(mesh,pt1->v[1]),
132 MMGS_indPt(mesh,pt1->v[2]));
133 fprintf(stderr,"vertices of adj %" MMG5_PRId ": %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " \n",
134 MMGS_indElt(mesh,adj),
135 MMGS_indPt(mesh,pt2->v[0]),MMGS_indPt(mesh,pt2->v[1]),
136 MMGS_indPt(mesh,pt2->v[2]));
137 fprintf(stderr,"adj(%" MMG5_PRId "): %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",MMGS_indElt(mesh,k),
138 MMGS_indElt(mesh,adja[0]/3),MMGS_indElt(mesh,adja[1]/3),
139 MMGS_indElt(mesh,adja[2]/3));
140 fprintf(stderr,"adj(%" MMG5_PRId "): %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",MMGS_indElt(mesh,adj),
141 MMGS_indElt(mesh,adjb[0]/3),MMGS_indElt(mesh,adjb[1]/3),
142 MMGS_indElt(mesh,adjb[2]/3));
143 }
144 return 0;
145 }
146 if ( !MS_SIN(pt1->tag[i]) ) {
147 j1 = MMG5_inxt2[voy];
148 j2 = MMG5_iprv2[voy];
149 if ( pt2->v[j2] != pt1->v[i1] || pt2->v[j1] != pt1->v[i2] ) {
150 if ( !mmgErr4 ) {
151 mmgErr4 = 1;
152 fprintf(stderr,"\n ## Error: %s: 8. at least 1 wrong"
153 " orientation (%" MMG5_PRId " %" MMG5_PRId ").\n",__func__,MMGS_indElt(mesh,k),
154 MMGS_indElt(mesh,adj));
155 }
156 return 0;
157 }
158 }
159 }
160 }
161
162 if ( !severe ) return 1;
163
164 if ( !chknor( mesh ) ) {
165 printf(" *** WARNING: Non-admissible normals.\n");
166 }
167
168 for (k=1; k<=mesh->nt; k++) {
169 pt1 = &mesh->tria[k];
170 if ( !MG_EOK(pt1) ) continue;
171
172 adja = &mesh->adja[3*(k-1)+1];
173 for (i=0; i<3; i++) {
174 if ( !adja[i] ) continue;
175
176 ip = pt1->v[i];
177 ppt = &mesh->point[ip];
178 if ( !MG_VOK(ppt) ) {
179 if ( !mmgErr5 ) {
180 mmgErr5 = 1;
181 fprintf(stderr,"\n ## Error: %s: 6. at least 1 unused"
182 " vertex (%" MMG5_PRId " %" MMG5_PRId ")\n",__func__,
184 fprintf(stderr,"%" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",MMGS_indPt(mesh,pt1->v[0]),
185 MMGS_indPt(mesh,pt1->v[1]),MMGS_indPt(mesh,pt1->v[2]));
186 }
187 return 0;
188 }
189 else if ( MS_SIN(ppt->tag) ) continue;
190
191 int8_t dummy;
192 lon = MMG5_boulet(mesh,k,i,list,1,&dummy);
193 if ( lon < 1 ) continue;
194 for (l=0; l<lon; l++) {
195 kk = list[l] / 3;
196 nk = list[l] % 3;
197 pt2 = &mesh->tria[kk];
198 if ( pt2->v[nk] != ip ) {
199 if ( !mmgErr6 ) {
200 mmgErr6 = 1;
201 fprintf(stderr,"\n ## Error: %s: 5. at least 1 wrong"
202 " ball (%" MMG5_PRId ", %" MMG5_PRId ").\n",__func__,MMGS_indPt(mesh,ip),
203 MMGS_indPt(mesh,pt2->v[nk]));
204 }
205 return 0;
206 }
207 }
208 len = 0;
209 for (kk=1; kk<=mesh->nt; kk++) {
210 pt2 = &mesh->tria[kk];
211 if ( !MG_EOK(pt2) ) continue;
212 for (j=0; j<3; j++)
213 if ( pt2->v[j] == ip ) {
214 len++;
215 break;
216 }
217 }
218 if ( len != lon ) {
219 if ( !mmgErr7 ) {
220 mmgErr7 = 1;
221 fprintf(stderr,"\n ## Error: %s: 7. at least 1 incorrect"
222 " ball (%" MMG5_PRId ": %d %d).\n",__func__,MMGS_indPt(mesh,ip),lon,len);
223 ppt->tag |= MG_CRN + MG_REQ;
224 }
225 return 0;
226 }
227 }
228 }
229
230 return 1;
231}
232
243 MMG5_pTria pt;
244 MMG5_pPoint p0;
245 MMG5_pxPoint go;
246 double dd,ps,*n,nt[3];
247 MMG5_int k;
248 int8_t i;
249 static int8_t mmgWarn0=0, mmgWarn1=0;
250
251 /* First test : check that all normal vectors at points are non 0 */
252 for (k=1; k<=mesh->np; k++) {
253 p0 = &mesh->point[k];
254 if ( !MG_VOK(p0) ) continue;
255 if ( MS_SIN(p0->tag) ) continue;
256 if ( !(p0->tag & MG_GEO) ) continue;
257
258 assert( p0->xp );
259 go = &mesh->xpoint[p0->xp];
260 n = &go->n1[0];
261
262 dd = n[0]*n[0] + n[1]*n[1] + n[2]*n[2];
263 if ( dd < 0.9 ) {
264 if ( !mmgWarn0 ) {
265 mmgWarn0 = 1;
266 fprintf(stderr,"\n ## Error: %s: at least 1 non unitary normal"
267 " (point: %" MMG5_PRId " normal n1 = %f %f %f). exit program\n",
268 __func__,MMGS_indPt(mesh,k),n[0],n[1],n[2]);
269 }
270 return 0;
271 }
272
273 n = &go->n2[0];
274
275 dd = n[0]*n[0] + n[1]*n[1] + n[2]*n[2];
276 if ( dd < 0.9 ) {
277 if ( !mmgWarn0 ) {
278 mmgWarn0 = 1;
279 fprintf(stderr,"\n ## Error: %s: at least 1 non unitary normal"
280 " (point: %" MMG5_PRId " normal n2 = %f %f %f). exit program\n",
281 __func__,MMGS_indPt(mesh,k),n[0],n[1],n[2]);
282 }
283 return 0;
284 }
285 }
286
287 /* Second test : check that all normal vectors at points are consistently oriented with
288 respect to the underlying triangles */
289 for (k=1; k<=mesh->nt; k++) {
290 pt = &mesh->tria[k];
291 if ( !MG_EOK(pt) ) continue;
292
293 MMG5_nortri(mesh,pt,nt);
294 for (i=0; i<3; i++) {
295 p0 = &mesh->point[pt->v[i]];
296 if ( MS_SIN(p0->tag) ) continue;
297 else if ( MG_EDG(p0->tag) ) {
298 assert ( p0->xp );
299 go = &mesh->xpoint[p0->xp];
300 if ( p0->tag & MG_GEO ) {
301 n = &go->n1[0];
302 ps = n[0]*nt[0] + n[1]*nt[1] + n[2]*nt[2];
303 if ( ps < -0.99 ) {
304 if ( !mmgWarn1 ) {
305 mmgWarn1 = 1;
306 fprintf(stderr,"\n ## Error: %s: at least 1"
307 " inconsistant normal (point %" MMG5_PRId " in triangle %" MMG5_PRId "):"
308 " ps = %f \n",__func__,MMGS_indPt(mesh,pt->v[i]),
309 MMGS_indElt(mesh,k),ps);
310 }
311 return 0;
312 }
313
314 n = &go->n2[0];
315 ps = n[0]*nt[0] + n[1]*nt[1] + n[2]*nt[2];
316 if ( ps < -0.99 ) {
317 if ( !mmgWarn1 ) {
318 mmgWarn1 = 1;
319 fprintf(stderr,"\n ## Error: %s: at least 1"
320 " inconsistant normal (point %" MMG5_PRId " in triangle %" MMG5_PRId "):"
321 " ps = %f \n",__func__,MMGS_indPt(mesh,pt->v[i]),
322 MMGS_indElt(mesh,k),ps);
323 }
324 return 0;
325 }
326 }
327 else {
328 n = &go->n1[0];
329 ps = n[0]*nt[0] + n[1]*nt[1] + n[2]*nt[2];
330 if ( ps < -0.99 ) {
331 if ( !mmgWarn1 ) {
332 mmgWarn1 = 1;
333 fprintf(stderr,"\n ## Error: %s: at least 1"
334 " inconsistant normal (point %" MMG5_PRId " in triangle %" MMG5_PRId "):"
335 " ps = %f \n",__func__,MMGS_indPt(mesh,pt->v[i]),
336 MMGS_indElt(mesh,k),ps);
337 }
338 return 0;
339 }
340 }
341 }
342 else {
343 n = &p0->n[0];
344 ps = n[0]*nt[0] + n[1]*nt[1] + n[2]*nt[2];
345 if ( ps < -0.99 ) {
346 if ( !mmgWarn1 ) {
347 mmgWarn1 = 1;
348 fprintf(stderr,"\n ## Error: %s: at least 1"
349 " inconsistant normal (point %" MMG5_PRId " in triangle %" MMG5_PRId "):"
350 " ps = %f \n",__func__,MMGS_indPt(mesh,pt->v[i]),
351 MMGS_indElt(mesh,k),ps);
352 }
353 return 0;
354 }
355 }
356 }
357 }
358
359 return 1;
360}
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 MMG5_mmgsChkmsh(MMG5_pMesh mesh, int severe, MMG5_int base)
Definition: chkmsh_s.c:48
int chknor(MMG5_pMesh mesh)
Definition: chkmsh_s.c:242
MMG5_int MMGS_indPt(MMG5_pMesh mesh, MMG5_int kp)
Definition: gentools_s.c:139
MMG5_int MMGS_indElt(MMG5_pMesh mesh, MMG5_int kel)
Definition: gentools_s.c:123
#define MS_SIN(tag)
#define MG_REQ
#define MG_GEO
#define MG_EOK(pt)
#define MG_EDG(tag)
static const uint8_t MMG5_iprv2[3]
#define MMG5_TRIA_LMAX
static const uint8_t MMG5_inxt2[6]
#define MG_VOK(ppt)
int MMG5_nortri(MMG5_pMesh mesh, MMG5_pTria pt, double *n)
Definition: tools.c:209
#define MG_CRN
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 nt
Definition: libmmgtypes.h:612
MMG5_pTria tria
Definition: libmmgtypes.h:647
MMG5_int np
Definition: libmmgtypes.h:612
Structure to store points of a MMG mesh.
Definition: libmmgtypes.h:270
double n[3]
Definition: libmmgtypes.h:272
int16_t tag
Definition: libmmgtypes.h:284
MMG5_int xp
Definition: libmmgtypes.h:279
MMG5_int edg[3]
Definition: libmmgtypes.h:339
int16_t tag[3]
Definition: libmmgtypes.h:342
MMG5_int v[3]
Definition: libmmgtypes.h:334
Structure to store surface points of a MMG mesh.
Definition: libmmgtypes.h:294
double n2[3]
Definition: libmmgtypes.h:295
double n1[3]
Definition: libmmgtypes.h:295