Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
optbdry_3d.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
33#include "libmmg3d.h"
34#include "libmmg3d_private.h"
36
48 MMG5_pTetra pt;
49 MMG5_pxTetra pxt;
50 MMG5_pPoint ppt;
51 /* double *n; */
52 int64_t listv[MMG3D_LMAX+2];
53 MMG5_int ier/*,lists[MMG3D_LMAX+2]*/,base;
54 int i0,i,j/*,ilists*/,ilistv;
55 int /* improve,*/ internal,nm,/*maxit,*/ns;
56
57 // improve = 1;
58 internal = 1;
59 nm = ns = 0;
60 // maxit = 1;
61 base = mesh->base;
62
63 pt = &mesh->tetra[k];
64
65 /* point j on face i */
66 for (i=0; i<4; i++) {
67 for (j=0; j<3; j++) {
68 if ( pt->xt ) {
69 pxt = &mesh->xtetra[pt->xt];
70 if ( pxt->tag[MMG5_iarf[i][j]] & MG_REQ ) continue;
71 }
72 else pxt = 0;
73 i0 = MMG5_idir[i][j];
74 ppt = &mesh->point[pt->v[i0]];
75 if ( ppt->flag == base ) continue;
76 else if ( MG_SIN(ppt->tag) ) continue;
77
78 // if ( maxit != 1 )
79 ppt->flag = base;
80
81 ier = 0;
82 if ( ppt->tag & MG_BDY ) {
83
84 continue;
85
86 /* /\* Catch a boundary point by a boundary face *\/ */
87/* if ( !pt->xt || !(MG_BDY & pxt->ftag[i]) ) continue; */
88/* else if( ppt->tag & MG_NOM ){ */
89/* if( mesh->adja[4*(k-1)+1+i] ) continue; */
90/* ier=MMG5_boulesurfvolp(mesh,k,i0,i,listv,&ilistv,lists,&ilists,1); */
91/* if( !ier ) continue; */
92/* else if ( ier>0 ) */
93/* ier = MMG5_movbdynompt(mesh,met,PROctree,listv,ilistv,lists,ilists,improve); */
94/* else */
95/* return -1; */
96/* } */
97/* else if ( ppt->tag & MG_GEO ) { */
98/* ier=MMG5_boulesurfvolp(mesh,k,i0,i,listv,&ilistv,lists,&ilists,0); */
99/* if ( !ier ) continue; */
100/* else if ( ier>0 ) */
101/* ier = MMG5_movbdyridpt(mesh,met,PROctree,listv,ilistv,lists,ilists,improve); */
102/* else */
103/* return -1; */
104/* } */
105/* else if ( ppt->tag & MG_REF ) { */
106/* ier=MMG5_boulesurfvolp(mesh,k,i0,i,listv,&ilistv,lists,&ilists,0); */
107/* if ( !ier ) */
108/* continue; */
109/* else if ( ier>0 ) */
110/* ier = MMG5_movbdyrefpt(mesh,met,PROctree,listv,ilistv,lists,ilists,improve); */
111/* else */
112/* return -1; */
113/* } */
114/* else { */
115/* ier=MMG5_boulesurfvolp(mesh,k,i0,i,listv,&ilistv,lists,&ilists,0); */
116/* if ( !ier ) */
117/* continue; */
118/* else if ( ier<0 ) */
119/* return -1; */
120
121/* n = &(mesh->xpoint[ppt->xp].n1[0]); */
122/* if ( !MG_GET(pxt->ori,i) ) { */
123/* if ( !MMG5_directsurfball(mesh,pt->v[i0],lists,ilists,n) ) */
124/* continue; */
125/* } */
126/* //#warning CECILE a modifier pour opttyp */
127/* ier = MMG5_movbdyregpt(mesh,met, PROctree, listv,ilistv,lists,ilists,improve,improve); */
128/* if ( ier ) ns++; */
129/* } */
130 }
131 else if ( internal ) {
132 ilistv = MMG5_boulevolp(mesh,k,i0,listv);
133 if ( !ilistv ) continue;
134 ier = MMG3D_movnormal_iso(mesh,met,k,i0);
135 }
136 if ( ier ) {
137 nm++;
138 // if(maxit==1)
139 ppt->flag = base;
140 }
141 }
142 }
143 if(nm)
144 return 1;
145 else
146 return 0;
147
148}
149
161int MMG3D_coledges(MMG5_pMesh mesh,MMG5_pSol met,MMG5_int k,int i) {
162 MMG5_pTetra pt;
163 double len;
164 int ied,iedg,iq,i1,ilistcol;
165 int64_t listcol[MMG3D_LMAX+2];
166 int ier;
167 int8_t iface,ief;
168
169 pt = &mesh->tetra[k];
170
171 if ( MG_SIN(mesh->point[pt->v[i]].tag) ) {
172 return 0;
173 }
174
175 /*3 possibilities to remove the vertex ib*/
176 for(ied = 0 ; ied<3 ;ied++) {
177 iedg = MMG5_arpt[i][ied];
178 len = MMG5_lenedg(mesh,met,iedg,pt);
179
180 if(len > 1.1) continue;
181 iface = MMG5_ifar[iedg][0];
182 ief = MMG5_iarfinv[iface][iedg];
183 iq = MMG5_idir[iface][MMG5_iprv2[ief]];
184 if(iq==i) {
185 iface = MMG5_ifar[iedg][1];
186 ief = MMG5_iarfinv[iface][iedg];
187 iq = MMG5_idir[iface][MMG5_iprv2[ief]];
188 }
189 i1 = MMG5_idir[iface][MMG5_inxt2[ief]];
190
191 assert( 0<=i1 && i1<4 && "unexpected local index for vertex");
192 ilistcol = MMG5_boulevolp(mesh,k,i1,listcol);
193
194 ilistcol = MMG5_chkcol_int(mesh,met,k,iface,ief,listcol,ilistcol,2);
195 if ( ilistcol > 0 ) {
196 ier = MMG5_colver(mesh,met,listcol,ilistcol,iq,2);
197 if ( ilistcol < 0 ) continue;
198 if ( ier < 0 ) return -1;
199 else if(ier) {
201 return 1;
202 }
203 }
204 }
205 return 0;
206}
207
221 MMG5_int k,int i) {
222 MMG5_pTetra pt;
223 int il,ilist,ip;
224 int64_t list[MMG3D_LMAX+2];
225 MMG5_int iel;
226
227 pt = &mesh->tetra[k];
228
229 if ( MG_SIN(mesh->point[pt->v[i]].tag) ) {
230 return 0;
231 }
232
233 assert( 0<=i && i<4 && "unexpected local index for vertex");
234 ilist = MMG5_boulevolp(mesh,k,i,list);
235 if (ilist > 30 ) return 0;
236
237 for(il = 0 ; il<ilist ; il++) {
238 iel = list[il] / 4;
239 ip = list[il] % 4;
240 if( MMG3D_coledges(mesh,met,iel,ip) ) {
241 return 1;
242 }
243 }
244
245 return 0;
246}
247
260 MMG5_pTetra pt;
261 MMG5_pxTetra pxt;
262 int ib,i,j;
263 int64_t list[MMG3D_LMAX+2];
264 MMG5_int ipb,it1,it2;
265 int iedg,ier,ilist,ied,ia,ret,imove;
266
267 imove = 0;
268
269 pt = &mesh->tetra[k];
270 assert(pt->xt);
271
272 pxt = &mesh->xtetra[pt->xt];
273
274 for(i=0 ; i<4 ; i++)
275 if ( pxt->ftag[i] & MG_BDY ) break;
276
277 assert ( i< 4 );
278 if ( i== 4 ) return 0;
279
280 ib = i;
281 ipb = pt->v[ib];
282
283 /*check that the vertex is not a boundary one*/
284 if ( mesh->point[ipb].tag & MG_BDY ) return 0;
285
286 /* try to move the vertex in order to improve the quality*/
287 ier = 0;
288 if ( !mesh->info.nomove ) {
289 for(j = 0 ; j<3 ; j++) {
290 imove = MMG3D_movetetrapoints(mesh,met,PROctree,k);
291 ier += imove;
292 if(!imove) break;
293 }
294 if(ier) {
295 imove = 1;
296 }
297 }
298
299 if(!mesh->info.noinsert) {
300 /*try to remove the non-bdry vertex*/
301 ier = MMG3D_coledges(mesh,met,k,ib);
302 if(ier) return 1;
303
304 /* try to remove the non-bdry vertex : with all the edges containing the
305 * vertex */
306 ier = MMG3D_deletePoint(mesh,met,PROctree,k,i);
307 if(ier) return 1;
308 }
309
310
311 /*try to swap the 3 internal edges*/
312 if(!mesh->info.noswap) {
313 for(ied = 0 ; ied<3 ;ied++) {
314 iedg = MMG5_arpt[i][ied];
315 ier = MMG3D_swpItem(mesh,met,PROctree,k,iedg);
316 if(ier) {
317 return 1;
318 }
319 }
320 /*try to swap the bdry edges*/
321 for (j=0; j<3; j++) {
322 ia = MMG5_iarf[i][j];
323
324 /* No swap of geometric edge */
325 if ( MG_EDG_OR_NOM(pxt->tag[ia]) || (pxt->tag[ia] & MG_REQ) ) {
326 continue;
327 }
328
329 ret = MMG5_coquilface(mesh,k,i,ia,list,&it1,&it2,0);
330 ilist = ret / 2;
331 if ( ret < 0 ) return -1;
332 /* CAUTION: trigger collapse with 2 elements */
333 if ( ilist <= 1 ) continue;
334 ier = MMG5_chkswpbdy(mesh,met,list,ilist,it1,it2,2);
335 if ( ier < 0 )
336 return -1;
337 else if ( ier ) {
338 ier = MMG5_swpbdy(mesh,met,list,ret,it1,PROctree,2);
339 if ( ier < 0 ) return -1;
340 else if(ier) {
341 return 1;
342 }
343 }
344 }
345 }
346
347
348 return imove;
349
350}
int ier
MMG5_pMesh * mesh
int MMG5_boulevolp(MMG5_pMesh mesh, MMG5_int start, int ip, int64_t *list)
Definition: boulep_3d.c:54
int MMG5_coquilface(MMG5_pMesh mesh, MMG5_int start, int8_t iface, int ia, int64_t *list, MMG5_int *it1, MMG5_int *it2, int silent)
Definition: boulep_3d.c:1843
MMG5_int MMG5_colver(MMG5_pMesh mesh, MMG5_pSol met, int64_t *list, int ilist, int8_t indq, int8_t typchk)
Definition: colver_3d.c:1144
int MMG5_chkcol_int(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, int8_t iface, int8_t iedg, int64_t *list, int ilist, int8_t typchk)
Definition: colver_3d.c:43
API headers for the mmg3d library.
#define MMG3D_LMAX
Definition: libmmg3d.h:58
int MMG5_swpbdy(MMG5_pMesh, MMG5_pSol, int64_t *, int, MMG5_int, MMG3D_pPROctree, int8_t)
Definition: swap_3d.c:467
int MMG3D_movnormal_iso(MMG5_pMesh, MMG5_pSol, MMG5_int, int)
Definition: movpt_3d.c:1746
void MMG3D_delPt(MMG5_pMesh mesh, MMG5_int ip)
Definition: zaldy_3d.c:80
static const int8_t MMG5_iarfinv[4][6]
num of the j^th edge in the i^th face
static const uint8_t MMG5_arpt[4][3]
arpt[i]: edges passing through vertex i
int MMG5_chkswpbdy(MMG5_pMesh, MMG5_pSol, int64_t *, int, MMG5_int, MMG5_int, int8_t)
Definition: swap_3d.c:57
static const int8_t MMG5_iarf[4][3]
iarf[i]: edges of face opposite to vertex i
static const uint8_t MMG5_ifar[6][2]
ifar[i][]: faces sharing the ith edge of the tetra
static const uint8_t MMG5_idir[4][3]
idir[i]: vertices of face opposite to vertex i
int MMG3D_swpItem(MMG5_pMesh, MMG5_pSol, MMG3D_pPROctree, MMG5_int, int)
Definition: opttyp_3d.c:328
#define MG_REQ
static const uint8_t MMG5_iprv2[3]
#define MG_EDG_OR_NOM(tag)
#define MG_SIN(tag)
static const uint8_t MMG5_inxt2[6]
#define MG_BDY
int MMG3D_coledges(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, int i)
Definition: optbdry_3d.c:161
int MMG3D_movetetrapoints(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, MMG5_int k)
Definition: optbdry_3d.c:47
int MMG3D_optbdry(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, MMG5_int k)
Definition: optbdry_3d.c:259
int MMG3D_deletePoint(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, MMG5_int k, int i)
Definition: optbdry_3d.c:220
uint8_t noswap
Definition: libmmgtypes.h:546
uint8_t noinsert
Definition: libmmgtypes.h:546
uint8_t nomove
Definition: libmmgtypes.h:546
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_Info info
Definition: libmmgtypes.h:651
MMG5_pPoint point
Definition: libmmgtypes.h:641
MMG5_int base
Definition: libmmgtypes.h:616
MMG5_pTetra tetra
Definition: libmmgtypes.h:643
MMG5_pxTetra xtetra
Definition: libmmgtypes.h:644
Structure to store points of a MMG mesh.
Definition: libmmgtypes.h:270
int16_t tag
Definition: libmmgtypes.h:284
MMG5_int flag
Definition: libmmgtypes.h:282
MMG5_int v[4]
Definition: libmmgtypes.h:403
MMG5_int xt
Definition: libmmgtypes.h:407
Structure to store the surface tetrahedra of a MMG mesh.
Definition: libmmgtypes.h:418
int16_t ftag[4]
Definition: libmmgtypes.h:423
int16_t tag[6]
Definition: libmmgtypes.h:425