/* 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); }
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); }
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 } } } }