mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-24 01:01:15 -06:00
Building igl statically and moving to the dep scripts
Fixing dep build script on Windows and removing some warnings. Use bundled igl by default. Not building with the dependency scripts if not explicitly stated. This way, it will stay in Fix the libigl patch to include C source files in header only mode.
This commit is contained in:
parent
89e39e3895
commit
2ae2672ee9
1095 changed files with 181 additions and 5 deletions
|
|
@ -1,245 +0,0 @@
|
|||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#include "planarize_quad_mesh.h"
|
||||
#include "quad_planarity.h"
|
||||
#include <Eigen/Sparse>
|
||||
#include <Eigen/Eigenvalues>
|
||||
#include <iostream>
|
||||
|
||||
namespace igl
|
||||
{
|
||||
template <typename DerivedV, typename DerivedF>
|
||||
class PlanarizerShapeUp
|
||||
{
|
||||
protected:
|
||||
// number of faces, number of vertices
|
||||
long numV, numF;
|
||||
// references to the input faces and vertices
|
||||
const Eigen::PlainObjectBase<DerivedV> &Vin;
|
||||
const Eigen::PlainObjectBase<DerivedF> &Fin;
|
||||
|
||||
// vector consisting of the vertex positions stacked: [x;y;z;x;y;z...]
|
||||
// vector consisting of a weight per face (currently all set to 1)
|
||||
// vector consisting of the projected face vertices (might be different for the same vertex belonging to different faces)
|
||||
Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, 1> Vv, weightsSqrt, P;
|
||||
|
||||
// Matrices as in the paper
|
||||
// Q: lhs matrix
|
||||
// Ni: matrix that subtracts the mean of a face from the 4 vertices of a face
|
||||
Eigen::SparseMatrix<typename DerivedV::Scalar > Q, Ni;
|
||||
Eigen::SimplicialLDLT<Eigen::SparseMatrix<typename DerivedV::Scalar > > solver;
|
||||
|
||||
int maxIter;
|
||||
double threshold;
|
||||
const int ni = 4;
|
||||
|
||||
// Matrix assemblers
|
||||
inline void assembleQ();
|
||||
inline void assembleP();
|
||||
inline void assembleNi();
|
||||
|
||||
// Selects out of Vv the 4 vertices belonging to face fi
|
||||
inline void assembleSelector(int fi,
|
||||
Eigen::SparseMatrix<typename DerivedV::Scalar > &S);
|
||||
|
||||
|
||||
public:
|
||||
// Init - assemble stacked vector and lhs matrix, factorize
|
||||
inline PlanarizerShapeUp(const Eigen::PlainObjectBase<DerivedV> &V_,
|
||||
const Eigen::PlainObjectBase<DerivedF> &F_,
|
||||
const int maxIter_,
|
||||
const double &threshold_);
|
||||
// Planarization - output to Vout
|
||||
inline void planarize(Eigen::PlainObjectBase<DerivedV> &Vout);
|
||||
};
|
||||
}
|
||||
|
||||
//Implementation
|
||||
|
||||
template <typename DerivedV, typename DerivedF>
|
||||
inline igl::PlanarizerShapeUp<DerivedV, DerivedF>::PlanarizerShapeUp(const Eigen::PlainObjectBase<DerivedV> &V_,
|
||||
const Eigen::PlainObjectBase<DerivedF> &F_,
|
||||
const int maxIter_,
|
||||
const double &threshold_):
|
||||
numV(V_.rows()),
|
||||
numF(F_.rows()),
|
||||
Vin(V_),
|
||||
Fin(F_),
|
||||
weightsSqrt(Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, 1>::Ones(numF,1)),
|
||||
maxIter(maxIter_),
|
||||
threshold(threshold_)
|
||||
{
|
||||
// assemble stacked vertex position vector
|
||||
Vv.setZero(3*numV,1);
|
||||
for (int i =0;i<numV;++i)
|
||||
Vv.segment(3*i,3) = Vin.row(i);
|
||||
// assemble and factorize lhs matrix
|
||||
assembleQ();
|
||||
};
|
||||
|
||||
template <typename DerivedV, typename DerivedF>
|
||||
inline void igl::PlanarizerShapeUp<DerivedV, DerivedF>::assembleQ()
|
||||
{
|
||||
std::vector<Eigen::Triplet<typename DerivedV::Scalar> > tripletList;
|
||||
|
||||
// assemble the Ni matrix
|
||||
assembleNi();
|
||||
|
||||
for (int fi = 0; fi< numF; fi++)
|
||||
{
|
||||
Eigen::SparseMatrix<typename DerivedV::Scalar > Sfi;
|
||||
assembleSelector(fi, Sfi);
|
||||
|
||||
// the final matrix per face
|
||||
Eigen::SparseMatrix<typename DerivedV::Scalar > Qi = weightsSqrt(fi)*Ni*Sfi;
|
||||
// put it in the correct block of Q
|
||||
// todo: this can be made faster by omitting the selector matrix
|
||||
for (int k=0; k<Qi.outerSize(); ++k)
|
||||
for (typename Eigen::SparseMatrix<typename DerivedV::Scalar >::InnerIterator it(Qi,k); it; ++it)
|
||||
{
|
||||
typename DerivedV::Scalar val = it.value();
|
||||
int row = it.row();
|
||||
int col = it.col();
|
||||
tripletList.push_back(Eigen::Triplet<typename DerivedV::Scalar>(row+3*ni*fi,col,val));
|
||||
}
|
||||
}
|
||||
|
||||
Q.resize(3*ni*numF,3*numV);
|
||||
Q.setFromTriplets(tripletList.begin(), tripletList.end());
|
||||
// the actual lhs matrix is Q'*Q
|
||||
// prefactor that matrix
|
||||
solver.compute(Q.transpose()*Q);
|
||||
if(solver.info()!=Eigen::Success)
|
||||
{
|
||||
std::cerr << "Cholesky failed - PlanarizerShapeUp.cpp" << std::endl;
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename DerivedV, typename DerivedF>
|
||||
inline void igl::PlanarizerShapeUp<DerivedV, DerivedF>::assembleNi()
|
||||
{
|
||||
std::vector<Eigen::Triplet<typename DerivedV::Scalar>> tripletList;
|
||||
for (int ii = 0; ii< ni; ii++)
|
||||
{
|
||||
for (int jj = 0; jj< ni; jj++)
|
||||
{
|
||||
tripletList.push_back(Eigen::Triplet<typename DerivedV::Scalar>(3*ii+0,3*jj+0,-1./ni));
|
||||
tripletList.push_back(Eigen::Triplet<typename DerivedV::Scalar>(3*ii+1,3*jj+1,-1./ni));
|
||||
tripletList.push_back(Eigen::Triplet<typename DerivedV::Scalar>(3*ii+2,3*jj+2,-1./ni));
|
||||
}
|
||||
tripletList.push_back(Eigen::Triplet<typename DerivedV::Scalar>(3*ii+0,3*ii+0,1.));
|
||||
tripletList.push_back(Eigen::Triplet<typename DerivedV::Scalar>(3*ii+1,3*ii+1,1.));
|
||||
tripletList.push_back(Eigen::Triplet<typename DerivedV::Scalar>(3*ii+2,3*ii+2,1.));
|
||||
}
|
||||
Ni.resize(3*ni,3*ni);
|
||||
Ni.setFromTriplets(tripletList.begin(), tripletList.end());
|
||||
}
|
||||
|
||||
//assumes V stacked [x;y;z;x;y;z...];
|
||||
template <typename DerivedV, typename DerivedF>
|
||||
inline void igl::PlanarizerShapeUp<DerivedV, DerivedF>::assembleSelector(int fi,
|
||||
Eigen::SparseMatrix<typename DerivedV::Scalar > &S)
|
||||
{
|
||||
|
||||
std::vector<Eigen::Triplet<typename DerivedV::Scalar>> tripletList;
|
||||
for (int fvi = 0; fvi< ni; fvi++)
|
||||
{
|
||||
int vi = Fin(fi,fvi);
|
||||
tripletList.push_back(Eigen::Triplet<typename DerivedV::Scalar>(3*fvi+0,3*vi+0,1.));
|
||||
tripletList.push_back(Eigen::Triplet<typename DerivedV::Scalar>(3*fvi+1,3*vi+1,1.));
|
||||
tripletList.push_back(Eigen::Triplet<typename DerivedV::Scalar>(3*fvi+2,3*vi+2,1.));
|
||||
}
|
||||
|
||||
S.resize(3*ni,3*numV);
|
||||
S.setFromTriplets(tripletList.begin(), tripletList.end());
|
||||
|
||||
}
|
||||
|
||||
//project all faces to their closest planar face
|
||||
template <typename DerivedV, typename DerivedF>
|
||||
inline void igl::PlanarizerShapeUp<DerivedV, DerivedF>::assembleP()
|
||||
{
|
||||
P.setZero(3*ni*numF);
|
||||
for (int fi = 0; fi< numF; fi++)
|
||||
{
|
||||
// todo: this can be made faster by omitting the selector matrix
|
||||
Eigen::SparseMatrix<typename DerivedV::Scalar > Sfi;
|
||||
assembleSelector(fi, Sfi);
|
||||
Eigen::SparseMatrix<typename DerivedV::Scalar > NSi = Ni*Sfi;
|
||||
|
||||
Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, 1> Vi = NSi*Vv;
|
||||
Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic> CC(3,ni);
|
||||
for (int i = 0; i <ni; ++i)
|
||||
CC.col(i) = Vi.segment(3*i, 3);
|
||||
Eigen::Matrix<typename DerivedV::Scalar, 3, 3> C = CC*CC.transpose();
|
||||
|
||||
// Alec: Doesn't compile
|
||||
Eigen::EigenSolver<Eigen::Matrix<typename DerivedV::Scalar, 3, 3>> es(C);
|
||||
// the real() is for compilation purposes
|
||||
Eigen::Matrix<typename DerivedV::Scalar, 3, 1> lambda = es.eigenvalues().real();
|
||||
Eigen::Matrix<typename DerivedV::Scalar, 3, 3> U = es.eigenvectors().real();
|
||||
int min_i;
|
||||
lambda.cwiseAbs().minCoeff(&min_i);
|
||||
U.col(min_i).setZero();
|
||||
Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic> PP = U*U.transpose()*CC;
|
||||
for (int i = 0; i <ni; ++i)
|
||||
P.segment(3*ni*fi+3*i, 3) = weightsSqrt[fi]*PP.col(i);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename DerivedV, typename DerivedF>
|
||||
inline void igl::PlanarizerShapeUp<DerivedV, DerivedF>::planarize(Eigen::PlainObjectBase<DerivedV> &Vout)
|
||||
{
|
||||
Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, 1> planarity;
|
||||
Vout = Vin;
|
||||
|
||||
for (int iter =0; iter<maxIter; ++iter)
|
||||
{
|
||||
igl::quad_planarity(Vout, Fin, planarity);
|
||||
typename DerivedV::Scalar nonPlanarity = planarity.cwiseAbs().maxCoeff();
|
||||
//std::cerr<<"iter #"<<iter<<": max non-planarity: "<<nonPlanarity<<std::endl;
|
||||
if (nonPlanarity<threshold)
|
||||
break;
|
||||
assembleP();
|
||||
Vv = solver.solve(Q.transpose()*P);
|
||||
if(solver.info()!=Eigen::Success)
|
||||
{
|
||||
std::cerr << "Linear solve failed - PlanarizerShapeUp.cpp" << std::endl;
|
||||
assert(0);
|
||||
}
|
||||
for (int i =0;i<numV;++i)
|
||||
Vout.row(i) << Vv.segment(3*i,3).transpose();
|
||||
}
|
||||
// set the mean of Vout to the mean of Vin
|
||||
Eigen::Matrix<typename DerivedV::Scalar, 1, 3> oldMean, newMean;
|
||||
oldMean = Vin.colwise().mean();
|
||||
newMean = Vout.colwise().mean();
|
||||
Vout.rowwise() += (oldMean - newMean);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename DerivedV, typename DerivedF>
|
||||
IGL_INLINE void igl::planarize_quad_mesh(const Eigen::PlainObjectBase<DerivedV> &Vin,
|
||||
const Eigen::PlainObjectBase<DerivedF> &Fin,
|
||||
const int maxIter,
|
||||
const double &threshold,
|
||||
Eigen::PlainObjectBase<DerivedV> &Vout)
|
||||
{
|
||||
PlanarizerShapeUp<DerivedV, DerivedF> planarizer(Vin, Fin, maxIter, threshold);
|
||||
planarizer.planarize(Vout);
|
||||
}
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
template void igl::planarize_quad_mesh<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, double const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue