You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

144 lines
5.0 KiB

#include "triangulate.h"
#include "assign_scalar.h"
#include "../../list_to_matrix.h"
#include <CGAL/Point_2.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <CGAL/Constrained_triangulation_plus_2.h>
#include <CGAL/Triangulation_face_base_with_info_2.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <queue>
template <
typename Kernel,
typename DerivedV,
typename DerivedE,
typename DerivedH,
typename DerivedV2,
typename DerivedF2>
IGL_INLINE void igl::copyleft::cgal::triangulate(
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedE> & E,
const Eigen::MatrixBase<DerivedH> & H,
const bool retain_convex_hull,
Eigen::PlainObjectBase<DerivedV2> & TV,
Eigen::PlainObjectBase<DerivedF2> & TF)
{
struct FaceInfo2
{
FaceInfo2(){}
bool visited = false;
bool in_domain = true;
};
typedef Eigen::Index Index;
//typedef CGAL::Epeck Kernel;
typedef CGAL::Point_2<Kernel> Point_2;
typedef CGAL::Triangulation_vertex_base_2<Kernel> TVB_2;
typedef CGAL::Triangulation_face_base_with_info_2<FaceInfo2,Kernel> TFB_2;
typedef CGAL::Constrained_triangulation_face_base_2<Kernel,TFB_2> CTFB_2;
typedef CGAL::Triangulation_data_structure_2<TVB_2,CTFB_2> TDS_2;
typedef CGAL::Exact_intersections_tag Itag;
typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel,TDS_2,Itag> CDT_2;
typedef CGAL::Constrained_triangulation_plus_2<CDT_2> CDT_plus_2;
typedef typename CDT_plus_2::Face_handle Face_handle;
CDT_plus_2 cdt;
// Insert all points
std::vector<Point_2> points;points.reserve(V.rows());
for(Eigen::Index i = 0;i<V.rows();i++)
{
Point_2 p(V(i,0),V(i,1));
cdt.insert(p);
points.emplace_back(p);
}
// Insert all edges
for(Eigen::Index e = 0;e<E.rows();e++)
{
cdt.insert_constraint(points[E(e,0)],points[E(e,1)]);
}
// https://doc.cgal.org/latest/Triangulation_2/index.html#title30
//
// "remove" connected component of face start by marking faces as
// in_domain = false. start should not yet be visited.
const auto remove_cc = [&](Face_handle start)
{
std::queue<Face_handle> queue;
queue.push(start);
while(!queue.empty())
{
Face_handle fh = queue.front();
queue.pop();
if(!fh->info().visited)
{
fh->info().visited = true;
fh->info().in_domain = false;
for(int i = 0; i < 3; i++)
{
typename CDT_plus_2::Edge e(fh,i);
Face_handle n = fh->neighbor(i);
if(!n->info().visited && !cdt.is_constrained(e))
{
queue.push(n);
}
}
}
}
};
// If _not_ meshsing convex hull, remove anything connected to infinite face
if(!retain_convex_hull)
{
remove_cc(cdt.infinite_face());
}
// remove holes
for(Eigen::Index h = 0;h<H.rows();h++)
{
remove_cc(cdt.locate({H(h,0),H(h,1)}));
}
std::vector<CGAL::Point_2<Kernel> > vertices;
std::vector<std::vector<Index> > faces;
// Read off vertices of the cdt, remembering index
std::map<typename CDT_plus_2::Vertex_handle,Index> v2i;
size_t count=0;
for (
auto itr = cdt.finite_vertices_begin();
itr != cdt.finite_vertices_end();
itr++)
{
vertices.push_back(itr->point());
v2i[itr] = count;
count++;
}
// Read off faces and store index triples
for (
auto itr = cdt.finite_faces_begin();
itr != cdt.finite_faces_end();
itr++)
{
if(itr->info().in_domain)
{
faces.push_back(
{ v2i[itr->vertex(0)], v2i[itr->vertex(1)], v2i[itr->vertex(2)] });
}
}
TV.resize(vertices.size(),2);
for(int v = 0;v<vertices.size();v++)
{
for(int d = 0;d<2;d++)
{
assign_scalar(vertices[v][d], TV(v,d));
}
}
list_to_matrix(faces,TF);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::copyleft::cgal::triangulate<CGAL::Epeck, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::triangulate<CGAL::Epick, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
#endif