diff --git a/Installation/changes.html b/Installation/changes.html
index 8b4c36cd3e2..976e4711c58 100644
--- a/Installation/changes.html
+++ b/Installation/changes.html
@@ -128,7 +128,6 @@ and src/ directories).
Release date: March 2017
@@ -143,7 +142,15 @@ and
src/ directories).
+
+
2D Triangulation data structure
+
+ -
+ Add function
insert_in_hole.
+
+
+
diff --git a/TDS_2/doc/TDS_2/Concepts/TriangulationDataStructure_2.h b/TDS_2/doc/TDS_2/Concepts/TriangulationDataStructure_2.h
index 6294a7ea62d..bc15b83770f 100644
--- a/TDS_2/doc/TDS_2/Concepts/TriangulationDataStructure_2.h
+++ b/TDS_2/doc/TDS_2/Concepts/TriangulationDataStructure_2.h
@@ -550,6 +550,32 @@ void dim_down(Face_handle f, int i);
/// @{
+/*!
+\cgalModifBegin
+creates a new vertex `v` and uses it to star a hole.
+
+Given a set of faces 'F' describing a simply connected hole (i.e., a topological disk),
+the function deletes all the faces in `F`, creates a new vertex `v` and for each edge on
+the boundary of the hole creates a new face with `v` as a vertex. The input is an iterator
+range `[face_begin, face_end[` of `Face_handle`s over the connected faces in `F`. The handle
+to the new vertex `v` is returned.
+
+\pre `tds.dimension() = 2` and the set of faces has the topology of a disk.
+\cgalModifEnd
+*/
+template< class FaceIt >
+Vertex_handle insert_in_hole(FaceIt face_begin, FaceIt face_end);
+
+/*!
+\cgalModifBegin
+same as above, except that `new_v` will be used as the new vertex, which must have been
+allocated previously with e.g. `create_vertex`.
+\cgalModifEnd
+*/
+template< class FaceIt >
+void insert_in_hole(Vertex_handle new_v, FaceIt face_begin, FaceIt face_end);
+
+
/*!
creates a new vertex `v` and use it to star the hole
whose boundary is described by the sequence of edges `[edge_begin, edge_end)`. Returns a handle to the vertex.
diff --git a/TDS_2/include/CGAL/Triangulation_data_structure_2.h b/TDS_2/include/CGAL/Triangulation_data_structure_2.h
index 5dd7bd4d665..02e3c6b9e1a 100644
--- a/TDS_2/include/CGAL/Triangulation_data_structure_2.h
+++ b/TDS_2/include/CGAL/Triangulation_data_structure_2.h
@@ -428,6 +428,106 @@ public:
// template members definition
public:
+
+ /************* START OF MODIFICATIONS ***************/
+
+ template< class FaceIt >
+ Vertex_handle insert_in_hole(FaceIt face_begin, FaceIt face_end)
+ {
+ Vertex_handle newv = create_vertex();
+ insert_in_hole(newv, face_begin, face_end);
+ return newv;
+ }
+
+
+ template< class FaceIt >
+ void insert_in_hole(Vertex_handle v, FaceIt face_begin, FaceIt face_end)
+ {
+
+ CGAL_triangulation_precondition(dimension() == 2);
+
+ std::vector
new_faces;
+ std::vector bdry_edges;
+
+ Face_handle fh = *face_begin;
+ int ii = 0;
+ bool found_boundary = false;
+ do {
+ if (std::find(face_begin, face_end, fh->neighbor(ii)) == face_end) {
+ bdry_edges.push_back(Edge(fh, ii));
+ found_boundary = true;
+ } else {
+ int newi = fh->neighbor(ii)->index(fh->vertex(ccw(ii)));
+ fh = fh->neighbor(ii);
+ ii = newi;
+ }
+ } while(!found_boundary);
+ // Now we have found ONE edge on the boundary.
+ // From that one edge we must walk on the boundary
+ // of the hole until we've covered the whole thing.
+
+ bool complete_walk = false;
+ do {
+ Face_handle nh = fh->neighbor(ccw(ii));
+ if (std::find(face_begin, face_end, nh) == face_end) {
+ ii = ccw(ii);
+ Edge new_edge(fh, ii);
+ if (std::find(bdry_edges.begin(), bdry_edges.end(), new_edge) == bdry_edges.end()) {
+ bdry_edges.push_back(Edge(fh, ii));
+ } else {
+ complete_walk = true;
+ }
+ } else {
+ int newi = cw(nh->index(fh->vertex(ii)));
+ fh = nh;
+ ii = newi;
+ }
+ } while (!complete_walk);
+ // At this point, bdry_edges contains the edges that define
+ // the boundary of the hole with a specific ordering: for any
+ // two consecutive edges in the vector e1 = (f1, i1),
+ // e2 = (f2, i2) it holds that
+ // f1->vertex(cw(i1)) == f2->vertex(ccw(i2))
+
+ for (unsigned int jj = 0; jj < bdry_edges.size(); jj++) {
+ Face_handle fh = bdry_edges[jj].first;
+ int idx = bdry_edges[jj].second;
+
+ Vertex_handle v1 = fh->vertex(ccw(idx));
+ Vertex_handle v2 = fh->vertex(cw(idx));
+
+ Face_handle nf = fh->neighbor(idx);
+ int jdx = mirror_index(fh, idx);
+
+ Face_handle new_f = create_face(v, v1, v2);
+ v1->set_face(new_f);
+ set_adjacency(new_f, 0, nf, jdx);
+ new_faces.push_back(new_f);
+ }
+ // At this point we have created all the new faces of the triangulation,
+ // and we have set adjacency relationships with the faces on the border
+ // of the hole.
+
+ for (unsigned int i = 0; i < new_faces.size() - 1; i++) {
+ set_adjacency(new_faces[i], 1, new_faces[i+1], 2);
+ }
+ set_adjacency(new_faces[0], 2, new_faces[new_faces.size()-1], 1);
+ // Now we have also set adjacency relationships between the new faces.
+
+ for (FaceIt it = face_begin; it != face_end; it++) {
+ delete_face(*it);
+ }
+ // The old faces that were in conflict are now deleted.
+
+ v->set_face(new_faces[0]);
+ // Set the pointer of the new vertex to one of the new faces.
+ }
+
+
+
+ /************* END OF MODIFICATIONS ***************/
+
+
template< class EdgeIt>
Vertex_handle star_hole(EdgeIt edge_begin, EdgeIt edge_end)
// creates a new vertex
diff --git a/TDS_2/test/TDS_2/include/CGAL/_test_cls_tds_2.h b/TDS_2/test/TDS_2/include/CGAL/_test_cls_tds_2.h
index ea60804cbb0..78bce69ebf8 100644
--- a/TDS_2/test/TDS_2/include/CGAL/_test_cls_tds_2.h
+++ b/TDS_2/test/TDS_2/include/CGAL/_test_cls_tds_2.h
@@ -128,7 +128,6 @@ _test_cls_tds_2( const Tds &)
assert(tds3.dimension()== 1);
assert(tds3.number_of_vertices() == 4);
assert(tds3.is_valid() );
-
Vertex_handle w4 = tds4.insert_first();
Vertex_handle v4_1 = tds4.insert_second();
@@ -187,6 +186,121 @@ _test_cls_tds_2( const Tds &)
u4 = tds4.star_hole(hole);
tds4.remove_degree_3(u4);
+
+ // insert_in_hole
+ // Count also the faces with the vertex at infinity!
+ //
+ // 1 |------| 3 1 |------| 3
+ // |\ | |\ /|
+ // | \ | | \ 4/ |
+ // | \ | --> | \/ |
+ // | \ | | /\ |
+ // | \ | | / \ |
+ // | \| |/ \|
+ // 2 |------| 0 2 |------| 0
+ //
+ //
+
+ std::cout << " insert_in_hole" << std::endl;
+ Tds td45;
+ Vertex_handle v045 = td45.insert_first();
+ Vertex_handle v145 = td45.insert_second();
+ Vertex_handle v245 = td45.insert_dim_up(v045, true);
+ Vertex_handle v345 = td45.insert_dim_up(v045, true);
+
+ assert(td45.is_valid() && td45.number_of_vertices() == 4 && td45.number_of_faces() == 4);
+
+ Face_handle f0_0 = td45.faces_begin();
+ Face_handle f0_1 = f0_0++;
+
+ Vertex_handle v445 = td45.insert_in_face(f0_0);
+ Vertex_handle v545 = td45.insert_in_face(f0_1);
+
+ Face_handle f1_0, f1_1, f1_2, f1_3, fcf_0, fcf_1;
+ Face_circulator fc1 = td45.incident_faces(v445), fc1e(fc1);
+ do {
+ int i = fc1->index(v445);
+ if (fc1->vertex((i+1)%3) == v345) {
+ f1_0 = fc1;
+ }
+ if (fc1->vertex((i+1)%3) == v145) {
+ f1_1 = fc1;
+ }
+ if (fc1->vertex((i+1)%3) == v245) {
+ fcf_0 = fc1;
+ }
+ } while(++fc1 != fc1e);
+
+
+ Face_circulator fc2 = td45.incident_faces(v545), fc2e(fc2);
+ do {
+ int i = fc2->index(v545);
+ if (fc2->vertex((i+1)%3) == v045) {
+ f1_2 = fc2;
+ }
+ if (fc2->vertex((i+1)%3) == v245) {
+ f1_3 = fc2;
+ }
+ if (fc2->vertex((i+1)%3) == v345) {
+ fcf_1 = fc2;
+ }
+ } while(++fc2 != fc2e);
+
+ Vertex_handle v645 = td45.insert_in_face(f1_0);
+ Vertex_handle v745 = td45.insert_in_face(f1_1);
+ Vertex_handle v845 = td45.insert_in_face(f1_2);
+ Vertex_handle v945 = td45.insert_in_face(f1_3);
+
+ Face_handle fcf_2, fcf_3, fcf_4, fcf_5;
+ Face_circulator fc6 = td45.incident_faces(v645), fc6e(fc6);
+ do {
+ int i = fc6->index(v645);
+ if (fc6->vertex((i+1)%3) == v445) {
+ fcf_2 = fc6;
+ break;
+ }
+ } while(++fc6 != fc6e);
+
+ Face_circulator fc7 = td45.incident_faces(v745), fc7e(fc7);
+ do {
+ int i = fc7->index(v745);
+ if (fc7->vertex((i+1)%3) == v245) {
+ fcf_3 = fc7;
+ break;
+ }
+ } while(++fc7 != fc7e);
+
+ Face_circulator fc8 = td45.incident_faces(v845), fc8e(fc8);
+ do {
+ int i = fc8->index(v845);
+ if (fc8->vertex((i+1)%3) == v345) {
+ fcf_4 = fc8;
+ break;
+ }
+ } while(++fc8 != fc8e);
+
+ Face_circulator fc9 = td45.incident_faces(v945), fc9e(fc9);
+ do {
+ int i = fc9->index(v945);
+ if (fc9->vertex((i+1)%3) == v545) {
+ fcf_5 = fc9;
+ break;
+ }
+ } while(++fc9 != fc9e);
+
+ std::vector vhole;
+ vhole.push_back( fcf_0 );
+ vhole.push_back( fcf_1 );
+ vhole.push_back( fcf_2 );
+ vhole.push_back( fcf_3 );
+ vhole.push_back( fcf_4 );
+ vhole.push_back( fcf_5 );
+
+ assert(td45.is_valid() && td45.number_of_vertices() == 10 && td45.number_of_faces() == 16);
+
+ Vertex_handle nv45 = td45.insert_in_hole(vhole.begin(), vhole.end());
+ assert(nv45 != Vertex_handle() && td45.is_valid() && td45.number_of_vertices() == 11 && td45.number_of_faces() == 18);
+
// dim_down
std::cout << " dim_down" << std::endl;
Tds td5;