static void tv_iter(int nx, const PetscScalar *x, PetscScalar *y){ // deg: degree of polynomials // nx: some context variable from Petsc interface // x: vector with which matrix A is multiplied // y = A*x const int MAT_ENTRIES = pars -> get_int("MAT_ENTRIES"); //hard coded atm, move to parameters later const int DEG = pars -> get_int("DEG"); //const int DEG = 8; std::vector<PetscScalar> Told(MAT_ENTRIES); std::vector<PetscScalar> Tcur(MAT_ENTRIES); std::vector<PetscScalar> Tnew(MAT_ENTRIES); std::vector<PetscScalar> tmp(MAT_ENTRIES); // initialize chebyshev polynomials tv2( nx, &x[0], &Tcur[0]); equal_arrays(&x[0], &Told[0]); // if deg is 1 or less return initialised values if (DEG >=1){ // else iteratively calculate chebyshev polynomials up to deg // T_n(B) = 2*B(T_{n-1}(B))-T_{n-2}(B) for (int n = 2; n <= DEG; n++){ // store B(Tcur(Bx)) in tmp1 tv2(nx, &Tcur[0], &tmp[0]); // scale tmp1 scale_array(2., &tmp[0], &tmp[0]); //calculate new polynomial subtract_arrays(&Told[0], &tmp[0], &y[0]); // overwrite new variables equal_arrays(&Tcur[0], &Told[0]); equal_arrays(&y[0], &Tcur[0]); } } }
void Mesh::skin(uint start) { intA TT; uintA Tt; getTriNeighborsList(*this, Tt, TT); arr Tn; getTriNormals(*this, Tn); uintA goodTris; boolA added(T.d0); goodTris.append(start); added=false; added(start)=true; uint t, tt, r, i, k; int m; double p, mp=0; for(k=0; k<goodTris.N; k++) { t=goodTris(k); for(r=0; r<3; r++) { //select from all neighbors the one most parallel m=-1; for(i=0; i<Tt(t, r); i++) { tt=TT(t, r, i); p=scalarProduct(Tn[t], Tn[tt]); if(m==-1 || p>mp) { m=tt; mp=p; } } if(m!=-1 && !added(m)) { goodTris.append(m); added(m)=true; } } } uintA Tnew(k, 3); for(k=0; k<goodTris.N; k++) { t=goodTris(k); Tnew(k, 0)=T(t, 0); Tnew(k, 1)=T(t, 1); Tnew(k, 2)=T(t, 2); } T=Tnew; cout <<T <<endl; }
void Mesh::clean() { uint i, j, idist=0; Vector a, b, c, m; double mdist=0.; arr Tc(T.d0, 3); //tri centers arr Tn(T.d0, 3); //tri normals uintA Vt(V.d0); intA VT(V.d0, 100); //tri-neighbors to a vertex Vt.setZero(); VT=-1; for(i=0; i<T.d0; i++) { a.set(&V(T(i, 0), 0)); b.set(&V(T(i, 1), 0)); c.set(&V(T(i, 2), 0)); //tri center m=(a+b+c)/3.; Tc(i, 0)=m.x; Tc(i, 1)=m.y; Tc(i, 2)=m.z; //farthest tri if(m.length()>mdist) { mdist=m.length(); idist=i; } //tri normal b-=a; c-=a; a=b^c; a.normalize(); Tn(i, 0)=a.x; Tn(i, 1)=a.y; Tn(i, 2)=a.z; //vertex neighbor count j=T(i, 0); VT(j, Vt(j))=i; Vt(j)++; j=T(i, 1); VT(j, Vt(j))=i; Vt(j)++; j=T(i, 2); VT(j, Vt(j))=i; Vt(j)++; } //step through tri list and flip them if necessary boolA Tisok(T.d0); Tisok=false; uintA Tok; //contains the list of all tris that are ok oriented uintA Tnew(T.d0, T.d1); Tok.append(idist); Tisok(idist)=true; int A=0, B=0, D; uint r, k, l; intA neighbors; for(k=0; k<Tok.N; k++) { i=Tok(k); Tnew(k, 0)=T(i, 0); Tnew(k, 1)=T(i, 1); Tnew(k, 2)=T(i, 2); for(r=0; r<3; r++) { if(r==0) { A=T(i, 0); B=T(i, 1); /*C=T(i, 2);*/ } if(r==1) { A=T(i, 1); B=T(i, 2); /*C=T(i, 0);*/ } if(r==2) { A=T(i, 2); B=T(i, 0); /*C=T(i, 1);*/ } //check all triangles that share A & B setSection(neighbors, VT[A], VT[B]); neighbors.removeAllValues(-1); if(neighbors.N>2) MT_MSG("edge shared by more than 2 triangles " <<neighbors); neighbors.removeValue(i); //if(!neighbors.N) cout <<"mesh.clean warning: edge has only one triangle that shares it" <<endl; //orient them correctly for(l=0; l<neighbors.N; l++) { j=neighbors(l); //j is a neighboring triangle sharing A & B D=-1; //align the neighboring triangle and let D be its 3rd vertex if((int)T(j, 0)==A && (int)T(j, 1)==B) D=T(j, 2); if((int)T(j, 0)==A && (int)T(j, 2)==B) D=T(j, 1); if((int)T(j, 1)==A && (int)T(j, 2)==B) D=T(j, 0); if((int)T(j, 1)==A && (int)T(j, 0)==B) D=T(j, 2); if((int)T(j, 2)==A && (int)T(j, 0)==B) D=T(j, 1); if((int)T(j, 2)==A && (int)T(j, 1)==B) D=T(j, 0); if(D==-1) HALT("dammit"); //determine orientation if(!Tisok(j)) { T(j, 0)=B; T(j, 1)=A; T(j, 2)=D; Tok.append(j); Tisok(j)=true; } else { //check if consistent! } } #if 0 //compute their rotation if(neighbors.N>1) { double phi, phimax; int jmax=-1; Vector ni, nj; for(l=0; l<neighbors.N; l++) { j=neighbors(l); //j is a neighboring triangle sharing A & B a.set(&V(T(i, 0), 0)); b.set(&V(T(i, 1), 0)); c.set(&V(T(i, 2), 0)); b-=a; c-=a; a=b^c; a.normalize(); ni = a; a.set(&V(T(j, 0), 0)); b.set(&V(T(j, 1), 0)); c.set(&V(T(j, 2), 0)); b-=a; c-=a; a=b^c; a.normalize(); nj = a; Quaternion q; q.setDiff(ni, -nj); q.getDeg(phi, c); a.set(&V(A, 0)); b.set(&V(B, 0)); if(c*(a-b) < 0.) phi+=180.; if(jmax==-1 || phi>phimax) { jmax=j; phimax=phi; } } if(!Tisok(jmax)) { Tok.append(jmax); Tisok(jmax)=true; } } else { j = neighbors(0); if(!Tisok(j)) { Tok.append(j); Tisok(j)=true; } } #endif } } if(k<T.d0) { cout <<"mesh.clean warning: not all triangles connected: " <<k <<"<" <<T.d0 <<endl; cout <<"WARNING: cutting of all non-connected triangles!!" <<endl; Tnew.resizeCopy(k, 3); T=Tnew; deleteUnusedVertices(); } computeNormals(); }