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

147 lines
5.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2018 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 "is_intrinsic_delaunay.h"
#include "unique_edge_map.h"
#include "tan_half_angle.h"
#include "EPS.h"
#include "cotmatrix_entries.h"
#include <iostream>
#include <cassert>
template <
typename Derivedl,
typename DerivedF,
typename DerivedD>
IGL_INLINE void igl::is_intrinsic_delaunay(
const Eigen::MatrixBase<Derivedl> & l,
const Eigen::MatrixBase<DerivedF> & F,
Eigen::PlainObjectBase<DerivedD> & D)
{
typedef Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,2> MatrixX2I;
typedef Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,1> VectorXI;
MatrixX2I E,uE;
VectorXI EMAP;
std::vector<std::vector<typename DerivedF::Scalar> > uE2E;
igl::unique_edge_map(F, E, uE, EMAP, uE2E);
return is_intrinsic_delaunay(l,F,uE2E,D);
}
template <
typename Derivedl,
typename DerivedF,
typename uE2EType,
typename DerivedD>
IGL_INLINE void igl::is_intrinsic_delaunay(
const Eigen::MatrixBase<Derivedl> & l,
const Eigen::MatrixBase<DerivedF> & F,
const std::vector<std::vector<uE2EType> > & uE2E,
Eigen::PlainObjectBase<DerivedD> & D)
{
const int num_faces = F.rows();
D.setConstant(F.rows(),F.cols(),false);
// loop over all unique edges
for(int ue = 0;ue < uE2E.size(); ue++)
{
const bool ue_is_d = is_intrinsic_delaunay(l,uE2E,num_faces,ue);
// Set for all instances
for(int e = 0;e<uE2E[ue].size();e++)
{
D( uE2E[ue][e]%num_faces, uE2E[ue][e]/num_faces) = ue_is_d;
}
}
};
template <
typename Derivedl,
typename uE2EType,
typename Index>
IGL_INLINE bool igl::is_intrinsic_delaunay(
const Eigen::MatrixBase<Derivedl> & l,
const std::vector<std::vector<uE2EType> > & uE2E,
const Index num_faces,
const Index uei)
{
if(uE2E[uei].size() == 1) return true;
if(uE2E[uei].size() > 2) return false;
typedef typename Derivedl::Scalar Scalar;
const auto cot_alpha = [](
const Scalar & a,
const Scalar & b,
const Scalar & c)->Scalar
{
// Fisher 2007
const Scalar t = tan_half_angle(a,b,c);
return (1.0-t*t)/(2*t);
};
// 2 //
// /|\ //
// a/ | \d //
// / e \ //
// / | \ //
//0.α---|-f-β.3 //
// \ | / //
// \ | / //
// b\ | /c //
// \|/ //
// . //
// 1
// Fisher 2007
assert(uE2E[uei].size() == 2 && "edge should have 2 incident faces");
const Index he1 = uE2E[uei][0];
const Index he2 = uE2E[uei][1];
const Index f1 = he1%num_faces;
const Index c1 = he1/num_faces;
const Index f2 = he2%num_faces;
const Index c2 = he2/num_faces;
assert( std::abs(l(f1,c1)-l(f2,c2)) < igl::EPS<Scalar>());
const Scalar e = l(f1,c1);
const Scalar a = l(f1,(c1+1)%3);
const Scalar b = l(f1,(c1+2)%3);
const Scalar c = l(f2,(c2+1)%3);
const Scalar d = l(f2,(c2+2)%3);
const Scalar w = cot_alpha(e,a,b) + cot_alpha(e,c,d);
//// Test
//{
// Eigen::MatrixXd l(2,3);
// l<<e,a,b,
// d,e,c;
// //Eigen::MatrixXi F(2,3);
// //F<<0,1,2,
// // 1,3,2;
// Eigen::MatrixXd C;
// cotmatrix_entries(l,C);
// if(std::abs(w-(2.0*(C(0,0)+C(1,1))))>1e-10)
// {
// std::cout<<matlab_format(l,"l")<<std::endl;
// std::cout<<w<<std::endl;
// std::cout<<(2.0*(C(0,0)+C(1,1)))<<std::endl;
// std::cout<<w-(2.0*(C(0,0)+C(1,1)))<<std::endl;
// std::cout<<std::endl;
// }
//}
return w >= 0;
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template bool igl::is_intrinsic_delaunay<Eigen::Matrix<double, -1, 3, 0, -1, 3>, int, int>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, int, int);
// generated by autoexplicit.sh
template bool igl::is_intrinsic_delaunay<Eigen::Matrix<double, -1, -1, 0, -1, -1>, int, int>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, int, int);
// generated by autoexplicit.sh
template void igl::is_intrinsic_delaunay<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, int, Eigen::Matrix<bool, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 3, 0, -1, 3> >&);
// generated by autoexplicit.sh
template void igl::is_intrinsic_delaunay<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<bool, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, -1, 0, -1, -1> >&);
// generated by autoexplicit.sh
template void igl::is_intrinsic_delaunay<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<bool, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 3, 0, -1, 3> >&);
#endif