Example #1
0
    void dual(Manifold& m)
    {
        // Create new vertices. Each face becomes a vertex whose position
        // is the centre of the face
        int i = 0;
        FaceAttributeVector<int> ftouched;
        vector<Vec3d> vertices;
        vertices.resize(m.no_faces());
        for(auto f : m.faces())
            vertices[ftouched[f] = i++] = centre(m, f);
        
        // Create new faces. Each vertex is a new face with N=valency of vertex
        // edges.
        vector<int> faces;
        vector<int> indices;
        for(auto v : m.vertices())
            if(valency(m, v) > 2 && !(boundary(m, v)))
            {
//				int N = circulate_vertex_ccw(m, v, (std::function<void(FaceID)>)[&](FaceID fid) {
//                    indices.push_back(ftouched[fid]);
//                });

                Walker w = m.walker(v);
                for(; !w.full_circle(); w = w.circulate_vertex_ccw()){
                    indices.push_back(ftouched[w.face()]);
                }
                int N = w.no_steps();
                // Insert face valency in the face vector.
                faces.push_back(N);
            }
        
        // Clear the manifold before new geometry is inserted.
        m.clear();
        
        // And build
        m.build(    vertices.size(),
                reinterpret_cast<double*>(&vertices[0]),
                faces.size(),
                &faces[0],
                &indices[0]);
    }
Example #2
0
void mean_curvature_smooth(Manifold& m, bool implicit, double lambda)
{
    using EigMat = SparseMatrix<double>;
    using EigVec = VectorXd;
    
    int N = (int)m.no_vertices();
    VertexAttributeVector<int> indices(m.allocated_vertices());
    VertexAttributeVector<double> areas(m.allocated_vertices());
    int i=0;
    for(auto v: m.vertices()) {
        indices[v] = i++;
        areas[v] = mixed_area(m, v);
    }
    

    EigMat K(N,N);      // Sparse matrix initialized with 0
    EigVec X(N),Y(N),Z(N);
    EigVec Xp(N), Yp(N), Zp(N);
    
    //-----------------------------------------------------------
    // Student implementation
    //-----------------------------------------------------------
    double epsilon = 1e-5;
    for (auto vkey : m.vertices())
    {
        int i = indices[vkey];
        for (auto w = m.walker(vkey); !w.full_circle(); w = w.circulate_vertex_ccw())
        {
            int j = indices[w.vertex()];
            assert(i != j);
            
            if (i > j
                or w.face() == HMesh::InvalidFaceID
                or w.opp().face() == HMesh::InvalidFaceID)
            {
                continue; // Avoid recomputation
            }
            
            auto pi = m.pos(w.opp().vertex());
            auto pj = m.pos(w.vertex());
            auto pl = m.pos(w.opp().next().vertex());
            auto pk = m.pos(w.next().vertex());
            
            double cot_alpha_ij = dot(pj - pk, pi - pk) /
                                ( cross(pi - pk, pj - pk).length() + epsilon);
            double cot_beta_ij = dot(pj - pl, pi - pl) /
                                ( cross(pi - pl, pj - pl).length() + epsilon);
            
            double Ai = areas[w.opp().vertex()];
            double Aj = areas[w.vertex()];
            
            double Lij = (cot_alpha_ij + cot_beta_ij)
                        / sqrt(Ai*Aj + epsilon);
            
            K.coeffRef(i, j) = Lij;
            K.coeffRef(j, i) = Lij;
            K.coeffRef(i, i) -= Lij;
            K.coeffRef(j, j) -= Lij;
            
        }
    }
    
    EigMat I(N,N);
    for (int i = 0; i < N; i++)
    {
        I.coeffRef(i, i) = 1;
    }
    
    K = I - K*lambda;
    
    
    for (auto vkey : m.vertices())
    {
        auto p = m.pos(vkey);
        int i = indices[vkey];
        X.coeffRef(i) = p[0];
        Y.coeffRef(i) = p[1];
        Z.coeffRef(i) = p[2];
    }
    
    // Solve
    SimplicialLLT<EigMat> solver(K);
    Xp = solver.solve(X);
    Yp = solver.solve(Y);
    Zp = solver.solve(Z);
    
    // End student implementation
    //-----------------------------------------------------------
        
    for(auto v: m.vertices())
    {
        int i = indices[v];
        m.pos(v) = Vec3d(Xp[i], Yp[i], Zp[i]);
    }
}