Fix uvunwrap
The As-Rigid-As-Possible method of parametrization sometimes failed, so added Least-Squares-Conformal-Maps method as a fallback option.master
parent
aadee8df08
commit
a2a5b774aa
|
@ -1,4 +1,5 @@
|
|||
#include <igl/arap.h>
|
||||
#include <igl/lscm.h>
|
||||
#include <igl/boundary_loop.h>
|
||||
#include <igl/harmonic.h>
|
||||
#include <igl/map_vertices_to_circle.h>
|
||||
|
@ -8,35 +9,9 @@
|
|||
namespace simpleuv
|
||||
{
|
||||
|
||||
// Modified from the libigl example code
|
||||
// https://github.com/libigl/libigl/blob/master/tutorial/503_ARAPParam/main.cpp
|
||||
bool parametrize(const std::vector<Vertex> &verticies,
|
||||
const std::vector<Face> &faces,
|
||||
std::vector<TextureCoord> &vertexUvs)
|
||||
void parametrizeUsingARAP(const Eigen::MatrixXd &V, const Eigen::MatrixXi &F, const Eigen::VectorXi &bnd, Eigen::MatrixXd &V_uv)
|
||||
{
|
||||
if (verticies.empty() || faces.empty())
|
||||
return false;
|
||||
|
||||
//qDebug() << "parametrize vertices:" << verticies.size() << "faces:" << faces.size();
|
||||
|
||||
Eigen::MatrixXd V(verticies.size(), 3);
|
||||
Eigen::MatrixXi F(faces.size(), 3);
|
||||
Eigen::MatrixXd V_uv;
|
||||
Eigen::MatrixXd initial_guess;
|
||||
|
||||
for (decltype(verticies.size()) i = 0; i < verticies.size(); i++) {
|
||||
const auto &vertex = verticies[i];
|
||||
V.row(i) << vertex.xyz[0], vertex.xyz[1], vertex.xyz[2];
|
||||
}
|
||||
|
||||
for (decltype(faces.size()) i = 0; i < faces.size(); i++) {
|
||||
const auto &face = faces[i];
|
||||
F.row(i) << face.indices[0], face.indices[1], face.indices[2];
|
||||
}
|
||||
|
||||
// Compute the initial solution for ARAP (harmonic parametrization)
|
||||
Eigen::VectorXi bnd;
|
||||
igl::boundary_loop(F,bnd);
|
||||
Eigen::MatrixXd bnd_uv;
|
||||
igl::map_vertices_to_circle(V,bnd,bnd_uv);
|
||||
|
||||
|
@ -58,15 +33,82 @@ bool parametrize(const std::vector<Vertex> &verticies,
|
|||
V_uv = initial_guess;
|
||||
|
||||
arap_solve(bc,arap_data,V_uv);
|
||||
}
|
||||
|
||||
void parametrizeUsingLSCM(const Eigen::MatrixXd &V, const Eigen::MatrixXi &F, const Eigen::VectorXi &bnd, Eigen::MatrixXd &V_uv)
|
||||
{
|
||||
Eigen::VectorXi b(2,1);
|
||||
b(0) = bnd(0);
|
||||
b(1) = bnd(round(bnd.size()/2));
|
||||
Eigen::MatrixXd bc(2,2);
|
||||
bc<<0,0,1,0;
|
||||
|
||||
// LSCM parametrization
|
||||
igl::lscm(V,F,b,bc,V_uv);
|
||||
}
|
||||
|
||||
bool extractResult(const std::vector<Vertex> &verticies, const Eigen::MatrixXd &V_uv, std::vector<TextureCoord> &vertexUvs)
|
||||
{
|
||||
vertexUvs.clear();
|
||||
auto isCoordValid = [=](float coord) {
|
||||
if (std::isnan(coord) || std::isinf(coord))
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
for (decltype(verticies.size()) i = 0; i < verticies.size(); i++) {
|
||||
TextureCoord coord;
|
||||
coord.uv[0] = V_uv.row(i)[0];
|
||||
coord.uv[1] = V_uv.row(i)[1];
|
||||
vertexUvs.push_back(coord);
|
||||
if (isCoordValid(coord.uv[0]) && isCoordValid(coord.uv[1])) {
|
||||
vertexUvs.push_back(coord);
|
||||
continue;
|
||||
}
|
||||
vertexUvs.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Modified from the libigl example code
|
||||
// https://github.com/libigl/libigl/blob/master/tutorial/503_ARAPParam/main.cpp
|
||||
bool parametrize(const std::vector<Vertex> &verticies,
|
||||
const std::vector<Face> &faces,
|
||||
std::vector<TextureCoord> &vertexUvs)
|
||||
{
|
||||
if (verticies.empty() || faces.empty())
|
||||
return false;
|
||||
|
||||
Eigen::MatrixXd V(verticies.size(), 3);
|
||||
Eigen::MatrixXi F(faces.size(), 3);
|
||||
|
||||
for (decltype(verticies.size()) i = 0; i < verticies.size(); i++) {
|
||||
const auto &vertex = verticies[i];
|
||||
V.row(i) << vertex.xyz[0], vertex.xyz[1], vertex.xyz[2];
|
||||
}
|
||||
|
||||
for (decltype(faces.size()) i = 0; i < faces.size(); i++) {
|
||||
const auto &face = faces[i];
|
||||
F.row(i) << face.indices[0], face.indices[1], face.indices[2];
|
||||
}
|
||||
|
||||
Eigen::VectorXi bnd;
|
||||
igl::boundary_loop(F,bnd);
|
||||
|
||||
{
|
||||
Eigen::MatrixXd V_uv;
|
||||
parametrizeUsingARAP(V, F, bnd, V_uv);
|
||||
if (extractResult(verticies, V_uv, vertexUvs))
|
||||
return true;
|
||||
}
|
||||
|
||||
{
|
||||
Eigen::MatrixXd V_uv;
|
||||
parametrizeUsingLSCM(V, F, bnd, V_uv);
|
||||
if (extractResult(verticies, V_uv, vertexUvs))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue