Beispiel #1
0
/* check and eventually insert vertex */
int MMG_buckin_ani(pMesh mesh,pSol sol,pBucket bucket,int ip) {
  pPoint	ppt,pp1;
  double	dd,d2,det,ux,uy,uz,dmi,m1,m2,m3,dx,dy,dz;
  double	*ma,*mb;
  int		i,j,k,ii,jj,kk,ic,icc,siz,ip1;
  int 		iadr,imin,imax,jmin,jmax,kmin,kmax;

  ppt = &mesh->point[ip];
  siz = bucket->size;
  dd  = siz / (double)PRECI;

  iadr = (ip-1)*sol->offset + 1;
  ma   = &sol->met[iadr];
  dmi  = LFILT*LFILT;

  ii = M_MAX(0,(int)(dd * ppt->c[0])-1);
  jj = M_MAX(0,(int)(dd * ppt->c[1])-1);
  kk = M_MAX(0,(int)(dd * ppt->c[2])-1);
  ic = (kk*siz + jj)*siz + ii;

  /* check current cell */
  if ( bucket->head[ic] ) {
    ip1 = bucket->head[ic];
    pp1 = &mesh->point[ip1];
    ux = pp1->c[0] - ppt->c[0];
    uy = pp1->c[1] - ppt->c[1];
    uz = pp1->c[2] - ppt->c[2];
    d2 =      ma[0]*ux*ux + ma[3]*uy*uy + ma[5]*uz*uz \
       + 2.0*(ma[1]*ux*uy + ma[2]*ux*uz + ma[4]*uy*uz);
    if ( d2 < dmi ) {
      iadr = (ip1-1)*sol->offset + 1;
      mb = &sol->met[iadr];
      d2 =      mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \
         + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz);
      if ( d2 < dmi )  return(0);
    }

    while ( bucket->link[ip1] ) {
      ip1 = bucket->link[ip1];
      pp1 = &mesh->point[ip1];
      ux = pp1->c[0] - ppt->c[0];
      uy = pp1->c[1] - ppt->c[1];
      uz = pp1->c[2] - ppt->c[2];
      d2 =      ma[0]*ux*ux + ma[3]*uy*uy + ma[5]*uz*uz \
         + 2.0*(ma[1]*ux*uy + ma[2]*ux*uz + ma[4]*uy*uz);
      if ( d2 < dmi ) {
        iadr = (ip1-1)*sol->offset + 1;
        mb = &sol->met[iadr];
        d2 =      mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \
           + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz);
        if ( d2 < dmi )  return(0);
      }
    }
  }

  /* bounding box */
  det = ma[0] * (ma[3]*ma[5] - ma[4]*ma[4]) \
      - ma[1] * (ma[1]*ma[5] - ma[2]*ma[4]) \
      + ma[2] * (ma[1]*ma[4] - ma[3]*ma[2]);
  det = 1.0 / det;
  m1 = ma[3]*ma[5] - ma[4]*ma[4];
  m2 = ma[0]*ma[5] - ma[2]*ma[2];
  m3 = ma[0]*ma[3] - ma[1]*ma[1];
  if ( det < 0.0 || m1 < 0.0 )
    return(1);
  else {
    dx = LFILT * sqrt(m1 * det) ;
    dy = LFILT * sqrt(m2 * det) ;
    dz = LFILT * sqrt(m3 * det) ;
  }

  imin = (int)(dd * (ppt->c[0]-dx))-1;
  jmin = (int)(dd * (ppt->c[1]-dy))-1;
  kmin = (int)(dd * (ppt->c[2]-dz))-1;
  imax = (int)(dd * (ppt->c[0]+dx))-1;
  jmax = (int)(dd * (ppt->c[1]+dy))-1;
  kmax = (int)(dd * (ppt->c[2]+dz))-1;

  imin = M_MAX(0,M_MIN(imin,siz-1));
  imax = M_MIN(siz-1,M_MAX(0,imax));
  jmin = M_MAX(0,M_MIN(jmin,siz-1));
  jmax = M_MIN(siz-1,M_MAX(0,jmax));
  kmin = M_MAX(0,M_MIN(kmin,siz-1));
  kmax = M_MIN(siz-1,M_MAX(0,kmax));
  if ( imin == imax && jmin == jmax && kmin == kmax )  return(1);

  /* explore neighbours */
  for (k=kmin; k<=kmax; k++)
    for (j=jmin; j<=jmax; j++) 
      for (i=imin; i<=imax; i++) {
        icc = (k*siz + j)*siz + i;
        ip1 = bucket->head[icc];
        if ( !ip1 )  continue;
        pp1 = &mesh->point[ip1];
        ux = pp1->c[0] - ppt->c[0];
        uy = pp1->c[1] - ppt->c[1];
        uz = pp1->c[2] - ppt->c[2];
        d2 =      ma[0]*ux*ux + ma[3]*uy*uy + ma[5]*uz*uz \
           + 2.0*(ma[1]*ux*uy + ma[2]*ux*uz + ma[4]*uy*uz);
        if ( d2 < dmi ) {
          iadr = (ip1-1)*sol->offset + 1;
          mb = &sol->met[iadr];
          d2 =      mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \
             + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz);
          if ( d2 < dmi )  return(0);
        }

        while ( bucket->link[ip1] ) {
          ip1 = bucket->link[ip1];
          pp1 = &mesh->point[ip1];
          ux = pp1->c[0] - ppt->c[0];
          uy = pp1->c[1] - ppt->c[1];
          uz = pp1->c[2] - ppt->c[2];
          d2 =      ma[0]*ux*ux + ma[3]*uy*uy + ma[5]*uz*uz \
             + 2.0*(ma[1]*ux*uy + ma[2]*ux*uz + ma[4]*uy*uz);
          if ( d2 < dmi ) {
            iadr = (ip1-1)*sol->offset + 1;
            mb = &sol->met[iadr];
            d2 =      mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \
               + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz);
            if ( d2 < dmi )  return(0);
          }
        }
      }

  return(1);
}
Beispiel #2
0
int MMG_opt2peau(pMesh mesh,pSol sol,pQueue queue,int k,double declic) {
  pTetra    pt,pt1;
  pPoint    pa,pb,pc,pd;
  List      list;
  double    abx,aby,abz,acx,acy,acz,adx,ady,adz,v1,v2,v3,vol;
  double    bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz,h[6];
  double     crit;
  double    s[4],dd,rapmin,rapmax;
  int       i,ia,ib,ic,id,iarmax,iarmin;
  int       lon,l,iel,ier;

  ier = 0;
  
  pt = &mesh->tetra[k];
  if ( !pt->v[0] )  return(-1);

  ia = pt->v[0];
  ib = pt->v[1];
  ic = pt->v[2];
  id = pt->v[3];
  pa = &mesh->point[ia];
  pb = &mesh->point[ib];
  pc = &mesh->point[ic];
  pd = &mesh->point[id];

  /* volume */
  abx = pb->c[0] - pa->c[0]; 
  aby = pb->c[1] - pa->c[1]; 
  abz = pb->c[2] - pa->c[2]; 

  acx = pc->c[0] - pa->c[0]; 
  acy = pc->c[1] - pa->c[1]; 
  acz = pc->c[2] - pa->c[2]; 

  adx = pd->c[0] - pa->c[0]; 
  ady = pd->c[1] - pa->c[1]; 
  adz = pd->c[2] - pa->c[2]; 

  v1  = acy*adz - acz*ady;
  v2  = acz*adx - acx*adz;
  v3  = acx*ady - acy*adx;
  vol = abx * v1 + aby * v2 + abz * v3;

  /* max edge */
  h[0] = abx*abx + aby*aby + abz*abz;
  h[1] = acx*acx + acy*acy + acz*acz;
  h[2] = adx*adx + ady*ady + adz*adz;

  bcx = pc->c[0] - pb->c[0];
  bcy = pc->c[1] - pb->c[1];
  bcz = pc->c[2] - pb->c[2];

  bdx = pd->c[0] - pb->c[0];
  bdy = pd->c[1] - pb->c[1];
  bdz = pd->c[2] - pb->c[2];

  cdx = pd->c[0] - pc->c[0];
  cdy = pd->c[1] - pc->c[1];
  cdz = pd->c[2] - pc->c[2];

  h[3] = bcx*bcx + bcy*bcy + bcz*bcz;
  h[4] = bdx*bdx + bdy*bdy + bdz*bdz;
  h[5] = cdx*cdx + cdy*cdy + cdz*cdz;

  /* face areas */
  dd = cdy*bdz - cdz*bdy; 
  s[0] = dd * dd;
  dd = cdz*bdx - cdx*bdz;
  s[0] = s[0] + dd * dd;
  dd = cdx*bdy - cdy*bdx;
  s[0] = s[0] + dd * dd;
  s[0] = sqrt(s[0]);

  s[1] = sqrt(v1*v1 + v2*v2 + v3*v3);

  dd = bdy*adz - bdz*ady;
  s[2] = dd * dd;
  dd = bdz*adx - bdx*adz;
  s[2] = s[2] + dd * dd;
  dd = bdx*ady - bdy*adx;
  s[2] = s[2] + dd * dd;
  s[2] = sqrt(s[2]);

  dd = aby*acz - abz*acy;
  s[3] = dd * dd;
  dd = abz*acx - abx*acz;
  s[3] = s[3] + dd * dd;
  dd = abx*acy - aby*acx;
  s[3] = s[3] + dd * dd;
  s[3] = sqrt(s[3]);

  /* classification */
  rapmin = h[0];
  rapmax = h[0];
  iarmin = 0;
  iarmax = 0;
  for (i=1; i<6; i++) {
    if ( h[i] < rapmin ) {
      rapmin = h[i];
      iarmin = i;
    }
    else if ( h[i] > rapmax ) {
      rapmax = h[i];
      iarmax = i;
    }
  }
  rapmin = sqrt(rapmin);
  rapmax = sqrt(rapmax);
  
  if(mesh->info.imprim < -9) printf("edge : %d %d\n",pt->v[MMG_iare[iarmax][0]],pt->v[MMG_iare[iarmax][1]]);
  /*split edge*/
  lon = MMG_coquil(mesh,k,iarmax,&list);
  if(mesh->info.imprim < 0) {
    //printf("lon %d\n",lon);
    //if(!lon) printf("colle peau, edge peau\n");
  }
  
  if(!lon) {  
   for(i=0 ; i<6 ; i++) {
     lon = MMG_coquil(mesh,k,i,&list);
     if ( lon > 2 ) {
       if ( !MMG_zaldy4(&list.hedg,3*LONMAX) ) {
         fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM MMG_optbdry.\n");
         MMG_kiufree(queue);
         return(0);
       }
       crit = pt->qual;
       for (l=2; l<=lon; l++) {
         iel = list.tetra[l] / 6;
         pt1 = &mesh->tetra[iel];
         if ( pt1->qual > crit )  crit = pt1->qual;
       }
       crit *= OCRIT;
       //crit = min(1000/ALPHAD,crit*1.3);
       ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,1e9);
       if(ier) {/*printf("on a reussi a l'enlever par MMG_swap\n");*/break;}
       if ( ier == 0 && !mesh->info.noinsert) { 
         crit = M_MIN(100./ALPHAD,crit*1.5);
         ier = MMG_spledg(mesh,sol,queue,&list,lon,/*1.8**/crit,declic);
       }
       if(ier) {/*printf("on a reussi a l'enlever par split \n");*/break;}
      
       M_free(list.hedg.item);
      }
    }
    
    //M_free(list.hedg.item);

    if(ier) {
      M_free(list.hedg.item);
      return(1);
    }
    else return(0);
  } else {
 
    if ( !MMG_zaldy4(&list.hedg,3*LONMAX) ) {
      fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM MMG_optbdry.\n");
      MMG_kiufree(queue);
      return(0);
    }
    if ( lon > 2 ) {
      crit = pt->qual;
      for (l=2; l<=lon; l++) {
        iel = list.tetra[l] / 6;
        pt1 = &mesh->tetra[iel];
        if ( pt1->qual > crit )  crit = pt1->qual;
      }
      crit *= OCRIT;
      // crit = min(1000/ALPHAD,crit*1.3);
      ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,1e9);
      if ( ier == 0 && !mesh->info.noinsert) {
        crit = M_MIN(100./ALPHAD,crit*1.5);
        ier = MMG_spledg(mesh,sol,queue,&list,lon,/*1.8**/crit,declic);
      }
    }
   
  
    M_free(list.hedg.item);
    if(ier) return(1);
    else return(0);
 }
  return(1);
    
}
Beispiel #3
0
int MMG_buckin_iso(pMesh mesh,pSol sol,pBucket bucket,int ip) {
  pPoint	ppt,pp1;
  double	dd,d2,ux,uy,uz,hpi,hp1,hp2;
  int		i,j,k,ii,jj,kk,ic,icc,siz,ip1;
  int 		imin,imax,jmin,jmax,kmin,kmax;

  ppt = &mesh->point[ip];
  siz = bucket->size;
  dd  = siz / (double)PRECI;
  hpi = LFILT * sol->met[ip];
  hp1 = hpi*hpi;

  ii = M_MAX(0,(int)(dd * ppt->c[0])-1);
  jj = M_MAX(0,(int)(dd * ppt->c[1])-1);
  kk = M_MAX(0,(int)(dd * ppt->c[2])-1);
  ic = (kk*siz + jj)*siz + ii;

  /* check current cell */
  if ( bucket->head[ic] ) {
    ip1 = bucket->head[ic];
    pp1 = &mesh->point[ip1];
    hp2 = LFILT * sol->met[ip1];
    ux = pp1->c[0] - ppt->c[0];
    uy = pp1->c[1] - ppt->c[1];
    uz = pp1->c[2] - ppt->c[2];
    d2 = ux*ux + uy*uy + uz*uz;
    if ( d2 < hp1 || d2 < hp2*hp2 )  {
//printf("filtre current %d : %e %e %e %e\n",ip1,d2,hp1,d2,hp2*hp2);
      return(0);
    }

    while ( bucket->link[ip1] ) {
      ip1 = bucket->link[ip1];
      pp1 = &mesh->point[ip1];
      hp2 = LFILT * sol->met[ip1];
      ux = pp1->c[0] - ppt->c[0];
      uy = pp1->c[1] - ppt->c[1];
      uz = pp1->c[2] - ppt->c[2];
      d2 = ux*ux + uy*uy + uz*uz;
      if ( d2 < hp1 || d2 < hp2*hp2 )  {
//printf("filtre link %d : %e %e %e %e\n",ip1,d2,hp1,d2,hp2*hp2);
        return(0);
      }
    }
  }

  /* explore neighbors */
  imin = (int)(dd * (ppt->c[0]-hpi))-1;
  jmin = (int)(dd * (ppt->c[1]-hpi))-1;
  kmin = (int)(dd * (ppt->c[2]-hpi))-1;
  imax = (int)(dd * (ppt->c[0]+hpi))-1;
  jmax = (int)(dd * (ppt->c[1]+hpi))-1;
  kmax = (int)(dd * (ppt->c[2]+hpi))-1;

  imin = M_MAX(0,M_MIN(imin,siz-1));
  imax = M_MIN(siz-1,M_MAX(0,imax));
  jmin = M_MAX(0,M_MIN(jmin,siz-1));
  jmax = M_MIN(siz-1,M_MAX(0,jmax));
  kmin = M_MAX(0,M_MIN(kmin,siz-1));
  kmax = M_MIN(siz-1,M_MAX(0,kmax));
  if ( imin == imax && jmin == jmax && kmin == kmax )  return(1);

  for (k=kmin; k<=kmax; k++)
    for (j=jmin; j<=jmax; j++) 
      for (i=imin; i<=imax; i++) {
        icc = (k*siz + j)*siz + i;
        ip1 = bucket->head[icc];
        if ( !ip1 )  continue;
        pp1 = &mesh->point[ip1];
        hp2 = LFILT * sol->met[ip1];
        ux = pp1->c[0] - ppt->c[0];
        uy = pp1->c[1] - ppt->c[1];
        uz = pp1->c[2] - ppt->c[2];
        d2 = ux*ux + uy*uy + uz*uz;
        if ( d2 < hp1 || d2 < hp2*hp2 ) {
/*	 printf("other cell %d %e < %e -- %e < %e \n",ip1,d2,MMG_length(mesh,sol,ip,ip1),d2,hp2*hp2);
	 printf("on filtre avec %d : %e %e %e\n",ip1,pp1->c[0],pp1->c[1],pp1->c[2]);
	*/ return(0);
	}

        while ( bucket->link[ip1] ) {
          ip1 = bucket->link[ip1];
          pp1 = &mesh->point[ip1];
          hp2 = LFILT * sol->met[ip1];
          ux = pp1->c[0] - ppt->c[0];
          uy = pp1->c[1] - ppt->c[1];
          uz = pp1->c[2] - ppt->c[2];
          d2 = ux*ux + uy*uy + uz*uz;
          if ( d2 < hp1 || d2 < hp2*hp2 )  {
//	    printf("link cell %d %e < %e -- %e < %e \n",ip1,d2,hp1,d2,hp2*hp2);
	    return(0);
	  }
        }
      }

  return(1);
}
void splitFacesFromEquilateral(T *_data, unsigned int _width, unsigned int _height, Face<T> **_faces ) {
    // Alloc data.
    const uint32_t faceWidth = (_height + 1)/2;
    const uint32_t faceHeight = faceWidth;

    // Get source parameters.
    const float srcWidthMinusOne  = float(int(_width-1));
    const float srcHeightMinusOne = float(int(_height-1));
    const float invfaceWidthf = 1.0f/float(faceWidth);

    for (int i = 0; i < 6; i++) {
        _faces[i] = new Face<T>();
        _faces[i]->id = i;
        _faces[i]->data = new T[3 * faceWidth * faceHeight];
        _faces[i]->width = faceWidth;
        _faces[i]->height = faceHeight;
        _faces[i]->currentOffset = 0;

        for (uint32_t yy = 0; yy < faceHeight; ++yy) {
            T* dstRowData = &_faces[i]->data[yy * faceWidth * 3];

            for (uint32_t xx = 0; xx < faceWidth; ++xx) {
                T* dstColumnData = &dstRowData[xx * 3];

                // Cubemap (u,v) on current face.
                const float uu = 2.0f*xx*invfaceWidthf-1.0f;
                const float vv = 2.0f*yy*invfaceWidthf-1.0f;

                // Get cubemap vector (x,y,z) from (u,v,faceIdx).
                float vec[3];
                texelCoordToVec(vec, uu, vv, i);

                // Convert cubemap vector (x,y,z) to latlong (u,v).
                float xSrcf;
                float ySrcf;
                latLongFromVec(xSrcf, ySrcf, vec);

                // Convert from [0..1] to [0..(size-1)] range.
                xSrcf *= srcWidthMinusOne;
                ySrcf *= srcHeightMinusOne;

                // Sample from latlong (u,v).
                #ifdef USE_BILINEAR_INTERPOLATION
                    const uint32_t x0 = ftou(xSrcf);
                    const uint32_t y0 = ftou(ySrcf);
                    const uint32_t x1 = M_MIN(x0+1, _width-1);
                    const uint32_t y1 = M_MIN(y0+1, _height-1);

                    const T *src0 = &_data[y0 * _width * 3 + x0 * 3];
                    const T *src1 = &_data[y0 * _width * 3 + x1 * 3];
                    const T *src2 = &_data[y1 * _width * 3 + x0 * 3];
                    const T *src3 = &_data[y1 * _width * 3 + x1 * 3];

                    const float tx = xSrcf - float(int(x0));
                    const float ty = ySrcf - float(int(y0));
                    const float invTx = 1.0f - tx;
                    const float invTy = 1.0f - ty;

                    T p0[3];
                    T p1[3];
                    T p2[3];
                    T p3[3];
                    vec3Mul(p0, src0, invTx*invTy);
                    vec3Mul(p1, src1,    tx*invTy);
                    vec3Mul(p2, src2, invTx*   ty);
                    vec3Mul(p3, src3,    tx*   ty);

                    const T rr = p0[0] + p1[0] + p2[0] + p3[0];
                    const T gg = p0[1] + p1[1] + p2[1] + p3[1];
                    const T bb = p0[2] + p1[2] + p2[2] + p3[2];

                    dstColumnData[0] = rr;
                    dstColumnData[1] = gg;
                    dstColumnData[2] = bb;
                #else
                    const uint32_t xSrc = ftou(xSrcf);
                    const uint32_t ySrc = ftou(ySrcf);

                    dstColumnData[0] = _data[ySrc * _width * 3 + xSrc * 3 + 0];
                    dstColumnData[1] = _data[ySrc * _width * 3 + xSrc * 3 + 1];
                    dstColumnData[2] = _data[ySrc * _width * 3 + xSrc * 3 + 2];
                #endif
            }
        }
    }
}