diff --git a/.gitattributes b/.gitattributes
index 8ad42df4aa4..215f40ec3b2 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -74,7 +74,6 @@ Scripts/scripts/cgal_create_assertions.sh text eol=lf
*.bat text eol=crlf
*.nsh text eol=crlf
*.vcproj text eol=crlf
-/Maintenance/infrastructure/picasso.geometryfactory.com/reference_platforms/*/CMakeCache.txt eol=crlf
# Denote all files that are truly binary and should not be modified.
*.png binary
diff --git a/Documentation/doc/Documentation/dependencies b/Documentation/doc/Documentation/dependencies
index 86d7b5629cb..c766a2e9b62 100644
--- a/Documentation/doc/Documentation/dependencies
+++ b/Documentation/doc/Documentation/dependencies
@@ -80,3 +80,5 @@ Surface_mesh_segmentation
Stream_lines_2
Stream_support
Surface_modeling
+Hole_filling
+
diff --git a/Documentation/doc/Documentation/packages.txt b/Documentation/doc/Documentation/packages.txt
index 7f341930c29..0df70ec9549 100644
--- a/Documentation/doc/Documentation/packages.txt
+++ b/Documentation/doc/Documentation/packages.txt
@@ -103,6 +103,7 @@ h1 {
\package_listing{Jet_fitting_3}
\package_listing{Point_set_processing_3}
\package_listing{Surface_modeling}
+\package_listing{Hole_filling}
\section PartSearchStructures Spatial Searching and Sorting
diff --git a/Hole_filling/doc/Hole_filling/Concepts/HoleFillingWeightCalculator.h b/Hole_filling/doc/Hole_filling/Concepts/HoleFillingWeightCalculator.h
new file mode 100644
index 00000000000..a39775232e6
--- /dev/null
+++ b/Hole_filling/doc/Hole_filling/Concepts/HoleFillingWeightCalculator.h
@@ -0,0 +1,26 @@
+ /// \ingroup PkgHoleFillingConcepts
+ /// \cgalConcept
+ ///
+ /// @brief Concept describing requirements for calculating weights for edges and vertices.
+
+class FairWeightCalculator
+{
+public:
+/// \name Types
+/// @{
+ /// a model of Polyhedron
+ typedef Hidden_type Polyhedron;
+/// @}
+
+
+/// \name Operations
+/// @{
+ /// Function computing the edge weight of edge `e`
+ double w_ij(Polyhedron::Halfedge_handle e, const Polyhedron& polyhedron);
+
+ /// Function computing the vertex weight of vertex `v`
+ double w_i(Polyhedron::Vertex_handle v, const Polyhedron& polyhedron);
+/// @}
+};
+
+
diff --git a/Hole_filling/doc/Hole_filling/Doxyfile.in b/Hole_filling/doc/Hole_filling/Doxyfile.in
new file mode 100644
index 00000000000..d92d78028b1
--- /dev/null
+++ b/Hole_filling/doc/Hole_filling/Doxyfile.in
@@ -0,0 +1,10 @@
+@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
+
+PROJECT_NAME = "CGAL ${CGAL_CREATED_VERSION_NUM} - Hole Filling"
+INPUT = ${CMAKE_SOURCE_DIR}/Hole_filling/doc/Hole_filling/ \
+ ${CMAKE_SOURCE_DIR}/Hole_filling/include
+
+# custom options for this package
+EXTRACT_ALL = false
+HIDE_UNDOC_CLASSES = true
+WARN_IF_UNDOCUMENTED = false
\ No newline at end of file
diff --git a/Hole_filling/doc/Hole_filling/Hole_filling.txt b/Hole_filling/doc/Hole_filling/Hole_filling.txt
new file mode 100644
index 00000000000..fe74976f5b4
--- /dev/null
+++ b/Hole_filling/doc/Hole_filling/Hole_filling.txt
@@ -0,0 +1,78 @@
+namespace CGAL {
+/*!
+\mainpage Hole Filling
+\anchor Chapter_HoleFilling
+
+\cgalAutoToc
+\author ... Ilker %O. Yaz ...
+
+\image html neptun_head.png
+\image latex neptun_head.png
+
+
+\section HoleFillingIntroduction Introduction
+
+This package provides algorithms for filling a hole that is either in a triangulated surface mesh (mesh in the following) or defined by a sequence of points.
+The main steps of the algorithm are described in \cgalCite{Lipea2003FillingHoles} and can be summarized as follows.
+
+First, a triangular patch for the hole is generated without introducing any new vertex.
+The patch minimizes a quality function for all possible triangular patches.
+The quality function first minimizes the worst dihedral angle between patch triangles, then the total surface area as a tiebreaker.
+Following the suggestions in \cgalCite{Zou2013AnAlgorithm}, the performance of the algorithm is significantly improved
+by narrowing the search space to faces of a 3D Delaunay triangulation of the border vertices, from all possible patches, while searching for the best patch.
+
+Then, the generated patch is refined by creating new vertices to approximate the density of near boundary triangles and flipping edges to obtain a Delaunay-like triangulation.
+Using a criteria presented in \cgalCite{Lipea2003FillingHoles},
+an edge is only flipped if the opposite edge does not exist in the mesh and if no degenerate triangle is produced.
+
+Finally, the refined region is faired to obtain a tangential continuous and smooth patch.
+The fairing step minimizes a linear bi-Laplacian system with boundary constraints \cgalCite{Botsch2008OnLinearVariational}.
+The visual results of aforementioned steps can be seen in \cgalFigureRef{Mech_steps}
+
+\cgalFigureBegin{Mech_steps, mech_hole_horz.png}
+Results of the main steps of the algorithm. Respectively: the hole, after triangulation, after triangulation and refinement, after triangulation, refinement and fairing.
+\cgalFigureEnd
+
+\section HoleFillingAPI API
+
+This package provides four functions for hole filling:
+ - `triangulate_hole_polyline()` : given a sequence of points defining the hole, triangulates the hole.
+ - `triangulate_hole()` : given a border halfedge defining the hole on a mesh, triangulates the hole.
+ - `triangulate_and_refine_hole()` : in addition to `triangulate_hole()` the generated patch is also refined.
+ - `triangulate_refine_and_fair_hole()` : in addition to `triangulate_and_refine_hole()` the generated patch is also faired.
+
+
+Note that refinement and fairing functions can be applied to an arbitrary region on a mesh:
+ - `refine()` : given a set of facets on a mesh, refines the region.
+ - `fair()` : given a set of vertices on a mesh, fairs the region.
+
+
+\section Examples Examples
+
+\subsection Example_1 Example: Triangulating a Polyline
+\cgalExample{Hole_filling/triangulate_polyline_example.cpp}
+
+
+
+\subsection Example_2 Example: Refining a Region on a Mesh
+
+\cgalExample{Hole_filling/refine_polyhedron_example.cpp}
+
+\cgalFigureBegin{Max_refine, max_refine.png}
+Result of refine example.
+\cgalFigureEnd
+
+\subsection Example_3 Example: Fairing a Region on a Mesh
+\cgalExample{Hole_filling/fair_polyhedron_example.cpp}
+
+\cgalFigureBegin{Max_fair, max_fair.png}
+Result of fairing example.
+\cgalFigureEnd
+
+*/
+ \cgalFigureBegin{Triangulated_fork, fork.gif}
+ Holes in fork model are filled with only triangulating.
+ \cgalFigureEnd
+/*!
+*/
+} /* namespace CGAL */
diff --git a/Hole_filling/doc/Hole_filling/PackageDescription.txt b/Hole_filling/doc/Hole_filling/PackageDescription.txt
new file mode 100644
index 00000000000..e4a97cee8ad
--- /dev/null
+++ b/Hole_filling/doc/Hole_filling/PackageDescription.txt
@@ -0,0 +1,27 @@
+/// \defgroup PkgHoleFilling Hole Filling Reference
+/// \defgroup PkgHoleFillingConcepts Concepts
+/// \ingroup PkgHoleFilling
+
+/*!
+\addtogroup PkgHoleFilling
+
+\cgalPkgDescriptionBegin{Hole Filling, PkgHoleFillingSummary}
+\cgalPkgPicture{hole_filling_ico.png}
+
+\cgalPkgSummaryBegin
+\cgalPkgAuthor{Ilker O. Yaz}
+\cgalPkgDesc{This package provides functionality to fill holes, refine and fair triangulated regions on surface mesh.}
+\cgalPkgManuals{Chapter_HoleFilling,PkgHoleFilling}
+\cgalPkgSummaryEnd
+
+\cgalPkgShortInfoBegin
+\cgalPkgSince{4.3}
+\cgalPkgDependsOn{\ref PkgTriangulation3Summary, Sparse square solver such as those from \ref thirdpartyEigen}
+\cgalPkgBib{cgal-tmp}
+\cgalPkgLicense{\ref licensesGPL "GPL"}
+\cgalPkgDemo{Operations on Polyhedra,polyhedron_3.zip}
+\cgalPkgShortInfoEnd
+
+\cgalPkgDescriptionEnd
+
+*/
\ No newline at end of file
diff --git a/Hole_filling/doc/Hole_filling/dependencies b/Hole_filling/doc/Hole_filling/dependencies
new file mode 100644
index 00000000000..a01021f28b7
--- /dev/null
+++ b/Hole_filling/doc/Hole_filling/dependencies
@@ -0,0 +1,7 @@
+Manual
+Kernel_23
+STL_Extension
+Algebraic_foundations
+Circulator
+Stream_support
+Polyhedron
diff --git a/Hole_filling/doc/Hole_filling/fig/hole_filling_ico.png b/Hole_filling/doc/Hole_filling/fig/hole_filling_ico.png
new file mode 100644
index 00000000000..bbd0fe5ac77
Binary files /dev/null and b/Hole_filling/doc/Hole_filling/fig/hole_filling_ico.png differ
diff --git a/Hole_filling/examples/Hole_filling/example_1.cpp b/Hole_filling/examples/Hole_filling/example_1.cpp
new file mode 100644
index 00000000000..cd73c7b9274
--- /dev/null
+++ b/Hole_filling/examples/Hole_filling/example_1.cpp
@@ -0,0 +1,173 @@
+#define CGAL_SUPERLU_ENABLED
+#undef NDEBUG
+#define DEBUG_TRACE
+#include
+
+#include
+#include
+#include
+
+#include
+
+typedef CGAL::Simple_cartesian Kernel;
+typedef CGAL::Polyhedron_3 Polyhedron;
+typedef Polyhedron::Facet_handle Facet_handle;
+typedef Polyhedron::Traits::Point_3 Point_3;
+
+//
+//void test_triangulate_polyline(Polyhedron& poly) {
+// typedef std::vector< std::vector > > Triangles_list;
+// Triangles_list tris;
+// // construct polyline from border
+// std::vector polyline;
+// for(Polyhedron::Halfedge_iterator it = poly.halfedges_begin(); it != poly.halfedges_end(); ++it){
+// if(!it->is_border()) { continue; }
+// Polyhedron::Halfedge_around_facet_circulator hf_around_facet = it->facet_begin();
+// do {
+// polyline.push_back(hf_around_facet->vertex()->point());
+// } while(++hf_around_facet != it->facet_begin());
+// }
+// std::cout << "tri begin" << std::endl;
+// for(int i = 0; i < 100; ++i) {
+// tris.push_back(std::vector >());
+// //CGAL::triangulate_hole_polyline(polyline.begin(), polyline.end(),std::back_inserter(tris.back()));
+// }
+// std::cout << "tri end" << std::endl;
+// bool is_all_equal = true;
+// for(std::size_t i = 0; i + 1 < tris.size() && is_all_equal; ++i)
+// {
+// for(std::size_t j = 0; j < tris[0].size(); ++j) {
+// if(tris[i][j].get<0>() != tris[i+1][j].get<0>()
+// || tris[i][j].get<1>() != tris[i+1][j].get<1>()
+// || tris[i][j].get<2>() != tris[i+1][j].get<2>())
+// {
+// is_all_equal = false;
+// std::cout << "---------not equal points---------" << std::endl;
+// std::cout << tris[i][j].get<0>() << tris[i][j].get<1>() << tris[i][j].get<2>() << std::endl;
+// std::cout << tris[i][j+1].get<0>() << tris[i][j+1].get<1>() << tris[i][j+1].get<2>() << std::endl;
+// std::cout << "----------------------------------" << std::endl;
+// }
+// }
+// }
+//
+// if(!is_all_equal) {
+// std::cout << "Error: test_triangulate results are different!" << std::endl;
+// }
+// else {
+// std::cout << "OK: test_triangulate results are the same" << std::endl;
+// }
+//}
+//
+//void test_triangulate(Polyhedron& poly) {
+// typedef std::vector< std::vector > Triangles_list; // 3 point for each tri
+// Triangles_list tris; //hold results
+//
+// for(int i = 0; i < 100; ++i) {
+// Polyhedron tmp = poly;
+// for(Polyhedron::Halfedge_iterator it = tmp.halfedges_begin(); it != tmp.halfedges_end(); ++it){
+// if(it->is_border()) {
+// std::vector facets;
+// CGAL::triangulate_hole(tmp, it, std::back_inserter(facets));
+// tris.push_back(std::vector());
+// for(std::vector::iterator it = facets.begin(); it != facets.end(); ++it) {
+// Polyhedron::Halfedge_around_facet_circulator b = (*it)->facet_begin(), e(b);
+// do{
+// tris.back().push_back(b->vertex()->point());
+// }while(++b != e);
+// }
+// break;
+// }
+// }
+// }
+//
+// bool is_all_equal = true;
+// for(std::size_t i = 0; i + 1 < tris.size() && is_all_equal; ++i)
+// {
+// for(std::size_t j = 0; j < tris[0].size(); ++j) {
+// if(tris[i][j] != tris[i+1][j]) {
+// is_all_equal = false;
+// std::cout << "---------not equal points---------" << std::endl;
+// std::cout << tris[i][j] << std::endl;
+// std::cout << tris[i+1][j] << std::endl;
+// std::cout << "----------------------------------" << std::endl;
+// }
+// }
+// }
+//
+// if(!is_all_equal) {
+// std::cout << "Error: test_triangulate results are different!" << std::endl;
+// }
+// else {
+// std::cout << "OK: test_triangulate results are the same" << std::endl;
+// }
+//}
+
+//void test_triangulate_fair(Polyhedron& poly) {
+// typedef std::vector< std::vector > Triangles_list;
+// Triangles_list tris; //hold results
+//
+// for(int i = 0; i < 100; ++i) {
+// Polyhedron tmp = poly;
+// for(Polyhedron::Halfedge_iterator it = tmp.halfedges_begin(); it != tmp.halfedges_end(); ++it){
+// if(it->is_border()) {
+// std::vector facets;
+// CGAL::triangulate_and_refine_hole(tmp, it, std::back_inserter(facets));
+// tris.push_back(std::vector());
+// for(std::vector::iterator it = facets.begin(); it != facets.end(); ++it) {
+// Polyhedron::Halfedge_around_facet_circulator b = (*it)->facet_begin(), e(b);
+// do{
+// tris.back().push_back(b->vertex()->point());
+// }while(++b != e);
+// }
+// break;
+// }
+// }
+// }
+//
+// bool is_all_equal = true;
+// for(std::size_t i = 0; i + 1 < tris.size() && is_all_equal; ++i)
+// {
+// if(tris[i] != tris[i+1]) { is_all_equal = false; }
+// }
+//
+// if(!is_all_equal) {
+// std::cout << "Error: test_triangulate_fair results are different!" << std::endl;
+// }
+// else {
+// std::cout << "OK: test_triangulate_fair results are the same" << std::endl;
+// }
+//}
+
+#include
+struct Nop_functor {
+ template
+ void operator()(const T& /* t */) const {}
+};
+typedef boost::function_output_iterator Nop_out;
+
+
+int main() {
+ Polyhedron poly;
+ std::ifstream input("data/mech-holes-shark-bug.off");
+ if ( !input || !(input >> poly) || poly.empty() ) {
+ std::cerr<< "Cannot open file" << std::endl;
+ return 1;
+ }
+
+ for(Polyhedron::Halfedge_iterator it = poly.halfedges_begin(); it != poly.halfedges_end(); ++it){
+ if(it->is_border()) {
+ //CGAL::triangulate_and_refine_hole(poly, it, Nop_out(), Nop_out(), 14.21);
+ CGAL::triangulate_refine_and_fair_hole(poly, it, Nop_out(), Nop_out(), 10.0);
+ break;
+ }
+ }
+
+ //test_triangulate(poly);
+ //test_triangulate_polyline(poly);
+ std::ofstream out("data/out.off");
+ out << poly;
+ out.close();
+ std::cout << "Done!" << std::endl;
+ std::cin.get();
+}
+
diff --git a/Hole_filling/examples/Hole_filling/fair_polyhedron_example.cpp b/Hole_filling/examples/Hole_filling/fair_polyhedron_example.cpp
new file mode 100644
index 00000000000..aa5a936851a
--- /dev/null
+++ b/Hole_filling/examples/Hole_filling/fair_polyhedron_example.cpp
@@ -0,0 +1,56 @@
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
+typedef CGAL::Polyhedron_3 Polyhedron;
+typedef Polyhedron::Vertex_handle Vertex_handle;
+typedef Polyhedron::Vertex_iterator Vertex_iterator;
+typedef Polyhedron::Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator;
+
+// extract vertices which are at most k (inclusive) far from vertex v
+std::vector extract_k_ring(Vertex_handle v, int k)
+{
+ std::map D;
+ std::vector Q;
+ Q.push_back(v); D[v] = 0;
+ std::size_t current_index = 0;
+
+ int dist_v;
+ while( current_index < Q.size() && (dist_v = D[ Q[current_index] ]) < k ) {
+ v = Q[current_index++];
+
+ Halfedge_around_vertex_circulator e(v->vertex_begin()), e_end(e);
+ do {
+ Vertex_handle new_v = e->opposite()->vertex();
+ if(D.insert(std::make_pair(new_v, dist_v + 1)).second) {
+ Q.push_back(new_v);
+ }
+ } while(++e != e_end);
+ }
+ return Q;
+}
+
+int main() {
+ Polyhedron poly;
+ std::ifstream input("data/max.off");
+ if ( !input || !(input >> poly) || poly.empty() ) {
+ std::cerr << "Not a valid off file." << std::endl;
+ return 1;
+ }
+
+ Vertex_iterator v = poly.vertices_begin();
+ std::advance(v, 8286);
+ const std::vector& region = extract_k_ring(v, 45);
+
+ bool success = CGAL::fair(poly, region.begin(), region.end());
+ std::cout << "Is fairing successful: " << success << std::endl;
+
+ std::ofstream faired_off("data/faired.off");
+ faired_off << poly;
+ faired_off.close();
+}
diff --git a/Hole_filling/examples/Hole_filling/fill_polyhedron_example.cpp b/Hole_filling/examples/Hole_filling/fill_polyhedron_example.cpp
new file mode 100644
index 00000000000..fc6888ec111
--- /dev/null
+++ b/Hole_filling/examples/Hole_filling/fill_polyhedron_example.cpp
@@ -0,0 +1,69 @@
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+
+struct Nop_functor
+{
+ template
+ void operator()(const T & /*t*/) const {}
+};
+typedef boost::function_output_iterator Nop_out;
+
+typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
+typedef CGAL::Polyhedron_3 Polyhedron;
+typedef Polyhedron::Halfedge_iterator Halfedge_iterator;
+typedef Polyhedron::Facet_handle Facet_handle;
+typedef Polyhedron::Vertex_handle Vertex_handle;
+
+int main() {
+ Polyhedron poly_1;
+ std::ifstream input("data/max.off");
+ if ( !input || !(input >> poly_1) || poly_1.empty() ) {
+ std::cerr << "Not a valid off file." << std::endl;
+ return 1;
+ }
+ Polyhedron poly_2(poly_1), poly_3(poly_1);
+
+ for(Halfedge_iterator h = poly_1.halfedges_begin(); h != poly_1.halfedges_end(); ++h) {
+ if(h->is_border()) {
+ std::vector patch;
+ CGAL::triangulate_hole(poly_1, h, back_inserter(patch));
+ std::cout << "Number of facets in constructed patch: " << patch.size() << std::endl;
+ }
+ }
+
+ for(Halfedge_iterator h = poly_2.halfedges_begin(); h != poly_2.halfedges_end(); ++h) {
+ if(h->is_border()) {
+ std::vector patch_facets;
+ std::vector patch_vertices;
+ CGAL::triangulate_and_refine_hole(poly_2,
+ h,
+ back_inserter(patch_facets),
+ back_inserter(patch_vertices));
+ std::cout << "Number of facets in constructed patch: " << patch_facets.size() << std::endl;
+ std::cout << "Number of vertices in constructed patch: " << patch_vertices.size() << std::endl;
+ }
+ }
+
+ for(Halfedge_iterator h = poly_3.halfedges_begin(); h != poly_3.halfedges_end(); ++h) {
+ if(h->is_border()) {
+ std::vector patch_facets;
+ std::vector patch_vertices;
+ bool success = CGAL::triangulate_refine_and_fair_hole(poly_3,
+ h,
+ back_inserter(patch_facets),
+ back_inserter(patch_vertices)).get<0>();
+
+ std::cout << "Number of facets in constructed patch: " << patch_facets.size() << std::endl;
+ std::cout << "Number of vertices in constructed patch: " << patch_vertices.size() << std::endl;
+ std::cout << "Is fairing successful: " << success << std::endl;
+ }
+ }
+}
diff --git a/Hole_filling/examples/Hole_filling/refine_polyhedron_example.cpp b/Hole_filling/examples/Hole_filling/refine_polyhedron_example.cpp
new file mode 100644
index 00000000000..c61accd9d87
--- /dev/null
+++ b/Hole_filling/examples/Hole_filling/refine_polyhedron_example.cpp
@@ -0,0 +1,57 @@
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+
+typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
+typedef CGAL::Polyhedron_3 Polyhedron;
+typedef Polyhedron::Facet_handle Facet_handle;
+typedef Polyhedron::Vertex_handle Vertex_handle;
+typedef Polyhedron::Facet Facet;
+
+struct Facet_to_facet_handle
+ : public std::unary_function
+{
+ result_type operator()(argument_type f) const
+ { return f.halfedge()->facet(); }
+};
+
+
+int main() {
+ Polyhedron poly_1;
+ std::ifstream input("data/max.off");
+ if ( !input || !(input >> poly_1) || poly_1.empty() ) {
+ std::cerr << "Not a valid off file." << std::endl;
+ return 1;
+ }
+ Polyhedron poly_2 = poly_1;
+
+ std::vector new_facets;
+ std::vector new_vertices;
+ // `facets_begin()` returns `Facet_iterator` which is an iterator over `Facet`,
+ // what `refine()` requires is an iterator over `Facet_handle`, hence a transformer is used
+ CGAL::refine(poly_1,
+ boost::make_transform_iterator(poly_1.facets_begin(), Facet_to_facet_handle()),
+ boost::make_transform_iterator(poly_1.facets_end() , Facet_to_facet_handle()),
+ back_inserter(new_facets), back_inserter(new_vertices), 2.0);
+
+ std::ofstream poly_1_off("data/poly_1.off");
+ poly_1_off << poly_1;
+ poly_1_off.close();
+
+ CGAL::refine(poly_2,
+ boost::make_transform_iterator(poly_2.facets_begin(), Facet_to_facet_handle()),
+ boost::make_transform_iterator(poly_2.facets_end() , Facet_to_facet_handle()),
+ CGAL::Emptyset_iterator(), CGAL::Emptyset_iterator(), 3.0);
+
+ std::ofstream poly_2_off("data/poly_2.off");
+ poly_2_off << poly_2;
+ poly_2_off.close();
+}
diff --git a/Hole_filling/examples/Hole_filling/triangulate_polyline_example.cpp b/Hole_filling/examples/Hole_filling/triangulate_polyline_example.cpp
new file mode 100644
index 00000000000..b2af0dacb05
--- /dev/null
+++ b/Hole_filling/examples/Hole_filling/triangulate_polyline_example.cpp
@@ -0,0 +1,54 @@
+#include
+#include
+
+#include
+#include
+#include
+
+typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
+typedef Kernel::Point_3 Point_3;
+
+struct My_triangle {
+ int v0, v1, v2;
+ My_triangle(int v0, int v1, int v2) : v0(v0), v1(v1), v2(v2) { }
+};
+
+int main() {
+ std::vector polyline;
+ polyline.push_back(Point_3( 1.,0.,0.));
+ polyline.push_back(Point_3( 0.,1.,0.));
+ polyline.push_back(Point_3(-1.,0.,0.));
+ polyline.push_back(Point_3( 1.,1.,0.));
+ // repeating first point (i.e. polyline.push_back(Point_3(1.,0.,0.)) ) is optional
+
+ // any type, having Type(int, int, int) constructor available, can be used to hold output triangles
+ std::vector > patch_1;
+ std::vector > patch_2;
+ std::vector patch_3;
+
+ patch_1.reserve(polyline.size() -2); // there will be exactly n-2 triangles in the patch
+ CGAL::triangulate_hole_polyline(polyline.begin(), polyline.end(), back_inserter(patch_1));
+ CGAL::triangulate_hole_polyline(polyline.begin(), polyline.end(), back_inserter(patch_2));
+ CGAL::triangulate_hole_polyline(polyline.begin(), polyline.end(), back_inserter(patch_3));
+
+ for(std::size_t i = 0; i < patch_1.size(); ++i) {
+ std::cout << "Triangle " << i << ": " << patch_1[i].get<0>() << " "
+ << patch_1[i].get<1>() << " " << patch_1[i].get<2>() << std::endl;
+
+ assert(patch_1[i].get<0>() == patch_2[i].first && patch_2[i].first == patch_3[i].v0);
+ assert(patch_1[i].get<1>() == patch_2[i].second && patch_2[i].second == patch_3[i].v1);
+ assert(patch_1[i].get<2>() == patch_2[i].third && patch_2[i].third == patch_3[i].v2);
+ }
+
+ // note that no degenerate triangle is constructed in patch
+ std::vector polyline_collinear;
+ polyline_collinear.push_back(Point_3(1.,0.,0.));
+ polyline_collinear.push_back(Point_3(2.,0.,0.));
+ polyline_collinear.push_back(Point_3(3.,0.,0.));
+ polyline_collinear.push_back(Point_3(4.,0.,0.));
+ std::vector patch_will_be_empty;
+ CGAL::triangulate_hole_polyline(polyline_collinear.begin(),
+ polyline_collinear.end(),
+ back_inserter(patch_will_be_empty));
+ assert(patch_will_be_empty.empty());
+}
diff --git a/Hole_filling/include/CGAL/Hole_filling.h b/Hole_filling/include/CGAL/Hole_filling.h
new file mode 100644
index 00000000000..2db4357e6bb
--- /dev/null
+++ b/Hole_filling/include/CGAL/Hole_filling.h
@@ -0,0 +1,168 @@
+#ifndef CGAL_HOLE_FILLING_H
+#define CGAL_HOLE_FILLING_H
+
+// Helper functions which combine triangulate, fair, and refine
+
+#include
+#include
+#include
+#include
+#include
+
+namespace CGAL {
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/*!
+\ingroup PkgHoleFilling
+@brief Function triangulating and refining a hole in a surface mesh.
+
+@tparam Polyhedron a \cgal polyhedron
+@tparam FacetOutputIterator iterator holding `Polyhedron::Facet_handle` for patch facets.
+@tparam VertexOutputIterator iterator holding `Polyhedron::Vertex_handle` for patch vertices.
+
+@param polyhedron surface mesh which has the hole
+@param border_halfedge a border halfedge incident to the hole
+@param facet_out iterator over patch facets
+@param vertex_out iterator over patch vertices without including the boundary
+@param density_control_factor factor for density where larger values cause denser refinements
+
+@return pair of @a facet_out and @a vertex_out
+*/
+template<
+ class Polyhedron,
+ class FacetOutputIterator,
+ class VertexOutputIterator
+>
+std::pair
+triangulate_and_refine_hole(Polyhedron& polyhedron,
+ typename Polyhedron::Halfedge_handle border_halfedge,
+ FacetOutputIterator facet_out,
+ VertexOutputIterator vertex_out,
+ double density_control_factor = std::sqrt(2.0),
+ bool use_delaunay_triangulation = false)
+{
+ std::vector patch;
+ triangulate_hole(polyhedron, border_halfedge, std::back_inserter(patch), use_delaunay_triangulation);
+ facet_out = std::copy(patch.begin(), patch.end(), facet_out);
+ return refine(polyhedron, patch.begin(), patch.end(), facet_out, vertex_out, density_control_factor);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/*!
+\ingroup PkgHoleFilling
+@brief Function triangulating, refining and fairing a hole in surface mesh.
+
+@tparam SparseLinearSolver a model of `SparseLinearAlgebraTraitsWithPreFactor_d` and can be omitted if Eigen is defined...(give exact models etc)
+@tparam WeightCalculator a model of `FairWeightCalculator` and can be omitted to use default Cotangent weights
+@tparam Polyhedron a \cgal polyhedron
+@tparam FacetOutputIterator iterator holding `Polyhedron::Facet_handle` for patch facets.
+@tparam VertexOutputIterator iterator holding `Polyhedron::Vertex_handle` for patch vertices.
+
+@param polyhedron surface mesh which has the hole
+@param border_halfedge a border halfedge incident to the hole
+@param facet_out iterator over patch facets
+@param vertex_out iterator over patch vertices without including the boundary
+@param weight_calculator function object to calculate weights, default to Cotangent weights and can be omitted
+@param density_control_factor factor for density where larger values cause denser refinements
+@param continuity tangential continuity, default to `FAIRING_C_1` and can be omitted
+@return tuple of
+ - bool: `true` if fairing is successful
+ - @a facet_out
+ - @a vertex_out
+ */
+template<
+ class SparseLinearSolver,
+ class WeightCalculator,
+ class Polyhedron,
+ class FacetOutputIterator,
+ class VertexOutputIterator
+>
+boost::tuple
+triangulate_refine_and_fair_hole(Polyhedron& polyhedron,
+ typename Polyhedron::Halfedge_handle border_halfedge,
+ FacetOutputIterator facet_out,
+ VertexOutputIterator vertex_out,
+ WeightCalculator weight_calculator,
+ double density_control_factor = std::sqrt(2.0),
+ bool use_delaunay_triangulation = false,
+ Fairing_continuity continuity = FAIRING_C_1)
+{
+ std::vector patch;
+
+ facet_out = triangulate_and_refine_hole
+ (polyhedron, border_halfedge, facet_out, std::back_inserter(patch), density_control_factor, use_delaunay_triangulation)
+ .first;
+
+ bool fair_success = fair(polyhedron, patch.begin(), patch.end(), weight_calculator, continuity);
+
+ vertex_out = std::copy(patch.begin(), patch.end(), vertex_out);
+ return boost::make_tuple(fair_success, facet_out, vertex_out);
+}
+
+//use default SparseLinearSolver
+template<
+ class WeightCalculator,
+ class Polyhedron,
+ class FacetOutputIterator,
+ class VertexOutputIterator
+>
+boost::tuple
+triangulate_refine_and_fair_hole(Polyhedron& polyhedron,
+ typename Polyhedron::Halfedge_handle border_halfedge,
+ FacetOutputIterator facet_out,
+ VertexOutputIterator vertex_out,
+ WeightCalculator weight_calculator,
+ double density_control_factor = std::sqrt(2.0),
+ bool use_delaunay_triangulation = false,
+ Fairing_continuity continuity = FAIRING_C_1)
+{
+ typedef CGAL::internal::Fair_default_sparse_linear_solver::Solver Sparse_linear_solver;
+ return triangulate_refine_and_fair_hole
+ (polyhedron, border_halfedge, facet_out, vertex_out, weight_calculator, density_control_factor, use_delaunay_triangulation, continuity);
+}
+
+//use default WeightCalculator
+template<
+ class SparseLinearSolver,
+ class Polyhedron,
+ class FacetOutputIterator,
+ class VertexOutputIterator
+>
+boost::tuple
+triangulate_refine_and_fair_hole(Polyhedron& polyhedron,
+ typename Polyhedron::Halfedge_handle border_halfedge,
+ FacetOutputIterator facet_out,
+ VertexOutputIterator vertex_out,
+ double density_control_factor = std::sqrt(2.0),
+ bool use_delaunay_triangulation = false,
+ Fairing_continuity continuity = FAIRING_C_1)
+{
+ typedef CGAL::internal::Cotangent_weight_with_voronoi_area_fairing Weight_calculator;
+ return triangulate_refine_and_fair_hole
+ (polyhedron, border_halfedge, facet_out, vertex_out, Weight_calculator(), density_control_factor, use_delaunay_triangulation, continuity);
+}
+
+//use default SparseLinearSolver and WeightCalculator
+template<
+ class Polyhedron,
+ class FacetOutputIterator,
+ class VertexOutputIterator
+>
+boost::tuple
+triangulate_refine_and_fair_hole(Polyhedron& polyhedron,
+ typename Polyhedron::Halfedge_handle border_halfedge,
+ FacetOutputIterator facet_out,
+ VertexOutputIterator vertex_out,
+ double density_control_factor = std::sqrt(2.0),
+ bool use_delaunay_triangulation = false,
+ Fairing_continuity continuity = FAIRING_C_1)
+{
+ typedef CGAL::internal::Fair_default_sparse_linear_solver::Solver Sparse_linear_solver;
+ return triangulate_refine_and_fair_hole
+ (polyhedron, border_halfedge, facet_out, vertex_out, density_control_factor, use_delaunay_triangulation, continuity);
+}
+
+} // namespace CGAL
+
+#endif
diff --git a/Hole_filling/include/CGAL/internal/Hole_filling/Fair_Polyhedron_3.h b/Hole_filling/include/CGAL/internal/Hole_filling/Fair_Polyhedron_3.h
new file mode 100644
index 00000000000..6e91bae9a16
--- /dev/null
+++ b/Hole_filling/include/CGAL/internal/Hole_filling/Fair_Polyhedron_3.h
@@ -0,0 +1,270 @@
+#ifndef CGAL_HOLE_FILLING_FAIR_POLYHEDRON_3_H
+#define CGAL_HOLE_FILLING_FAIR_POLYHEDRON_3_H
+
+#include