void Mesh::buildBasisCycles() { std::vector<BasisCycle> basisCycles; buildContractibleCycles(basisCycles); buildNonContractibleCycles(basisCycles); // build A Eigen::SparseMatrix<double> A((int)basisCycles.size(), (int)edges.size()); A.setZero(); std::vector<Eigen::Triplet<double>> ATriplet; for (int i = 0; i < (int)basisCycles.size(); i++) { for (int j = 0; j < (int)basisCycles[i].size(); j++) { HalfEdgeIter he = basisCycles[i][j]; int e = he->edge->index; double coefficient = sqrt((he->cotan() + he->flip->cotan()) * 0.5); if (coefficient != coefficient) coefficient = 0; // check for negative cotan weights if (he == he->edge->he) { ATriplet.push_back(Eigen::Triplet<double>(i, e, coefficient)); } else { ATriplet.push_back(Eigen::Triplet<double>(i, e, -coefficient)); } } } A.setFromTriplets(ATriplet.begin(), ATriplet.end()); solver.compute(A); }
double Mesh :: connectionOneForm(HalfEdgeIter h) const { double angle = 0.0; // coclosed term double star1 = 0.5 * ( h->cotan() + h->flip->cotan() ); double u0 = h->flip->vertex->potential; double u1 = h->vertex->potential; angle += star1*(u1 - u0); // harmonic term for(unsigned k = 0; k < h->harmonicBases.size(); ++k) angle += this->harmonicCoefs[k] * h->harmonicBases[k]; return angle; }