diff --git a/src/mmg3d/boulep_3d.c b/src/mmg3d/boulep_3d.c index 94eb81d9a..a2b37f5a5 100644 --- a/src/mmg3d/boulep_3d.c +++ b/src/mmg3d/boulep_3d.c @@ -748,8 +748,8 @@ int MMG5_boulesurfvolp(MMG5_pMesh mesh,MMG5_int start,int ip,int iface, /** * \param mesh pointer to the mesh structure. - * \param start index of the starting tetra. - * \param ip index in \a start of the looked point. + * \param start index of the starting tetrahedron. + * \param ip index in \a start of the desired vertex. * \param iface index in \a start of the starting face. * \param listv pointer to the computed volumic ball. * \param ilistv pointer to the computed volumic ball size. @@ -757,32 +757,38 @@ int MMG5_boulesurfvolp(MMG5_pMesh mesh,MMG5_int start,int ip,int iface, * \param ilists pointer to the computed surfacic ball size. * \param refmin return the reference of one of the two subdomains in presence * \param refplus return the reference of the other subdomain in presence - * \param isnm is the looked point \a ip non-manifold? - * \return -1 if fail, 1 otherwise. + * \param isnm is the vertex non-manifold? + * \return 1 if succesful, a negative value if the ball cannot be computed: + * -1 if a surface ball had too many elements, + * -2 if there are more than two references around, + * -3 if an edge cannot be found, and + * -4 if a volume ball had too many elements. + * Among these, -1, -3 and -4 can be taken as a sign that further remeshing + * is not possible, while -2 just mean the job could not be done. * * Compute the volumic ball of a SURFACE point \a p, as well as its surfacic - * ball, starting from tetra \a start, with point \a ip, and face \a if in tetra + * ball, starting from tetra \a start, with point \a ip, and face \a if in the * volumic ball. * \a listv[k] = 4*number of tet + index of point surfacic ball. * \a lists[k] = 4*number of tet + index of face. * - * \warning Don't work for a non-manifold point if \a start has an adjacent - * through \a iface (for example : a non-manifold subdomain). Thus, if \a ip is + * \warning Doesn't work for a non-manifold point if \a start has an adjacent + * through \a iface (for example: a non-manifold subdomain). Thus, if \a ip is * non-manifold, must be called only if \a start has no adjacent through iface. * */ -int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,MMG5_int start,int ip,int iface, - int64_t *listv,int *ilistv,MMG5_int *lists,int *ilists, - MMG5_int *refmin,MMG5_int *refplus,int isnm) +int MMG5_boulesurfvolpNom(MMG5_pMesh mesh, MMG5_int start, int ip, int iface, + int64_t *listv, int *ilistv, MMG5_int *lists, int *ilists, + MMG5_int *refmin, MMG5_int *refplus, int isnm) { - MMG5_pTetra pt,pt1; + MMG5_pTetra pt, pt1; MMG5_pxTetra pxt; - MMG5_int k,k1,nump,*adja,piv,na,nb,adj,cur,nvstart,fstart,aux,base; - int8_t iopp,ipiv,i,j,l,isface; + MMG5_int k, k1, nump, *adja, piv, na, nb, adj, cur, nvstart, fstart, aux, base; + int8_t iopp, ipiv, i, j, l, isface; static int8_t mmgErr0=0, mmgErr1=0, mmgErr2=0; - + if ( isnm ) assert(!mesh->adja[4*(start-1)+iface+1]); - + base = ++mesh->base; *ilists = 0; *ilistv = 0; @@ -814,16 +820,15 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,MMG5_int start,int ip,int iface, MMG3D_indPt(mesh,nump)); mmgErr0 = 1; } - return -1; } - + aux = nb; nb = piv; piv = aux; nvstart = k; adj = k; - + /* Now unfold shell of edge (na,nb) starting from k (included)*/ do { k = adj; @@ -835,7 +840,7 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,MMG5_int start,int ip,int iface, assert(i<4); listv[(*ilistv)] = 4*k+i; (*ilistv)++; - + /* Identify references of both subdomains in presence */ if ( *refmin == -1 ) *refmin = pt->ref; @@ -843,14 +848,14 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,MMG5_int start,int ip,int iface, if ( *refplus == -1 ) { if ( pt->ref != *refmin ) *refplus = pt->ref; } - else if ( pt->ref != *refmin && pt->ref != *refplus ) return -1; + else if ( pt->ref != *refmin && pt->ref != *refplus ) return -2; } pt->flag = base; } - + /* identification of edge number in tetra k */ - if ( !MMG3D_findEdge(mesh,pt,k,na,nb,0,&mmgErr2,&i) ) return -1; - + if ( !MMG3D_findEdge(mesh,pt,k,na,nb,0,&mmgErr2,&i) ) return -3; + /* set sense of travel */ if ( pt->v[ MMG5_ifar[i][0] ] == piv ) { iopp = MMG5_ifar[i][0]; @@ -878,14 +883,14 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,MMG5_int start,int ip,int iface, while ( adj && (adj != nvstart) && !isface ); } while ( 4*k+iopp != fstart ); - + /* Now, surfacic ball is complete ; finish travel of volumic ball */ cur = 0; // Check numerotation while ( cur < (*ilistv) ) { k = listv[cur]/4; i = listv[cur]%4; // index of point p in tetra k adja = &mesh->adja[4*(k-1)+1]; - + for (l=0; l<3; l++) { i = MMG5_inxt3[i]; k1 = adja[i]; @@ -894,11 +899,11 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,MMG5_int start,int ip,int iface, pt1 = &mesh->tetra[k1]; if ( pt1->flag == base ) continue; pt1->flag = base; - + for (j=0; j<4; j++) if ( pt1->v[j] == nump ) break; assert(j<4); - + /* overflow */ if ( *ilistv > MMG3D_LMAX-3 ) { if ( !mmgErr1 ) { @@ -909,11 +914,11 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,MMG5_int start,int ip,int iface, " or/and the maximum mesh.\n"); mmgErr1 = 1; } - return -1; + return -4; } listv[(*ilistv)] = 4*k1+j; (*ilistv)++; - + /* Identify references of both subdomains in presence */ if ( *refmin == -1 ) *refmin = pt1->ref; @@ -921,12 +926,12 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,MMG5_int start,int ip,int iface, if ( *refplus == -1 ) { if ( pt1->ref != *refmin ) *refplus = pt1->ref; } - else if ( pt1->ref != *refmin && pt1->ref != *refplus ) return -1; + else if ( pt1->ref != *refmin && pt1->ref != *refplus ) return -2; } } cur++; } - + return 1; } diff --git a/src/mmg3d/mmg3d1.c b/src/mmg3d/mmg3d1.c index 9cb8aef26..566ac50d1 100644 --- a/src/mmg3d/mmg3d1.c +++ b/src/mmg3d/mmg3d1.c @@ -880,12 +880,12 @@ MMG5_int MMG5_movtet(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree, * \param mesh pointer to the mesh structure. * \param met pointer to the metric structure. * \param typchk type of checking permformed for edge length (hmin or LSHORT criterion). - * \return -1 if failed, number of collapsed points otherwise. + * \return a negative value in case of failure, number of collapsed points otherwise. * - * Attempt to collapse small edges. + * Attempt to collapse short edges. * */ -static int MMG5_coltet(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) { +static MMG5_int MMG5_coltet(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) { MMG5_pTetra pt,ptloc; MMG5_pxTetra pxt; MMG5_pPoint p0,p1; @@ -897,7 +897,7 @@ static int MMG5_coltet(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) { int l,kk,isloc,ifac1; int16_t tag,isnm,isnmint; int8_t i,j,ip,iq; - int ier; + int ier, bsret; // function return values/error codes nc = nnm = 0; @@ -963,15 +963,21 @@ static int MMG5_coltet(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) { } else { if ( mesh->adja[4*(k-1)+1+i] ) continue; - if (MMG5_boulesurfvolpNom(mesh,k,ip,i, - list,&ilist,lists,&ilists,&refmin,&refplus,p0->tag & MG_NOM) < 0 ) - return -1; + + bsret = MMG5_boulesurfvolpNom(mesh,k,ip,i, + list,&ilist,lists,&ilists,&refmin,&refplus,p0->tag & MG_NOM); + if(bsret==-1 || bsret==-3 || bsret==-4){ + return -3; // fatal + }else if(bsret==-2){ + continue; // ball computation failed: cannot handle this vertex + } + assert(bsret==1 && "unexpected return value from MMG5_boulesurfvolpNom"); } } else { if (MMG5_boulesurfvolp(mesh,k,ip,i, list,&ilist,lists,&ilists,p0->tag & MG_NOM) < 0 ) - return -1; + return -2; } } else { @@ -1094,15 +1100,20 @@ static int MMG5_coltet(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) { } else { if ( mesh->adja[4*(k-1)+1+i] ) continue; - if (MMG5_boulesurfvolpNom(mesh,k,ip,i, - list,&ilist,lists,&ilists,&refmin,&refplus,p0->tag & MG_NOM) < 0 ) - return -1; + bsret = MMG5_boulesurfvolpNom(mesh,k,ip,i, + list,&ilist,lists,&ilists,&refmin,&refplus,p0->tag & MG_NOM); + if(bsret==-1 || bsret==-3 || bsret==-4){ + return -3; // fatal + }else if(bsret==-2){ + continue; // ball computation failed: cannot handle this vertex + } + assert(bsret==1 && "unexpected return value from MMG5_boulesurfvolpNom"); } } else { if (MMG5_boulesurfvolp(mesh,k,ip,i, list,&ilist,lists,&ilists,p0->tag & MG_NOM) < 0 ) - return -1; + return -4; } } else { @@ -1134,13 +1145,13 @@ static int MMG5_coltet(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) { if ( ilist > 0 ) { ier = MMG5_colver(mesh,met,list,ilist,iq,typchk); - if ( ier < 0 ) return -1; + if ( ier < 0 ) return -5; else if ( ier ) { MMG3D_delPt(mesh,ier); break; } } - else if (ilist < 0 ) return -1; + else if (ilist < 0 ) return -6; } if ( ier ) { p1->flag = base;