104 lines
2.4 KiB
C++
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
|