dust3d/third_party/libigl/include/igl/faces_first.cpp

104 lines
2.4 KiB
C++

// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 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 "faces_first.h"
#include <vector>
#include <Eigen/Dense>
template <typename MatV, typename MatF, typename VecI>
IGL_INLINE void igl::faces_first(
const MatV & V,
const MatF & F,
MatV & RV,
MatF & RF,
VecI & IM)
{
assert(&V != &RV);
assert(&F != &RF);
using namespace std;
using namespace Eigen;
vector<bool> in_face(V.rows());
for(int i = 0; i<F.rows(); i++)
{
for(int j = 0; j<F.cols(); j++)
{
in_face[F(i,j)] = true;
}
}
// count number of vertices not in faces
int num_in_F = 0;
for(int i = 0;i<V.rows();i++)
{
num_in_F += (in_face[i]?1:0);
}
// list of unique vertices that occur in F
VectorXi U(num_in_F);
// list of unique vertices that do not occur in F
VectorXi NU(V.rows()-num_in_F);
int Ui = 0;
int NUi = 0;
// loop over vertices
for(int i = 0;i<V.rows();i++)
{
if(in_face[i])
{
U(Ui) = i;
Ui++;
}else
{
NU(NUi) = i;
NUi++;
}
}
IM.resize(V.rows());
// reindex vertices that occur in faces to be first
for(int i = 0;i<U.size();i++)
{
IM(U(i)) = i;
}
// reindex vertices that do not occur in faces to come after those that do
for(int i = 0;i<NU.size();i++)
{
IM(NU(i)) = i+U.size();
}
RF.resizeLike(F);
// Reindex faces
for(int i = 0; i<F.rows(); i++)
{
for(int j = 0; j<F.cols(); j++)
{
RF(i,j) = IM(F(i,j));
}
}
RV.resizeLike(V);
// Reorder vertices
for(int i = 0;i<V.rows();i++)
{
RV.row(IM(i)) = V.row(i);
}
}
template <typename MatV, typename MatF, typename VecI>
IGL_INLINE void igl::faces_first(
MatV & V,
MatF & F,
VecI & IM)
{
MatV RV;
// Copying F may not be needed, seems RF = F is safe (whereas RV = V is not)
MatF RF;
igl::faces_first(V,F,RV,RF,IM);
V = RV;
F = RF;
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template void igl::faces_first<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::Matrix<double, -1, -1, 0, -1, -1>&, Eigen::Matrix<int, -1, -1, 0, -1, -1>&, Eigen::Matrix<int, -1, 1, 0, -1, 1>&);
#endif