From 60cc24370eb32d97e492622801f52cb72247cfb1 Mon Sep 17 00:00:00 2001 From: Luigi Malomo Date: Tue, 7 Mar 2017 14:48:18 +0100 Subject: [PATCH] added wrapping function for libigl arap parametrization --- wrap/igl/arap_parametrization.h | 207 ++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 wrap/igl/arap_parametrization.h diff --git a/wrap/igl/arap_parametrization.h b/wrap/igl/arap_parametrization.h new file mode 100644 index 00000000..a88ca056 --- /dev/null +++ b/wrap/igl/arap_parametrization.h @@ -0,0 +1,207 @@ +/**************************************************************************** +* VCGLib o o * +* Visual and Computer Graphics Library o o * +* _ O _ * +* Copyright(C) 2017 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ + +/* Optimizes given UV-mapping with + * [ARAP parametrization] + * (minimizes area and angle distortions). + * + * Needs: + * (-) per-vertex texture coords + * (-) per-vertex flags to fix boundaries + * Fixed vertices are the flagged ones. + * By default: BORDER or SELECTED verts are fixed. + * (use fixedMask parameter to customize) + * + * Example of usage: + * MyMesh m; + * ... + * vcg::tri::UpdateFlags::Clear(m); + * vcg::tri::UpdateFlags::VertexBorderFromNone(m); + * vcg::tri::OptimizeUV_ARAP(m); + * + */ + +#ifndef __VCG_IGL_ARAP_PARAMETRIZATION +#define __VCG_IGL_ARAP_PARAMETRIZATION + +#include + +#include +#include +#include +#include +#include + +namespace vcg { +namespace tri { + +template +void OptimizeUV_ARAP( + MeshType& m, + unsigned int iterations = 100, + unsigned int fixedMask = MeshType::VertexType::BORDER | MeshType::VertexType::SELECTED, + bool generateInitialGuess = true) +{ + + // check requirements + vcg::tri::RequirePerVertexTexCoord(m); + vcg::tri::RequirePerVertexFlags (m); + vcg::tri::RequireCompactness (m); + + if (m.vert.size() <= 1 || m.face.size() == 0) + { + return; + } + + // build fixed points data + int nFixed = 0; + if (fixedMask != 0) + { + for (size_t i=0; i::GetTriMeshData(m, F, V); + vcg::tri::MeshToMatrix::GetUVData(m, V_uv); + + b.resize(nFixed); + bc.resize(nFixed,2); + for (size_t i=0,k=0; i<(int)m.vert.size(); i++) + { + if (m.vert[i].Flags() & fixedMask) + { + b(k) = i; + bc(k,0) = m.vert[i].T().P()[0]; + bc(k,1) = m.vert[i].T().P()[1]; + k++; + } + } + + // Add dynamic regularization to avoid to specify boundary conditions + ::igl::ARAPData arap_data; + arap_data.with_dynamics = true; + arap_data.max_iter = iterations; + + // compute ARAP parametrization + ::igl::arap_precomputation(V, F, 2, b, arap_data); + ::igl::arap_solve(bc, arap_data, V_uv); + + // copy results back to mesh + for (size_t i=0; i +void InitializeArapWithLSCM(MeshType & m, unsigned int fixedMask = 0) +{ + typedef typename MeshType::ScalarType ScalarType; + typedef typename MeshType::CoordType CoordType; + typedef typename MeshType::VertexType::TexCoordType::PointType TexPointType; + typedef typename TexPointType::ScalarType TexScalarType; + + if (fixedMask == 0) + { + // manually select fixed vertices + vcg::tri::UpdateFlags::Clear(m); + + int fixed0, fixed1 = -1; + ScalarType minD0 = std::numeric_limits::max(); + ScalarType minD1 = std::numeric_limits::max(); + for (size_t i=0; i= 0); + assert(fixed1 >= 0); + assert(fixed0 != fixed1); + + //then select them + m.vert[fixed0].SetS(); + m.vert[fixed1].SetS(); + m.vert[fixed0].T().P() = TexPointType(0,0); + m.vert[fixed1].T().P() = TexPointType(1,1); + + fixedMask = MeshType::VertexType::SELECTED; + } + + vcg::tri::OptimizeUV_LSCM(m, fixedMask); + + // Rescale the parametrization to match the 3D area + ScalarType meshArea2D = 0; + ScalarType meshArea3D = 0; + + for (size_t i=0; i t2(m.face[i].V(0)->T().P(), + m.face[i].V(1)->T().P(), + m.face[i].V(2)->T().P()); + meshArea2D += ScalarType(fabs(((t2.P(1) - t2.P(0)) ^ (t2.P(2) - t2.P(0)))/2)); + meshArea3D += vcg::DoubleArea(m.face[i])/2; + } + + ScalarType scaleFact = std::sqrt(meshArea3D / meshArea2D); + + for (size_t i=0; i