Merge pull request #7808 from janetournois/Triangulation_3-vertices_array-jtournois

Triangulation_3 - add `vertices()` helper functions
This commit is contained in:
Laurent Rineau 2023-11-15 15:44:22 +01:00
commit 01f021d532
5 changed files with 107 additions and 26 deletions

View File

@ -52,6 +52,10 @@ Release date: October 2023
`CGAL::Simplicial_mesh_cell_base_3` `CGAL::Simplicial_mesh_cell_base_3`
have been modified to enable passing a geometric traits and a custom cell base class. have been modified to enable passing a geometric traits and a custom cell base class.
### [3D Triangulations](https://doc.cgal.org/6.0/Manual/packages.html#PkgTriangulation3)
- Added three functions `vertices()` to the class `Triangulation_3`.
Each of them returns an array containing the vertices of the given triangulation simplex.
[Release 5.6](https://github.com/CGAL/cgal/releases/tag/v5.6) [Release 5.6](https://github.com/CGAL/cgal/releases/tag/v5.6)
----------- -----------

View File

@ -1303,6 +1303,26 @@ Finite_vertex_handles finite_vertex_handles() const;
*/ */
Points points() const; Points points() const;
/*!
* returns an array containing the vertices of `e`,
* in the order of their indices `e.second` and `e.third`
* in the cell `e.first`.
*/
std::array<Vertex_handle, 2> vertices(const Edge& e) const;
/*!
* returns an array containing the vertices of `f`,
* in counterclockwise order on the face of `f.first`
* opposite to vertex `f.first->vertex(f.second)`.
*/
std::array<Vertex_handle, 3> vertices(const Facet& f) const;
/*!
* returns an array containing the vertices of `c`,
* in the same order as the indices in `c`.
*/
std::array<Vertex_handle, 4> vertices(const Cell_handle c) const;
/*! /*!
returns a range of iterators over the cells intersected by a line segment returns a range of iterators over the cells intersected by a line segment
*/ */

View File

@ -76,6 +76,7 @@
#include <unordered_map> #include <unordered_map>
#include <utility> #include <utility>
#include <stack> #include <stack>
#include <array>
#define CGAL_TRIANGULATION_3_USE_THE_4_POINTS_CONSTRUCTOR #define CGAL_TRIANGULATION_3_USE_THE_4_POINTS_CONSTRUCTOR
@ -1653,7 +1654,7 @@ protected:
protected: protected:
typedef Facet Edge_2D; typedef Facet Edge_2D;
typedef Triple<Vertex_handle,Vertex_handle,Vertex_handle> Vertex_triple; typedef std::array<Vertex_handle, 3> Vertex_triple;
typedef typename Base::template Vertex_triple_Facet_map_generator< typedef typename Base::template Vertex_triple_Facet_map_generator<
Vertex_triple, Facet>::type Vertex_triple_Facet_map; Vertex_triple, Facet>::type Vertex_triple_Facet_map;
typedef typename Base::template Vertex_handle_unique_hash_map_generator< typedef typename Base::template Vertex_handle_unique_hash_map_generator<
@ -1919,6 +1920,29 @@ public:
return Points(points_begin(),points_end()); return Points(points_begin(),points_end());
} }
/// Vertex ranges defining a simplex
static std::array<Vertex_handle, 2> vertices(const Edge& e)
{
return std::array<Vertex_handle, 2>{
e.first->vertex(e.second),
e.first->vertex(e.third)};
}
static std::array<Vertex_handle, 3> vertices(const Facet& f)
{
return std::array<Vertex_handle, 3>{
f.first->vertex(vertex_triple_index(f.second, 0)),
f.first->vertex(vertex_triple_index(f.second, 1)),
f.first->vertex(vertex_triple_index(f.second, 2))};
}
static std::array<Vertex_handle, 4> vertices(const Cell_handle c)
{
return std::array<Vertex_handle, 4>{
c->vertex(0),
c->vertex(1),
c->vertex(2),
c->vertex(3)};
}
// cells around an edge // cells around an edge
Cell_circulator incident_cells(const Edge& e) const Cell_circulator incident_cells(const Edge& e) const
{ {
@ -4380,12 +4404,7 @@ typename Triangulation_3<Gt,Tds,Lds>::Vertex_triple
Triangulation_3<Gt,Tds,Lds>:: Triangulation_3<Gt,Tds,Lds>::
make_vertex_triple(const Facet& f) make_vertex_triple(const Facet& f)
{ {
Cell_handle ch = f.first; return vertices(f);
int i = f.second;
return Vertex_triple(ch->vertex(vertex_triple_index(i,0)),
ch->vertex(vertex_triple_index(i,1)),
ch->vertex(vertex_triple_index(i,2)));
} }
template < class Gt, class Tds, class Lds > template < class Gt, class Tds, class Lds >
@ -4393,13 +4412,13 @@ void
Triangulation_3<Gt,Tds,Lds>:: Triangulation_3<Gt,Tds,Lds>::
make_canonical_oriented_triple(Vertex_triple& t) make_canonical_oriented_triple(Vertex_triple& t)
{ {
int i = (t.first < t.second) ? 0 : 1; int i = (t[0] < t[1]) ? 0 : 1;
if(i==0) if(i==0)
{ {
i = (t.first < t.third) ? 0 : 2; i = (t[0] < t[2]) ? 0 : 2;
} else } else
{ {
i = (t.second < t.third) ? 1 : 2; i = (t[1] < t[2]) ? 1 : 2;
} }
Vertex_handle tmp; Vertex_handle tmp;
@ -4407,16 +4426,16 @@ make_canonical_oriented_triple(Vertex_triple& t)
{ {
case 0: return; case 0: return;
case 1: case 1:
tmp = t.first; tmp = t[0];
t.first = t.second; t[0] = t[1];
t.second = t.third; t[1] = t[2];
t.third = tmp; t[2] = tmp;
return; return;
default: default:
tmp = t.first; tmp = t[0];
t.first = t.third; t[0] = t[2];
t.third = t.second; t[2] = t[1];
t.second = tmp; t[1] = tmp;
} }
} }
@ -4970,7 +4989,7 @@ create_triangulation_inner_map(const Triangulation& t,
{ {
Facet f = std::pair<Cell_handle,int>(it,index); Facet f = std::pair<Cell_handle,int>(it,index);
Vertex_triple vt_aux = make_vertex_triple(f); Vertex_triple vt_aux = make_vertex_triple(f);
Vertex_triple vt(vmap[vt_aux.first], vmap[vt_aux.third], vmap[vt_aux.second]); Vertex_triple vt{vmap[vt_aux[0]], vmap[vt_aux[2]], vmap[vt_aux[1]]};
make_canonical_oriented_triple(vt); make_canonical_oriented_triple(vt);
inner_map[vt] = f; inner_map[vt] = f;
} }
@ -4984,7 +5003,7 @@ create_triangulation_inner_map(const Triangulation& t,
{ {
Facet f = std::pair<Cell_handle,int>(it,index); Facet f = std::pair<Cell_handle,int>(it,index);
Vertex_triple vt_aux = make_vertex_triple(f); Vertex_triple vt_aux = make_vertex_triple(f);
Vertex_triple vt(vmap[vt_aux.first], vmap[vt_aux.third], vmap[vt_aux.second]); Vertex_triple vt{vmap[vt_aux[0]], vmap[vt_aux[2]], vmap[vt_aux[1]]};
make_canonical_oriented_triple(vt); make_canonical_oriented_triple(vt);
inner_map[vt] = f; inner_map[vt] = f;
} }
@ -5084,9 +5103,9 @@ copy_triangulation_into_hole(const Vertex_handle_unique_hash_map& vmap,
while(! outer_map.empty()) while(! outer_map.empty())
{ {
typename Vertex_triple_Facet_map::iterator oit = outer_map.begin(); typename Vertex_triple_Facet_map::iterator oit = outer_map.begin();
while(is_infinite(oit->first.first) || while(is_infinite(oit->first[0]) ||
is_infinite(oit->first.second) || is_infinite(oit->first[1]) ||
is_infinite(oit->first.third)) is_infinite(oit->first[2]))
{ {
++oit; ++oit;
// Otherwise the lookup in the inner_map fails // Otherwise the lookup in the inner_map fails
@ -5124,12 +5143,12 @@ copy_triangulation_into_hole(const Vertex_handle_unique_hash_map& vmap,
Facet f = std::pair<Cell_handle, int>(new_ch, index); Facet f = std::pair<Cell_handle, int>(new_ch, index);
Vertex_triple vt = make_vertex_triple(f); Vertex_triple vt = make_vertex_triple(f);
make_canonical_oriented_triple(vt); make_canonical_oriented_triple(vt);
std::swap(vt.second, vt.third); std::swap(vt[1], vt[2]);
typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt); typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt);
if(oit2 == outer_map.end()) if(oit2 == outer_map.end())
{ {
std::swap(vt.second, vt.third); std::swap(vt[1], vt[2]);
outer_map[vt] = f; outer_map[vt] = f;
} }
else else

View File

@ -268,4 +268,34 @@ _test_triangulation_iterator( const Triangulation &T )
return(n-m+f-t); return(n-m+f-t);
} }
template < class Triangulation >
void
_test_vertices_array(const Triangulation& tr)
{
typedef typename Triangulation::Facet Facet;
typedef typename Triangulation::Edge Edge;
typedef typename Triangulation::Vertex_handle Vertex_handle;
typedef typename Triangulation::Cell_handle Cell_handle;
for (const Edge& e : tr.all_edges())
{
std::array<Vertex_handle, 2> vv = tr.vertices(e);
assert(vv[0] != vv[1]);
}
for (const Facet& f : tr.all_facets())
{
std::array<Vertex_handle, 3> vv = tr.vertices(f);
assert(vv[0] != vv[1]);
assert(vv[0] != vv[2]);
assert(vv[1] != vv[2]);
}
for (const Cell_handle c : tr.all_cell_handles())
{
std::array<Vertex_handle, 4> vv = tr.vertices(c);
assert(vv[0] != vv[1] && vv[0] != vv[2] && vv[0] != vv[3]);
assert(vv[1] != vv[2] && vv[1] != vv[3]);
assert(vv[2] != vv[3]);
}
}
#endif // CGAL_TEST_CLS_ITERATOR_C #endif // CGAL_TEST_CLS_ITERATOR_C

View File

@ -1031,23 +1031,31 @@ _test_cls_triangulation_3(const Triangulation &)
Point p28(1,3,5); Point p28(1,3,5);
v0=T0_1.insert(p28); v0=T0_1.insert(p28);
std::cout << " Testing Iterator "<< std::endl; std::cout << " Testing Iterators and Ranges "<< std::endl;
_test_vertex_iterator(T0_1); _test_vertex_iterator(T0_1);
_test_triangulation_iterator(T0_1); _test_triangulation_iterator(T0_1);
_test_vertices_array(T0_1);
_test_vertex_iterator(T0); _test_vertex_iterator(T0);
_test_triangulation_iterator(T0); _test_triangulation_iterator(T0);
_test_vertices_array(T0);
_test_vertex_iterator(T2_0); _test_vertex_iterator(T2_0);
_test_triangulation_iterator(T2_0); _test_triangulation_iterator(T2_0);
_test_vertices_array(T2_0);
_test_vertex_iterator(T1_0); _test_vertex_iterator(T1_0);
_test_triangulation_iterator(T1_0); _test_triangulation_iterator(T1_0);
_test_vertices_array(T1_0);
_test_vertex_iterator(T3_1); _test_vertex_iterator(T3_1);
_test_triangulation_iterator(T3_1); _test_triangulation_iterator(T3_1);
_test_vertices_array(T3_1);
_test_vertex_iterator(T3_0); _test_vertex_iterator(T3_0);
_test_triangulation_iterator(T3_0); _test_triangulation_iterator(T3_0);
_test_vertices_array(T3_0);
_test_vertex_iterator(T3_2); _test_vertex_iterator(T3_2);
_test_triangulation_iterator(T3_2); _test_triangulation_iterator(T3_2);
_test_vertices_array(T3_2);
_test_vertex_iterator(T3_3); _test_vertex_iterator(T3_3);
_test_triangulation_iterator(T3_3); _test_triangulation_iterator(T3_3);
_test_vertices_array(T3_3);
std::cout << " Testing Circulator "<< std::endl; std::cout << " Testing Circulator "<< std::endl;
_test_circulator(T0); _test_circulator(T0);