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 4.10

Release date: March 2017

@@ -143,7 +142,15 @@ and src/ directories). + +

2D Triangulation data structure

+ + 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;