Ejemplo n.º 1
0
Archivo: mmgs1.c Proyecto: XL64/mmg
/* attempt to collapse small edges */
static int colelt(pMesh mesh,pSol met,char typchk) {
    pTria    pt;
    pPoint   p1,p2;
    double   ll,ux,uy,uz;
    int      ier,list[LMAX+2],ilist,k,nc;
    char     i,i1,i2;

    nc = 0;
    for (k=1; k<=mesh->nt; k++) {
        pt = &mesh->tria[k];
        if ( !MS_EOK(pt) || pt->ref < 0 )   continue;

        /* check edge length */
        pt->flag = 0;
        ier = 0;
        for (i=0; i<3; i++) {
            if ( MS_SIN(pt->tag[i]) )  continue;

            i1 = inxt[i];
            i2 = iprv[i];
            p1 = &mesh->point[pt->v[i1]];
            p2 = &mesh->point[pt->v[i2]];
            if ( p1->tag & MS_NOM || p2->tag & MS_NOM )  continue;
            else if ( MS_SIN(p1->tag) )   continue;
            else if ( p1->tag > p2->tag || p1->tag > pt->tag[i] )  continue;

            /* check length */
            if ( typchk == 1 ) {
                ux = p2->c[0] - p1->c[0];
                uy = p2->c[1] - p1->c[1];
                uz = p2->c[2] - p1->c[2];
                ll = ux*ux + uy*uy + uz*uz;
                if ( ll > info.hmin*info.hmin )  continue;
            }
            else {
                ll = lenedg(mesh,met,pt->v[i1],pt->v[i2],0);
                if ( ll > LSHRT )  continue;
            }

            /* check if geometry preserved */
            ilist = chkcol(mesh,met,k,i,list,typchk);
            if ( ilist > 3 ) {
                nc += colver(mesh,list,ilist);
                break;
            }
            else if ( ilist == 3 ) {
                nc += colver3(mesh,list);
                break;
            }
            else if ( ilist == 2 ) {
                nc += colver2(mesh,list);
                break;
            }
        }
    }
    if ( nc > 0 && (abs(info.imprim) > 5 || info.ddebug) )
        fprintf(stdout,"     %8d vertices removed\n",nc);

    return(nc);
}
Ejemplo n.º 2
0
Archivo: mmgs1.c Proyecto: XL64/mmg
/* analyze triangles and split or collapse to match gradation */
static int adpcol(pMesh mesh,pSol met) {
    pTria    pt;
    pPoint   p1,p2;
    double   len;
    int      k,list[LMAX+2],ilist,nc;
    char     i,i1,i2;

    nc = 0;
    for (k=1; k<=mesh->nt; k++) {
        pt = &mesh->tria[k];
        if ( !MS_EOK(pt) || pt->ref < 0 )   continue;

        /* check edge length */
        pt->flag = 0;
        for (i=0; i<3; i++) {
            if ( MS_SIN(pt->tag[i]) )  continue;

            /* check length */
            i1 = inxt[i];
            i2 = iprv[i];
            p1 = &mesh->point[pt->v[i1]];
            p2 = &mesh->point[pt->v[i2]];
            if ( p1->tag & MS_NOM || p2->tag & MS_NOM )  continue;

            len = lenedg(mesh,met,pt->v[i1],pt->v[i2],0);
            if ( len > LOPTS )  continue;

            p1 = &mesh->point[pt->v[i1]];
            p2 = &mesh->point[pt->v[i2]];
            if ( MS_SIN(p1->tag) )  continue;
            else if ( p1->tag > p2->tag || p1->tag > pt->tag[i] )  continue;

            /* check if geometry preserved */
            ilist = chkcol(mesh,met,k,i,list,2);
            if ( ilist > 3 ) {
                nc += colver(mesh,list,ilist);
                break;
            }
            else if ( ilist == 3 ) {
                nc += colver3(mesh,list);
                break;
            }
            else if ( ilist == 2 ) {
                nc += colver2(mesh,list);
                break;
            }
        }
    }
    return(nc);
}
Ejemplo n.º 3
0
/* collapse edge i of k, i1->i2 */
int litcol(MMG5_pMesh mesh,int k,char i,double kali) {
  MMG5_pTria     pt,pt0,pt1;
  MMG5_pPoint    p1,p2;
  double         kal,ps,cosnold,cosnnew,n0old[3],n0new[3],n1old[3],n1new[3],n00old[3],n00new[3];
  int            *adja,list[_MMG5_LMAX+2],jel,ip2,l,ilist;
  char           i1,i2,j,jj,j2,open;

  pt0 = &mesh->tria[0];
  pt  = &mesh->tria[k];
  i1  = _MMG5_inxt2[i];
  i2  = _MMG5_iprv2[i];
  ip2 = pt->v[i2];

  /* collect all triangles around vertex i1 */
  ilist = boulet(mesh,k,i1,list);

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

  if ( ilist > 3 ) {
    /* check references */
    jel = list[1] / 3;
    pt1 = &mesh->tria[jel];
    if ( abs(pt->ref) != abs(pt1->ref) )  return(0);

    /* analyze ball */
    for (l=1; l<ilist-1+open; l++) {
      jel = list[l] / 3;
      j   = list[l] % 3;
      jj  = _MMG5_inxt2[j];
      j2  = _MMG5_iprv2[j];
      pt1 = &mesh->tria[jel];

      /* check normal flipping */
      if ( !_MMG5_nortri(mesh,pt1,n1old) )  return(0);
      memcpy(pt0,pt1,sizeof(MMG5_Tria));
      pt0->v[j] = ip2;
      if ( !_MMG5_nortri(mesh,pt0,n1new) )  return(0);
      ps = n1new[0]*n1old[0] + n1new[1]*n1old[1]  + n1new[2]*n1old[2];
      if ( ps < 0.0 )  return(0);

      /* keep normals at 1st triangles */
      if ( l == 1 && !open ) {
        memcpy(n00old,n1old,3*sizeof(double));
        memcpy(n00new,n1new,3*sizeof(double));
      }

      /* check normals deviation */
      if ( !(pt1->tag[j2] & MG_GEO) ) {
        if ( l > 1 ) {
          cosnold = n0old[0]*n1old[0] + n0old[1]*n1old[1] + n0old[2]*n1old[2];
          cosnnew = n0new[0]*n1new[0] + n0new[1]*n1new[1] + n0new[2]*n1new[2];
          if ( cosnold < _MMG5_ANGEDG ) {
            if ( cosnnew < MG_MIN(0.0,cosnold) )  return(0);
          }
          else if ( cosnnew < _MMG5_ANGEDG )  return(0);
        }

        memcpy(n0old,n1old,3*sizeof(double));
        memcpy(n0new,n1new,3*sizeof(double));
      }
      /* check quality */
      kal = ALPHAD*_MMG5_caltri_iso(mesh,NULL,pt0);
      if ( kal < NULKAL )  return(0);
    }

    /* check angle between 1st and last triangles */
    if ( !open ) {
      cosnold = n00old[0]*n1old[0] + n00old[1]*n1old[1] + n00old[2]*n1old[2];
      cosnnew = n00new[0]*n1new[0] + n00new[1]*n1new[1] + n00new[2]*n1new[2];
      if ( cosnold < _MMG5_ANGEDG ) {
        if ( cosnnew < MG_MIN(0.0,cosnold) )  return(0);
      }
      else if ( cosnnew < _MMG5_ANGEDG )  return(0);

      /* other reference checks */
      jel = list[ilist-1] / 3;
      pt  = &mesh->tria[jel];
      jel = list[ilist-2] / 3;
      pt1 = &mesh->tria[jel];
      if ( abs(pt->ref) != abs(pt1->ref) )  return(0);
    }

    return(colver(mesh,list,ilist));
  }

  /* specific test: no collapse if any interior edge is EDG */
  else if ( ilist == 3 ) {
    p1 = &mesh->point[pt->v[i1]];
    if ( MS_SIN(p1->tag) )  return(0);
    else if (  MG_EDG(pt->tag[i2]) && !MG_EDG(pt->tag[i]) )  return(0);
    else if ( !MG_EDG(pt->tag[i2]) &&  MG_EDG(pt->tag[i]) )  return(0);
    else if (  MG_EDG(pt->tag[i2]) &&  MG_EDG(pt->tag[i]) && MG_EDG(pt->tag[i1]) )  return(0);

    return(colver3(mesh,list));
  }

  /* for specific configurations along open ridge */
  else if ( ilist == 2 ) {
    if ( !open )  return(0);
    jel = list[1] / 3;
    j   = list[1] % 3;
    jj  = _MMG5_inxt2[j];
    pt1 = &mesh->tria[jel];
    if ( abs(pt->ref) != abs(pt1->ref) )  return(0);
    else if ( !(pt1->tag[jj] & MG_GEO) )  return(0);

    p1 = &mesh->point[pt->v[i1]];
    p2 = &mesh->point[pt1->v[jj]];
    if ( p2->tag > p1->tag || p2->ref != p1->ref )  return(0);

    return(colver2(mesh,list));
  }

  return(0);
}