Beispiel #1
0
/**
 * \param mesh pointer toward the mesh structure.
 * \param list pointer toward the ball of the point to collapse.
 * \return 1.
 *
 * Collapse edge \f$list[0]%3\f$ in tet \f$list[0]/3\f$ (\f$ ip->i1\f$ ) for a
 * ball of the collapsed point of size 3: the collapsed point is removed.
 *
 */
int colver3(MMG5_pMesh mesh,int* list) {
  MMG5_pTria   pt,pt1,pt2;
  int          *adja,iel,jel,kel,mel,ip;
  char         i,i1,j,j1,j2,k,m;

  /* update of new point for triangle list[0] */
  iel = list[0] / 3;
  i   = list[0] % 3;
  i1  = _MMG5_inxt2[i];
  pt  = &mesh->tria[iel];
  ip  = pt->v[i];

  jel = list[1] / 3;
  j   = list[1] % 3;
  j1  = _MMG5_inxt2[j];
  j2  = _MMG5_iprv2[j];
  pt1 = &mesh->tria[jel];

  kel = list[2] / 3;
  k   = list[2] % 3;
  pt2 = &mesh->tria[kel];

  /* update info */
  pt1->v[j]     = pt->v[i1];
  pt1->tag[j1] |= pt2->tag[k];
  pt1->edg[j1]  = MG_MAX(pt1->edg[j1],pt2->edg[k]);
  pt1->tag[j2] |= pt->tag[i];
  pt1->edg[j2]  = MG_MAX(pt1->edg[j2],pt->edg[i]);
  pt1->base     = mesh->base;

  /* update neighbours of new triangle */
  adja = &mesh->adja[3*(jel-1)+1];
  adja[j1] = mesh->adja[3*(kel-1)+1+k];
  adja[j2] = mesh->adja[3*(iel-1)+1+i];

  mel  = adja[j2] / 3;
  if ( mel ) {
    m    = adja[j2] % 3;
    pt   = &mesh->tria[mel];
    pt->tag[m]  = pt1->tag[j2];
    pt->edg[m]  = pt1->edg[j2];
    mesh->adja[3*(mel-1)+1+m] = 3*jel + j2;
  }

  mel = adja[j1] / 3;
  if ( mel ) {
    m    = adja[j1] % 3;
    pt   = &mesh->tria[mel];
    pt->tag[m]  = pt1->tag[j1];
    pt->edg[m]  = pt1->edg[j1];
    mesh->adja[3*(mel-1)+1+m] = 3*jel + j1;
  }

  /* remove vertex + elements */
  _MMG5_delPt(mesh,ip);
  _MMG5_delElt(mesh,iel);
  _MMG5_delElt(mesh,kel);

  return(1);
}
Beispiel #2
0
/* collapse point along open ridge */
int colver2(MMG5_pMesh mesh,int* list) {
  MMG5_pTria   pt,pt1;
  int          *adja,iel,jel,kel,ip;
  char         i1,i2,jj,j2,k;

  /* update of new point for triangle list[0] */
  iel = list[0] / 3;
  i1  = list[0] % 3;
  i2  = _MMG5_inxt2[i1];
  pt  = &mesh->tria[iel];
  ip  = pt->v[i1];

  jel = list[1] / 3;
  j2  = list[1] % 3;
  jj  = _MMG5_iprv2[j2];
  pt1 = &mesh->tria[jel];

  /* update info */
  pt->v[i1] = pt1->v[jj];
  pt->tag[i2] |= pt1->tag[j2];
  pt->edg[i2] = pt1->edg[j2];
  pt->base  = mesh->base;

  /* update neighbours of new triangle */
  adja = &mesh->adja[3*(iel-1)+1];
  adja[i2] = mesh->adja[3*(jel-1)+1+j2];
  adja = &mesh->adja[3*(jel-1)+1];
  kel  = adja[j2] / 3;
  k    = adja[j2] % 3;
  if ( kel )
    mesh->adja[3*(kel-1)+1+k] = 3*iel + i2;

  /* remove vertex + element */
  _MMG5_delPt(mesh,ip);
  _MMG5_delElt(mesh,jel);

  return(1);
}
Beispiel #3
0
/**
 * \param mesh pointer toward the mesh structure.
 * \param met pointer toward the metric structure.
 * \param *warn \a warn is set to 1 if we don't have enough memory to complete mesh.
 * \return -1 if failed.
 * \return number of new points.
 *
 * Split edges of length bigger than _MMG5_LOPTL.
 *
 */
static int _MMG5_adpspl(MMG5_pMesh mesh,MMG5_pSol met, int* warn) {
    MMG5_pTetra     pt;
    MMG5_pxTetra    pxt;
    MMG5_Tria       ptt;
    MMG5_pPoint     p0,p1,ppt;
    MMG5_pxPoint    pxp;
    double     dd,len,lmax,o[3],to[3],ro[3],no1[3],no2[3],v[3];
    int        k,ip,ip1,ip2,list[_MMG5_LMAX+2],ilist,ns,ref,ier;
    char       imax,tag,j,i,i1,i2,ifa0,ifa1;

    *warn=0;
    ns = 0;
    for (k=1; k<=mesh->ne; k++) {
        pt = &mesh->tetra[k];
        if ( !MG_EOK(pt) || (pt->tag & MG_REQ) )   continue;
        pxt = pt->xt ? &mesh->xtetra[pt->xt] : 0;

        /* find longest edge */
        imax = -1; lmax = 0.0;
        for (i=0; i<6; i++) {
            if ( pt->xt && (pxt->tag[i] & MG_REQ) )  continue;
            ip1  = _MMG5_iare[i][0];
            ip2  = _MMG5_iare[i][1];
            len = _MMG5_lenedg(mesh,met,pt->v[ip1],pt->v[ip2]);
            if ( len > lmax ) {
                lmax = len;
                imax = i;
            }
        }
        if ( imax==-1 )
            fprintf(stdout,"%s:%d: Warning: all edges of tetra %d are required or of length null.\n",
                    __FILE__,__LINE__,k);
        if ( lmax < _MMG5_LOPTL )  continue;

        /* proceed edges according to lengths */
        ifa0 = _MMG5_ifar[imax][0];
        ifa1 = _MMG5_ifar[imax][1];
        i  = (pt->xt && (pxt->ftag[ifa1] & MG_BDY)) ? ifa1 : ifa0;
        j  = _MMG5_iarfinv[i][imax];
        i1 = _MMG5_idir[i][_MMG5_inxt2[j]];
        i2 = _MMG5_idir[i][_MMG5_iprv2[j]];
        ip1 = pt->v[i1];
        ip2 = pt->v[i2];
        p0  = &mesh->point[ip1];
        p1  = &mesh->point[ip2];

        /* Case of a boundary face */
        if ( pt->xt && (pxt->ftag[i] & MG_BDY) ) {
            if ( !(MG_GET(pxt->ori,i)) ) continue;
            ref = pxt->edg[_MMG5_iarf[i][j]];
            tag = pxt->tag[_MMG5_iarf[i][j]];
            if ( tag & MG_REQ )  continue;
            tag |= MG_BDY;
            ilist = _MMG5_coquil(mesh,k,imax,list);
            if ( !ilist )  continue;
            else if ( ilist < 0 )
                return(-1);
            if ( tag & MG_NOM ){
                if( !_MMG5_BezierNom(mesh,ip1,ip2,0.5,o,no1,to) )
                    continue;
                else if ( MG_SIN(p0->tag) && MG_SIN(p1->tag) ) {
                    _MMG5_tet2tri(mesh,k,i,&ptt);
                    _MMG5_nortri(mesh,&ptt,no1);
                    if ( !MG_GET(pxt->ori,i) ) {
                        no1[0] *= -1.0;
                        no1[1] *= -1.0;
                        no1[2] *= -1.0;
                    }
                }
            }
            else if ( tag & MG_GEO ) {
                if ( !_MMG5_BezierRidge(mesh,ip1,ip2,0.5,o,no1,no2,to) )
                    continue;
                if ( MG_SIN(p0->tag) && MG_SIN(p1->tag) ) {
                    _MMG5_tet2tri(mesh,k,i,&ptt);
                    _MMG5_nortri(mesh,&ptt,no1);
                    no2[0] = to[1]*no1[2] - to[2]*no1[1];
                    no2[1] = to[2]*no1[0] - to[0]*no1[2];
                    no2[2] = to[0]*no1[1] - to[1]*no1[0];
                    dd = no2[0]*no2[0] + no2[1]*no2[1] + no2[2]*no2[2];
                    if ( dd > _MMG5_EPSD2 ) {
                        dd = 1.0 / sqrt(dd);
                        no2[0] *= dd;
                        no2[1] *= dd;
                        no2[2] *= dd;
                    }
                }
            }
            else if ( tag & MG_REF ) {
                if ( !_MMG5_BezierRef(mesh,ip1,ip2,0.5,o,no1,to) )
                    continue;
            }
            else {
                if ( !_MMG5_norface(mesh,k,i,v) )  continue;
                if ( !_MMG5_BezierReg(mesh,ip1,ip2,0.5,v,o,no1) )
                    continue;
            }
            ier = _MMG5_simbulgept(mesh,list,ilist,o);
            if ( !ier ) {
                ier = _MMG5_dichoto1b(mesh,list,ilist,o,ro);
                memcpy(o,ro,3*sizeof(double));
            }
            ip = _MMG5_newPt(mesh,o,tag);
            if ( !ip ) {
                /* reallocation of point table */
                _MMG5_POINT_REALLOC(mesh,met,ip,mesh->gap,
                              *warn=1;
                              break
                              ,o,tag);
            }
            //CECILE
            if ( met->m )
                met->m[ip] = 0.5 * (met->m[ip1]+met->m[ip2]);
            //CECILE
            ier = _MMG5_split1b(mesh,met,list,ilist,ip,1);
            /* if we realloc memory in _MMG5_split1b pt and pxt pointers are not valid */
            pt = &mesh->tetra[k];
            pxt = pt->xt ? &mesh->xtetra[pt->xt] : 0;

            if ( ier < 0 ) {
                fprintf(stdout," ## Error: unable to split.\n");
                return(-1);
            }
            else if ( !ier ) {
                _MMG5_delPt(mesh,ip);
                continue;
            }
            ns++;
            ppt = &mesh->point[ip];
            if ( MG_EDG(tag) || (tag & MG_NOM) )
                ppt->ref = ref;
            else
                ppt->ref = pxt->ref[i];
            if ( met->m )
                met->m[ip] = 0.5 * (met->m[ip1]+met->m[ip2]);

            pxp = &mesh->xpoint[ppt->xp];
            if ( tag & MG_NOM ){
                memcpy(pxp->n1,no1,3*sizeof(double));
                memcpy(pxp->t,to,3*sizeof(double));
            }
            else if ( tag & MG_GEO ) {
                memcpy(pxp->n1,no1,3*sizeof(double));
                memcpy(pxp->n2,no2,3*sizeof(double));
                memcpy(pxp->t,to,3*sizeof(double));
            }
            else if ( tag & MG_REF ) {
                memcpy(pxp->n1,no1,3*sizeof(double));
                memcpy(pxp->t,to,3*sizeof(double));
            }
            else
                memcpy(pxp->n1,no1,3*sizeof(double));
        }

        /* Case of an internal face */
        else {
            if ( (p0->tag & MG_BDY) && (p1->tag & MG_BDY) ) continue;
Beispiel #4
0
/* collapse edge i of k, i1->i2 */
int colver(MMG5_pMesh mesh,int *list,int ilist) {
  MMG5_pTria    pt,pt1,pt2;
  int     *adja,k,iel,jel,kel,ip1,ip2;
  char     i,i1,i2,j,jj,open;

  iel = list[0] / 3;
  i1  = list[0] % 3;
  i   = _MMG5_iprv2[i1];
  i2  = _MMG5_inxt2[i1];
  pt  = &mesh->tria[iel];
  ip1 = pt->v[i1];
  ip2 = pt->v[i2];

  /* check for open ball */
  adja = &mesh->adja[3*(iel-1)+1];
  open = adja[i] == 0;

  /* update vertex ip1 -> ip2 */
  for (k=1; k<ilist-1+open; k++) {
    jel = list[k] / 3;
    jj  = list[k] % 3;
    pt1 = &mesh->tria[jel];
    pt1->v[jj] = ip2;
    pt1->base  = mesh->base;
  }

  /* update adjacent with 1st elt */
  jel = list[1] / 3;
  jj  = list[1] % 3;
  j   = _MMG5_iprv2[jj];
  pt1 = &mesh->tria[jel];
  pt1->tag[j] = MG_MAX(pt->tag[i1],pt1->tag[j]);
  pt1->edg[j] = MG_MAX(pt->edg[i1],pt1->edg[j]);
  if ( adja[i1] ) {
    kel = adja[i1] / 3;
    k   = adja[i1] % 3;
    mesh->adja[3*(kel-1)+1+k] = 3*jel + j;
    mesh->adja[3*(jel-1)+1+j] = 3*kel + k;
    pt2 = &mesh->tria[kel];
    pt2->tag[k] = MG_MAX(pt1->tag[j],pt2->tag[k]);
    pt2->edg[k] = MG_MAX(pt1->edg[j],pt2->edg[k]);
  }
  else
    mesh->adja[3*(jel-1)+1+j] = 0;

  /* adjacent with last elt */
  if ( !open ) {
    iel = list[ilist-1] / 3;
    i1  = list[ilist-1] % 3;
    pt  = &mesh->tria[iel];

    jel = list[ilist-2] / 3;
    jj  = list[ilist-2] % 3;
    j   = _MMG5_inxt2[jj];
    pt1 = &mesh->tria[jel];
    pt1->tag[j] = MG_MAX(pt->tag[i1],pt1->tag[j]);
    pt1->edg[j] = MG_MAX(pt->edg[i1],pt1->edg[j]);
    adja = &mesh->adja[3*(iel-1)+1];
    if ( adja[i1] ) {
      kel = adja[i1] / 3;
      k   = adja[i1] % 3;
      mesh->adja[3*(kel-1)+1+k] = 3*jel + j;
      mesh->adja[3*(jel-1)+1+j] = 3*kel + k;
      pt2 = &mesh->tria[kel];
      pt2->tag[k] = MG_MAX(pt1->tag[j],pt2->tag[k]);
      pt2->edg[k] = MG_MAX(pt1->edg[j],pt2->edg[k]);
    }
    else
      mesh->adja[3*(jel-1)+1+j] = 0;
  }

  _MMG5_delPt(mesh,ip1);
  _MMG5_delElt(mesh,list[0] / 3);
  if ( !open )  _MMG5_delElt(mesh,list[ilist-1] / 3);

  return(1);
}